计算机视觉 OpenCV Android | 基本特征检测 之 轮廓分析
(0)轮廓分析概述及作用
- 通过将
Canny边缘提取
或者者二值化结果
作为输入图像
来实现轮廓发现与绘制
,
可是这些并不是
我们想要的最终结果
,我们一般根据
获取到的轮廓
求出它们的外接矩形
或者者最小外接矩形
,
并计算外接矩形
的横纵比例、轮廓面积、周长等数据
,而后
使用这些数据
实现特定几何形状轮廓
的查找与过滤
,
为后续的解决与分析
剔除不正确的区域
而保留候选对象
。
(1)边界框
- 最常见的获取
轮廓的外接矩形
是边界框
,
获取每个轮廓的边界框
,
通过它
可以得到与各个轮廓相对应的高度与宽度
,
并能通过它计算出轮廓的纵横比
。
通过轮廓点集合得到轮廓边界框的API如下:
boundingRect(MatOfPoint points)
其中,points
是轮廓所有点的集合对象
。注意其数据类型。
调用该API会返回一个Rect对象实例
,它是OpenCV关于矩形的数据结构
,
从中可以得到外界矩形(边界框)的宽高
,
而后即可以计算出轮廓的横纵比
了。
这种情况下得到的边界框不肯定满足条件
,有时候我们还需要获取轮廓的最小边界框
。
(2)最小边界框
与上面边界框不同
的是,
获取到的最小边界框
有时候不是一个水平或者者垂直的矩形
,
而是一个旋转了肯定角度的矩形
,
但是最小外接矩形(最小边界框)
能够更加真实地反映出轮廓的几何结构大小
,
而横纵比结果
更能反映出轮廓的真实几何特征
,
所以有些时候我们计算的经常
是最小外接矩形
,
相关API函数如下:
RotatedRect minAreaRect(MatOfPoint2f points)
其中,points
是轮廓的所有点的集合对象。注意其数据类型。
- 调用该API会返回一个
RotatedRect对象实例
,
它是OpenCV关于旋转矩形的数据结构
,
其包含了旋转角度,矩形的宽、高及四个顶点等信息
,
通过相关的API
都可以查询取得
,绘制
旋转矩形对象
的时候,首先
需要得到四个顶点
,
而后通过OpenCV绘制直线的API
来完成旋转矩形的绘制
。
(3)面积与周长
轮廓分析
中包含了轮廓大小的度量
,
这些度量最常见的就是计算轮廓的面积大小
与长度大小
,这些数据对
分析轮廓
与过滤掉少量不符合条件的轮廓
十分有用。
计算轮廓面积
的API如下:
contourArea(Mat contour, boolean oriented)
contour
:轮廓的所有点
的集合对象
。oriented
:表示轮廓的方向
,当oriented = true
时返回的面积
是一个有符号值
,默认为false
,返回的是绝对值
。
计算轮廓周长
的API如下:
arcLength(MatOfPoint2f curve, boolean closed)
curve
:轮廓的所有点
的集合对象
。注意数据类型。
closed
:表示能否为闭合曲线
,默认是true
。
完整的发现获取轮廓、外接轮廓、最小外接轮廓、横纵比、面积与长度
的代码演示如下:
private void measureContours(Mat src, Mat dst) { Mat gray= new Mat(); Mat binary = new Mat(); // 二值 Imgproc.cvtColor(src, gray, Imgproc.COLOR_BGR2GRAY); Imgproc.threshold(gray, binary, 0, 255, Imgproc.THRESH_BINARY | Imgproc.THRESH_OTSU); // 轮廓发现 List<MatOfPoint> contours = new ArrayList<MatOfPoint>(); Mat hierarchy = new Mat(); Imgproc.findContours(binary, contours, hierarchy, Imgproc.RETR_TREE, Imgproc.CHAIN_APPROX_SIMPLE, new Point(0, 0)); // 测量轮廓 dst.create(src.size(), src.type()); for(int i=0; i<contours.size(); i++) { Rect rect = Imgproc.boundingRect(contours.get(i)); double w = rect.width; double h = rect.height; double rate = Math.min(w, h)/Math.max(w, h); Log.i("Bound Rect", "rate:" + rate);//一个轮廓元素打印一次 RotatedRect minRect = Imgproc.minAreaRect(new MatOfPoint2f(contours.get(i).toArray())); w = minRect.size.width; h = minRect.size.height; rate = Math.min(w, h)/Math.max(w, h); Log.i("Min Bound Rect", "rate:" + rate); double area = Imgproc.contourArea(contours.get(i), false); double arclen = Imgproc.arcLength(new MatOfPoint2f(contours.get(i).toArray()), true); Log.i("contourArea", "area:" + rate); Log.i("arcLength", "arcLength:" + arclen); Imgproc.drawContours(dst, contours, i, new Scalar(0, 0, 255), 1); } // 释放内存 gray.release(); binary.release();}
运行结果(左侧是原图,右侧是轮廓发现与绘制,计算结果参见logcat):
上述的代码是求取图像的一律轮廓
,修改
上述程序,把返回轮廓改为返回最外层轮廓RETR_EXTERNAL
,
同时修改阈值化方法
,将其改为THRESH_BINARY_INV
,
则运行结果如下:
- 感兴趣的小伙伴可以进一步细化该方法,
将计算得到的轮廓几何属性值如长度、面积等
通过putText函数显示到输出的图像上
参考材料
- 《OpenCV Android 开发实战》(贾志刚 著)
- 关于《OpenCV Android 开发实战》作者的GitHub项目
- 笔者基于作者GitHub维护的APP
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » 计算机视觉 OpenCV Android | 基本特征检测 之 轮廓分析