局部阈值法
通过灰度直方图看到图像的照明效果
自适应阈值分割函数:
CV_EXPORTS_W void adaptiveThreshold( InputArray src, OutputArray dst,
double maxValue, int adaptiveMethod,
int thresholdType, int blockSize, double C );
maxValue:阈值化后的最大值;
adaptiveMethod:计算阈值所采用的算法,有两个数值,分别为ADAPTIVE_THRESH_MEAN_C和ADAPTIVE_THRESH_GAUSSIAN_C;
blockSize:领域块大小;
分水岭算法分割
灰度图的几何解释
局部最小值点,该点对应一个盆地的最低点,当我们在盆地里滴一滴水的时候,由于重力作用,水最终会汇聚到该点。注意:可能存在一个最小值面,该平面内的都是最小值点。
盆地的其他位置点,该位置滴的水滴会汇聚到局部最小点。
盆地的边缘点,是该盆地和其他盆地交接点,在该点滴一滴水,会等概率的流向任何一个盆地。
假设我们在盆地的最小值点,打一个洞,然后往盆地里面注水,并阻止两个盆地的水汇集,我们会在两个盆地的水汇集的时刻,在交接的边缘线上(即分水岭线),建一个坝,来阻止两个盆地的水汇集成一片水域。这样图像就被分成2个像素集,一个是注水盆地像素集,一个是分水岭线像素集。
分水岭算法的过分割问题
由于噪声点或者其他干扰因素的存在,使用分水岭算法常常存在过分割的现象,这是因为很多很小的局部极值点的存在。
在初始时给marker,改善过分割问题
为了解决过分割的问题,可以使用基于标记(mark)图像的分水岭算法,就是指定mark图像,在这个区域的洪水淹没过程中,水平面都是定义的marker开始的,这样可以避免一些很小的噪声极值区域的分割。
使用marker改善分割结果
分水岭法图像分割函数:
CV_EXPORTS_W void watershed( InputArray image, InputOutputArray markers );
image:三通道彩色图像;
markers:记号点(种子点),每一个记号需要有不同的编号;
基于边缘轮廓的分割
可以在边缘检测的基础上,基于闭合边缘构建分割后的结果
在分割前需要进行边缘检测
OpenCV提供几种基于边缘轮廓的分割方法,包括简单的基于封闭曲线的方法,以及基于活动廓线(active contour的方法)
简单的基于封闭曲线的方法基于Suzeki,S.1985的方法,相对古老,但OpenCV基于此提供了关于图像描述的支持,比较好用
找到目标轮廓
CV_EXPORTS void findContours( InputArray image, OutputArrayOfArrays contours,
int mode, int method, Point offset = Point());
image:单通道图像矩阵,可以是灰度图,但更常用的是经过边缘检测算子处理后的二值图像;
contours:定义为“vector<vector<Point>>contours”,是一个轮廓列表;
hierarchy:存在嵌套轮廓时,分别为第i个轮廓的后一个轮廓、前一个轮廓、父轮廓、内嵌轮廓的索引编号。
mode:定义轮廓的索引模式,包括CV_RETR_EXTERNAL只检测最外围轮廓,CV_RETR_LIST检测所有轮廓,但不建立等级关系等。
method:包括CV_CHAIN_APPROX_SIMPLE仅保存轮廓的拐点信息,把所有轮廓拐点处的点保存如contours等;
offset:所有的轮廓信息相对于原始图像对应点的偏移量,缺省不设置。
搜索轮廓组成轮廓树
轮廓不同组织方式
画出目标轮廓
CV_EXPORTS_W void drawContours( InputOutputArray image, InputArrayOfArrays contours,
int contourIdx, const Scalar& color,
int thickness = 1, int lineType = LINE_8,
InputArray hierarchy = noArray(),
int maxLevel = INT_MAX, Point offset = Point() );