opencv 侵蚀erode 膨胀dilate 开运算 闭运算等形态学转换操作

1. 侵蚀 (白色区域减小)

侵蚀的基本思想就像土壤侵蚀一样,它侵蚀前景物体的边界(尽量使前景保持白色)。它是做什么的呢?内核滑动通过图像(在2D卷积中)。原始图像中的一个像素(无论是1还是0)只有当内核下的所有像素都是1时才被认为是1,否则它就会被侵蚀(变成0)。

结果是,根据内核的大小,边界附近的所有像素都会被丢弃。因此,前景物体的厚度或大小减小,或只是图像中的白色区域减小。它有助于去除小的白色噪声(正如我们在颜色空间章节中看到的),分离两个连接的对象等。

CV_EXPORTS_W void erode( InputArray src, OutputArray dst, InputArray kernel,
                         Point anchor = Point(-1,-1), int iterations = 1,
                         int borderType = BORDER_CONSTANT,
                         const Scalar& borderValue = morphologyDefaultBorderValue() );

在多通道图像的情况下,每个通道都是独立处理的。
@param src 			//输入图像; 通道数可以是任意的,但深度应为以下之一
					CV_8U,CV_16U,CV_16S,CV_32F或CV_64F。
@param dst 			//输出与src大小和类型相同的图像。
@param kernel		//用于腐蚀的结构元素; 如果`element = Mat()`,则为`3 x 3`矩形
					使用结构元素。 可以使用#getStructuringElement创建内核。
@param anchor 		//元素内锚的位置; 默认值(-1,-1)表示锚点位于元素中心。
@param iterations 	//施加腐蚀的次数。
@param borderType 	//像素外推方法,请参见#BorderTypes
@param borderValue 	//边界不变时的边界值

demo

int main() {
	cv::namedWindow("src",0);
	cv::namedWindow("dst", 0);
	cv::Mat src = cv::imread("./img/liangbaikai.jpg", 1);
	cv::Mat dst;
	//获取自定义核  
	cv::Mat element = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(10, 10));
	cv::erode(src,dst,element);
	cv::imshow("src", src);
	cv::imshow("dst", dst);
	cv::imwrite("./img/dst_liangbaikai.jpg", dst);
	cv::waitKey(0);

}
 

效果

原图:
在这里插入图片描述
结果:
在这里插入图片描述

2. 扩张

它与侵蚀正好相反。如果内核下的至少一个像素为“ 1”,则像素元素为“ 1”。因此,它会增加图像中的白色区域或增加前景对象的大小。通常,在消除噪音的情况下,腐蚀后会膨胀。因为腐蚀会消除白噪声,但也会缩小物体。因此,我们对其进行了扩展。由于噪音消失了,它们不会回来,但是我们的目标区域增加了。在连接对象的损坏部分时也很有用。

CV_EXPORTS_W void dilate( InputArray src, OutputArray dst, InputArray kernel,
                          Point anchor = Point(-1,-1), int iterations = 1,
                          int borderType = BORDER_CONSTANT,
                          const Scalar& borderValue = morphologyDefaultBorderValue() );
                        
在多通道图像的情况下,每个通道都是独立处理的。

@param src 			//输入图像; 通道数可以是任意的,但深度应为以下之一
					CV_8U,CV_16U,CV_16S,CV_32F或CV_64F。
@param dst 			//输出与src大小和类型相同的图像。
@param kernel		//用于扩展的结构元素; 如果elemenat = Mat(),则为3 x 3的矩形
					使用结构元素。 可以使用#getStructuringElement创建内核
@param anchor 		//元素内锚的位置; 默认值(-1,-1)表示锚点位于元素中心。
@param iterations 	//进行扩张的次数。
@param borderType 	//像素外推方法,请参见#BorderTypes
@param borderValue 	//边界不变时的边界值  

demo

int main() {
	cv::namedWindow("src",0);
	cv::namedWindow("dst", 0);
	cv::Mat src = cv::imread("./img/liangbaikai.jpg", 1);
	cv::Mat dst;
	//获取自定义核  
	cv::Mat element = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3));
	cv::dilate(src,dst,element);
	cv::imshow("src", src);
	cv::imshow("dst", dst);
	cv::imwrite("./img/dst_liangbaikai.jpg", dst);
	cv::waitKey(0);

}

效果

原图:
在这里插入图片描述

结果:
在这里插入图片描述

3. 形态学变化(组合)

CV_EXPORTS_W 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() );
                                
在多通道图像的情况下,每个通道都是独立处理的。

@param src 				//源图像。通道数可以是任意的。深度应为以下之一
						CV_8U,CV_16U,CV_16S,CV_32F或CV_64F。
@param dst	 			//与源图像大小和类型相同的目标图像。
@param op 				//形态学操作的类型,请参见#MorphTypes
@param kernel			//构造元素。可以使用#getStructuringElement创建它。
@param anchor 			//锚定在内核中的位置。负值表示锚点位于内核中心。
@param iterations 		//施加腐蚀和膨胀的次数。
@param borderType 		//像素外推方法,请参见#BorderTypes
@param borderValue 		//边界不变时的边界值。默认值有一个特殊的含义。

