本系列文章由@邻居张师傅 出品,转载请注明出处。
文章链接: https://editor.csdn.net/md?articleId=106491750
当前使用OpenCV版本: 4.0.1
形态学基本操作之一,还有一个则是膨胀操作。击中击不中变换主要以腐蚀操作为主,所以本文就主要介绍腐蚀操作。
B(结构元、核)对A的腐蚀操作可以表示为A⊖B。
具体而言就是,让B的原点(中心)去遍历A。如果B被A完全包含,则将当前位置标志为新集合的成员。最终结果是新集合所构成的图像较A而言变小了,即A被B腐蚀了。
通俗而言就是,被腐蚀的图像变瘦变小了。腐蚀操作如下图所示。
击中击不中变换主要用来检测输入图像的某个特定图像的位置。例如,我们想在A图像内部找到和D图像的位置,可以表示如下:
A⊛D=(A⊖D)∩(Ac⊖Dc)
其中,Ac表示A的补集,Dc表示D的补集
击中击不中变换如下图所示:
不难看出,该变换主要用到了以下三个步骤:
上图即需要找的图像。
根据前文所述变换的三个步骤,代码不难写出,其中的关键是两个步骤中的核的取值。
这里我们利用copyMakeBorder()扩大一圈,新区域的值与原核的值相反。避免使用值全0时的核对图像进行腐蚀(卷积)的操作,有兴趣的同学可以尝试其结果。
最后的变换结果如下
以下是代码
#include
#include
#include
#include
using namespace std;
using namespace cv;
int main( int argc, char** argv )
{
Mat a,b,aInv,bInv,hitOrNot, b_erode_a, bInv_erode_aInv;
a=imread("a.png",IMREAD_GRAYSCALE);
threshold(a, a, 180, 255, THRESH_BINARY);
//imshow("二值化图像", input_image);
b = imread("b.png",IMREAD_GRAYSCALE);
threshold(b, b, 180, 1, THRESH_BINARY);
copyMakeBorder(b,b,1,1,1,1,BORDER_CONSTANT,Scalar(1));
erode(a, b_erode_a, b, Point(-1,-1), 1, BORDER_DEFAULT, 0);
imshow("b_erode_a", b_erode_a);
aInv=imread("a.png",IMREAD_GRAYSCALE);
threshold(aInv, aInv, 180, 255, THRESH_BINARY_INV);
bInv= imread("b.png",IMREAD_GRAYSCALE);
threshold(bInv, bInv, 180, 1, THRESH_BINARY_INV);
copyMakeBorder(bInv,bInv,1,1,1,1,BORDER_CONSTANT,Scalar(0));
erode(aInv, bInv_erode_aInv, bInv, Point(-1,-1), 1, BORDER_DEFAULT, 0);
imshow("bInv_erode_aInv", bInv_erode_aInv);
bitwise_and(b_erode_a,bInv_erode_aInv,hitOrNot);//逻辑与,求交集
imshow("hitOrNot", hitOrNot);
waitKey();
}
1.Eroding and Dilating
2.Hit-or-Miss
3.冈萨雷斯. 数字图像处理[M]. 北京: 电子工业出版社, 2005.