图像处理2-图像形态学
上一篇图像滤波,这篇讲解形态学 形态学,即数学形态学,时图像处理过程中非常重要的一个研究方向,形态学主要从图像内提取其分量信息,该分量信息通常对于表达和描绘图像的形状具有重要的意义,通常时图像理解时所使用的最为本质的形状特征,这部分主要包含:腐蚀、膨胀、开运算、闭运算、Morphological Grandient(形态学梯度)、顶帽、黑帽等操作 1、 腐蚀 腐蚀能够将图像的边界点消除,使图像沿着边界向内收缩,也可以将小于指定结构体元素的部分去掉
原图
目标图像
void erode( InputArray src, OutputArray dst, InputArray kernel, Point anchor = Point(-1,-1), int iterations = 1, int borderType = BORDER_CONSTANT, const Scalar& borderValue = morphologyDefaultBorderValue() );
src:需要进行腐蚀的原始图像,图像的深度必须是CV_8U,CV_16U,CV_16S,CV_32F,CV_64F其中的一种 dst:被腐蚀后所输出的目标图像 kernel:腐蚀操作时所采用的结构类型 anchor:element结构中锚点的位置,该值默认为(-1,-1),在核的中心位置 iterations:腐蚀操作迭代的次数 borderType:图像边界处理的方法 borderType值如下
类型 | 说明 |
BORDER_CONSTANT | iiiiii|abcdefgh|iiiiii,特定值i |
BORDER_REPLICATE | aaaaaa|abcdefgh|hhhhhh |
BORDER_REFLECT | fedcba|abcdefgh|hgfedcb |
BORDER_WRAP | cdefgh|abcdefgh|abcdefg |
BORDER_REFLECT_101 | gfedcb|abcdefgh|gfedcba |
BORDER_TRANSPARENT | uvwxyz|abcdefgh|ijklmno |
BORDER_REFLECT101 | 与BORDER_REFLECT_101相同 |
BORDER_DEFAULT | 与BORDER_REFLECT_101相同 |
BORDER_ISOLATED | 不考虑ROI(Region of interest,感兴趣区域)外区域 |
borderValue:边界值,一般采用其默认值 其中morphologyDefaultBorderValue()用来返回腐蚀和膨胀的“魔力(magic)”边界值。它通常自动转换为Scalar::all(-DBL_MAX)进行膨胀 其参数中的kernel可以通过getStructuringElement得到 Mat getStructuringElement(int shape, Size ksize, Point anchor = Point(-1,-1));
该函数用来返回一个用于形态学操作的指定大小和形状的结构元素 shape:cv::MorphShapes中的任意一个元素形状 有MORPH_RECT,MORPH_CROSS,MORPH_ELLIPSE三种 ksize:结构元素的大小 anchor:结构元素中的锚点位置。该值默认为(-1,-1),是形状的中,仅十字星型的形状与锚点位置紧密相关。在其他情况下,锚点仅用于形态学运算结果的调整 //调用getStructuringElement函数 Mat element = getStructuringElement(MORPH_CROSS,Size(2 * 3+ 1, 2 * 3+ 1),Point(3, 3)); //调用腐蚀函数erode erode(m_srcImage, m_dstImage, element); 2、膨胀 膨胀对图像的边界进行扩张,将与当前对象接触到的背景点合并到图像内,让边界点向外部进行扩张。 如果图像内两个对象的距离较近,在膨胀的过程中,两个对象可能会连通到一起。 膨胀操作对填补图像分割后图像内所存在的空白相当有帮助
原图
目标图像
void dilate( InputArray src, OutputArray dst, InputArray kernel, Point anchor = Point(-1,-1), int iterations = 1, int borderType = BORDER_CONSTANT, const Scalar& borderValue = morphologyDefaultBorderValue() );
src:需要进行膨胀的原始图像,图像的深度必须是CV_8U,CV_16U,CV_16S,CV_32F,CV_64F其中的一种 dst:被膨胀后所输出的目标图像 kernel:腐蚀操作时所采用的结构类型 anchor:element结构中锚点的位置,该值默认为(-1,-1),在核的中心位置 iterations:膨胀操作迭代的次数 borderType:图像边界处理的方法 3、其他 包含开运算、闭运算、形态学梯度、顶帽、黑帽、击中不击中
//调用getStructuringElement函数 Mat element = getStructuringElement(MORPH_CROSS,Size(2 * 3+ 1, 2 * 3 + 1),Point(3, 3)); //调用膨胀函数dilate dilate(m_srcImage, m_dstImage, element); //开运算 MORPH_RECT MORPH_CROSS MORPH_ELLIPSE getStructuringElement morphologyEx MORPH_OPEN //闭运算 MORPH_RECT MORPH_CROSS MORPH_ELLIPSE getStructuringElement morphologyEx MORPH_CLOSE //Morphological Grandient MORPH_RECT MORPH_CROSS MORPH_ELLIPSE getStructuringElement morphologyEx MORPH_GRADIENT //顶帽 MORPH_RECT MORPH_CROSS MORPH_ELLIPSE getStructuringElement morphologyEx MORPH_TOPHAT //黑帽 MORPH_RECT MORPH_CROSS MORPH_ELLIPSE getStructuringElement morphologyEx MORPH_BLACKHAT //void morphologyEx( InputArray src, OutputArray dst, int op, InputArray kernel, Point anchor = Point(-1,-1), int iterations = 1, int borderType = BORDER_CONSTANT, const Scalar& borderValue = morphologyDefaultBorderValue() );
src:需要进行形态学的原始图像,图像的深度必须是CV_8U,CV_16U,CV_16S,CV_32F,CV_64F其中的一种 dst:经过形态学处理后所输出的目标图像 op:操作类型,各种形态学运算的操作规则均是将腐蚀和膨胀进行组合而得到的 op类型
类型 | 说明 | 含义 | 操作 |
MORPH_ERODE | 腐蚀 | 腐蚀 | erode(src) |
MORPH_DILATE | 膨胀 | 膨胀 | dilate(src) |
MORPH_OPEN | 开运算 | 先腐蚀后膨胀 | dilate(erode(src)) |
MORPH_CLOSE | 闭运算 | 先膨胀后腐蚀 | erode(dilate(src)) |
MORPH_GRADIENT | 形态学梯度 | 膨胀图像减去腐蚀图像 | dilate(src)-erode(src) |
MORPH_TOPHAT | 顶帽 | 原图减去开运算 | src-open(src) |
MORPH_BLACKHAT | 黑帽 | 闭运算减去原图 | close(src)-src |
MORPH_HITMISS | 击中击不中 | 前景背景腐蚀运算的交集,仅支持CV_8UC1二进制图 | Intersection(erode(src),erode(src1)) |
参数kernel、anchor、borderType、borderValue与erode函数的意义一致
//调用getStructuringElement函数Mat element = getStructuringElement(MORPH_CROSS,Size(2 * 3+ 1, 2 * 3+ 1),Point(3, 3));//调用morphologyEx函数-MORPH_OPEN->开运算morphologyEx(m_srcImage, m_dstImage, MORPH_OPEN, element);
/*形态学///形态学void DlgImageProcessing::on_comboBoxMorphology_currentIndexChanged(int value){if (m_srcImage.data){QString qsType = ui.comboBoxMorphType->currentText();//定义类型int MorphologyType = -1;if (qsType == "MORPH_RECT"){MorphologyType = MORPH_RECT;}else if (qsType == "MORPH_CROSS"){MorphologyType = MORPH_CROSS;}else if (qsType == "MORPH_ELLIPSE"){MorphologyType = MORPH_ELLIPSE;}else{MorphologyType = MORPH_RECT;}//定义大小int MorphlogySize = ui.comboBoxMorphSize->currentText().toInt();//调用getStructuringElement函数Mat element = getStructuringElement(MorphologyType, Size(2 * MorphlogySize + 1, 2 * MorphlogySize + 1), Point(MorphlogySize, MorphlogySize));Mat dstImage;if (0 == value){//调用腐蚀函数erode//erode(m_srcImage, dstImage, element);//也可以调用morphologyEx函数-MORPH_ERODE->腐蚀morphologyEx(m_srcImage, dstImage, MORPH_ERODE, element);}else if (1 == value){//调用膨胀函数dilate//dilate(m_srcImage, dstImage, element);//也可以调用morphologyEx函数-MORPH_DILATE->膨胀morphologyEx(m_srcImage, dstImage, MORPH_DILATE, element);}else if (2 == value){//调用morphologyEx函数-MORPH_OPEN->开运算morphologyEx(m_srcImage, dstImage, MORPH_OPEN, element);}else if (3 == value){//调用morphologyEx函数-MORPH_CLOSE->闭运算morphologyEx(m_srcImage, dstImage, MORPH_CLOSE, element);}else if (4 == value){//调用morphologyEx函数-MORPH_GRADIENT->Grandient运算morphologyEx(m_srcImage, dstImage, MORPH_GRADIENT, element);}else if (5 == value){//调用morphologyEx函数-MORPH_TOPHAT->顶帽变换morphologyEx(m_srcImage, dstImage, MORPH_TOPHAT, element);}else if (6 == value){//调用morphologyEx函数-MORPH_BLACKHAT->黑帽变换morphologyEx(m_srcImage, dstImage, MORPH_BLACKHAT, element);}cv::imshow("this result", dstImage);emit ShowImage(dstImage);}else{QMessageBox::warning(this, "提示", "没图片");}}
原图
腐蚀
膨胀
开运算
闭运算
morphology
顶帽
黑帽
个人站点
1、CSDN地址:
Qt学视觉_CSDN博客-Qt学视觉-OpenCV,特征提取与检测领域博主Qt学视觉擅长Qt学视觉-OpenCV,特征提取与检测,等方面的知识,Qt学视觉关注c++,qt,visualstudio,opencv领域.https://blog.csdn.net/u013480226?spm=1010.2135.3001.5421
2、知乎
欢迎关注我的知乎专题Qt学视觉 - 知乎使用qt所写的视觉软件https://www.zhihu.com/column/c_1237691650757353472
3、微信公众号《Qt学视觉》
欢迎关注