@note迭代次数是将应用腐蚀或膨胀操作的次数。
例如,具有两次迭代的开运算(#MORPH_OPEN)等效于应用
依次为:腐蚀->腐蚀->膨胀->膨胀(而不是腐蚀->膨胀->腐蚀->膨胀)。

3.1开运算 cv::MORPH_OPEN

开运算就是先侵蚀然后扩张,它对于消除噪音很有用

demo
int main() {
	cv::namedWindow("src",0);
	cv::namedWindow("dst", 0);
	cv::Mat src = cv::imread("./img/lbk.jpg", 1);
	cv::Mat dst;
	//获取自定义核  
	cv::Mat element = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(10, 10));
	cv::morphologyEx(src,dst, cv::MORPH_OPEN,element);
	cv::imshow("src", src);
	cv::imshow("dst", dst);
	cv::imwrite("./img/dst_liangbaikai.jpg", dst);
	cv::waitKey(0);
}
效果

原图:
在这里插入图片描述

结果:
在这里插入图片描述

3.2 闭运算 cv::MORPH_CLOSE

闭运算就是先扩张再侵蚀,在关闭前景对象内部的小孔或对象上的小黑点时很有用。

demo
int main() {
	cv::namedWindow("src",0);
	cv::namedWindow("dst", 0);
	cv::Mat src = cv::imread("./img/lbk.jpg", 1);
	cv::Mat dst;
	//获取自定义核  
	cv::Mat element = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(10, 10));
	cv::morphologyEx(src,dst, cv::MORPH_CLOSE,element);
	cv::imshow("src", src);
	cv::imshow("dst", dst);
	cv::imwrite("./img/dst_liangbaikai.jpg", dst);
	cv::waitKey(0);
}
效果

原图:
在这里插入图片描述

结果:
在这里插入图片描述

3.3 形态学梯度 cv::MORPH_GRADIENT

这是图像扩张和侵蚀之间的区别。结果将看起来像对象的轮廓。

demo
int main() {
	cv::namedWindow("src",0);
	cv::namedWindow("dst", 0);
	cv::Mat src = cv::imread("./img/lbk.jpg", 1);
	cv::Mat dst;
	//获取自定义核  
	cv::Mat element = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(10, 10));
	cv::morphologyEx(src,dst, cv::MORPH_GRADIENT,element);
	cv::imshow("src", src);
	cv::imshow("dst", dst);
	cv::imwrite("./img/dst_liangbaikai.jpg", dst);
	cv::waitKey(0);
}
效果

原图:
在这里插入图片描述

结果:
在这里插入图片描述

3.4 顶帽 cv::MORPH_TOPHAT

它是输入图像和图像开运算之差。

demo
int main() {
	cv::namedWindow("src",0);
	cv::namedWindow("dst", 0);
	cv::Mat src = cv::imread("./img/lbk.jpg", 1);
	cv::Mat dst;
	//获取自定义核  
	cv::Mat element = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(10, 10));
	cv::morphologyEx(src,dst, cv::MORPH_TOPHAT,element);
	cv::imshow("src", src);
	cv::imshow("dst", dst);
	cv::imwrite("./img/dst_liangbaikai.jpg", dst);
	cv::waitKey(0);
}

效果

原图:
在这里插入图片描述

结果:
在这里插入图片描述

3.5 黑帽 cv::MORPH_BLACKHAT

这是输入图像和图像闭运算之差。

demo
int main() {
	cv::namedWindow("src",0);
	cv::namedWindow("dst", 0);
	cv::Mat src = cv::imread("./img/lbk.jpg", 1);
	cv::Mat dst;
	//获取自定义核  
	cv::Mat element = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(10, 10));
	cv::morphologyEx(src,dst, cv::MORPH_BLACKHAT,element);
	cv::imshow("src", src);
	cv::imshow("dst", dst);
	cv::imwrite("./img/dst_liangbaikai.jpg", dst);
	cv::waitKey(0);
}

效果

原图:
在这里插入图片描述

结果:

在这里插入图片描述

4. 自定义内核的种类

CV_EXPORTS_W Mat getStructuringElement(int shape, Size ksize, Point anchor = Point(-1,-1));

enum MorphShapes {
    MORPH_RECT    = 0, //!< a rectangular structuring element:  \f[E_{ij}=1\f]
    MORPH_CROSS   = 1, //!< a cross-shaped structuring element:
                       //!< \f[E_{ij} =  \fork{1}{if i=\texttt{anchor.y} or j=\texttt{anchor.x}}{0}{otherwise}\f]
    MORPH_ELLIPSE = 2 //!< an elliptic structuring element, that is, a filled ellipse inscribed
                      //!< into the rectangle Rect(0, 0, esize.width, 0.esize.height)
};
# 矩形内核
cv::getStructuringElement(cv::MORPH_RECT,(5,5))
	 1  1  1  1  1 
	 1  1  1  1  1 
	 1  1  1  1  1 
	 1  1  1  1  1 
	 1  1  1  1  1 
       
# 椭圆内核
cv::getStructuringElement(cv::MORPH_ELLIPSE,(5,5))
     0  0  1  0  0
     1  1  1  1  1
     1  1  1  1  1
     1  1  1  1  1
     0  0  1  0  0

# 十字内核
cv::getStructuringElement(cv::MORPH_CROSS,(5,5))
     0  0  1  0  0
     0  0  1  0  0
     1  1  1  1  1
     0  0  1  0  0
     0  0  1  0  0
  • 6
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值