1.膨胀
膨胀运算将目标物体边界处的背景点整合到该目标区域中,使物体边界向外部扩张。膨胀运算的表达式为
opencv函数使用:
Mat out;
//第一个参数MORPH_RECT表示矩形的卷积核,当然还可以选择椭圆形的、交叉型的
//MORPH_ELLIPSE MORPH_CROSS
Mat element = getStructuringElement(MORPH_RECT, Size(15, 15));
//膨胀操作
dilate(img, out, element);
namedWindow("膨胀操作", WINDOW_NORMAL);
imshow("膨胀操作", out);
2.腐蚀
opencv函数使用
Mat out;
//第一个参数MORPH_RECT表示矩形的卷积核,当然还可以选择椭圆形的、交叉型的
//MORPH_ELLIPSE MORPH_CROSS
Mat element = getStructuringElement(MORPH_RECT, Size(15, 15));
//腐蚀操作
erode(img, out, element);
namedWindow("腐蚀操作", WINDOW_NORMAL);
imshow("腐蚀操作", out);
3.开运算与闭运算
开运算:先腐蚀后膨胀,常用于去除毛边、毛刺、较小白点噪声
闭运算:先膨胀后腐蚀,常用于填充较小孔洞
opencv函数使用
Mat out;
//第一个参数MORPH_RECT表示矩形的卷积核,当然还可以选择椭圆形的、交叉型的
//MORPH_ELLIPSE MORPH_CROSS
Mat element = getStructuringElement(MORPH_RECT, Size(15, 15));
//开运算
morphologyEx(img, out, MORPH_OPEN, element);
//闭运算
morphologyEx(img, out, MORPH_CLOSE, element);
4.其他
形态学梯度:就是膨胀图与俯视图之差,用于保留物体的边缘轮廓。
顶帽:原图像与开运算图之差,用于分离比邻近点亮一些的斑块。
黑帽:闭运算与原图像之差,用于分离比邻近点暗一些的斑块。
5.孔洞填充
孔洞填充的话Matlab中有可用函数imfill,使用时搭配结构单元就可以,opencv的话暂时没有可以直接用的函数,下面通过漫水填充实现填充孔洞:
注:漫水填充flood
floodFill()函数原型1
1. int cv::floodFill(InputOutputArray image,
2. InputOutputArray mask,
3. Point seedPoint,
4. Scalar newVal,
5. Rect * rect = 0,
6. Scalar loDiff = Scalar(),
7. Scalar upDiff = Scalar(),
8. int flags = 4
9. )
image:输入输出图像,图像数据类型可以为CV_8U或者CV_32F的单通道或者三通道图像。
mask:掩码矩阵,尺寸比如输入图像的宽和高各大2的单通道图像,用于标记漫水填充的区域。
seedPoint:种子点。
newVal:归入种子点区域内像素点的新像素值。
rect:种子点漫水填充区域的最小矩形边界,默认值为0,表示不输出边界。
loDiff:添加进种子点区域条件的下界差值,当邻域某像素点的像素值与种子点像素值的差值大于该值时,该像素点被添加进种子点所在的区域。
upDiff:添加进种子点区域条件的上界差值,当种子点像素值与邻域某像素点的像素值的差值小于该值时,该像素点被添加进种子点所在的区域。
flags:漫水填充方法的操作标志,其由三部分构成,分别表示邻域种类、掩码像素值和填充算法的规则
具体实现:
void imfill(const Mat srcimage, Mat &dstimage)
{
Size m_Size = srcimage.size();
Mat temimage = Mat::zeros(m_Size.height + 2, m_Size.width + 2, srcimage.type());//延展图像
srcimage.copyTo(temimage(Range(1, m_Size.height + 1), Range(1, m_Size.width + 1)));
floodFill(temimage, Point(0, 0), Scalar(255));
Mat cutImg;//裁剪延展的图像
temimage(Range(1, m_Size.height + 1), Range(1, m_Size.width + 1)).copyTo(cutImg);
dstimage = srcimage | (~cutImg);
}
效果:
6.凸壳运算
如果连通分量内连接任意两点的直线段都在其内部,称该连通分量是凸形的。在棒材端面二值图像中,每根棒材的连通分量都应该是凸形的。然而,受棒材截面氧化的影响,有些棒材的连通分量存在沟壑或者狭窄的间断,凸壳运算可以消除狭窄断裂和细小沟塾。
在本课题中,使用无限制条件的凸壳运算会使目标区域超出棒材端面原有尺寸,导致连通分量的膨胀,造成本不应该出现的粘连,破坏前述腐烛和幵运算取得的效果。为此,对凸壳运算加以改进,用最小多边形限制连通分量的生长,沿垂直、水平和对角线方向对生长空间进行限制。图显示了改进的凸壳运算的效果。
7.极限腐蚀算法用于生成单个目标标记
附加:条件膨胀:对极限后的图像设定一定条件下的定向膨胀,扩充种子连通域大小,如下:
8.应用举例
钢材的自动计数操作:
主要参考:薛彦冰 基于机器视觉的棒材计数系统研究与实现 山东大学硕士论文