击中击不中变换 Hit or Miss opencv实现


本系列文章由@邻居张师傅 出品,转载请注明出处。

文章链接: https://editor.csdn.net/md?articleId=106491750

邮箱: [email protected]

当前使用OpenCV版本: 4.0.1


Hit-or-Miss代码opencv实现

  • 原理
    • 腐蚀操作(Erosion)
    • 击中击不中变换(Hit-or-Miss)
  • 实现
  • 参考


原理

腐蚀操作(Erosion)

形态学基本操作之一,还有一个则是膨胀操作。击中击不中变换主要以腐蚀操作为主,所以本文就主要介绍腐蚀操作。
B(结构元、核)对A的腐蚀操作可以表示为A⊖B
具体而言就是,让B的原点(中心)去遍历A。如果B被A完全包含,则将当前位置标志为新集合的成员。最终结果是新集合所构成的图像较A而言变小了,即A被B腐蚀了。
通俗而言就是,被腐蚀的图像变瘦变小了。腐蚀操作如下图所示。
击中击不中变换 Hit or Miss opencv实现_第1张图片


击中击不中变换(Hit-or-Miss)

击中击不中变换主要用来检测输入图像的某个特定图像的位置。例如,我们想在A图像内部找到和D图像的位置,可以表示如下:
A⊛D=(A⊖D)∩(Ac⊖Dc)
其中,Ac表示A的补集,Dc表示D的补集
击中击不中变换如下图所示:
击中击不中变换 Hit or Miss opencv实现_第2张图片
不难看出,该变换主要用到了以下三个步骤:

  • 利用D对A进行腐蚀
  • 利用(W-D)对A的补集进行腐蚀
  • 将步骤一和步骤二得到的图像进行与操作,最终得到变换后的操作

实现

击中击不中变换 Hit or Miss opencv实现_第3张图片上图是图像A,我们利用击中击不中原理找到其中较大的正方形。

B图像上图即需要找的图像。
根据前文所述变换的三个步骤,代码不难写出,其中的关键是两个步骤中的核的取值
这里我们利用copyMakeBorder()扩大一圈,新区域的值与原核的值相反。避免使用值全0时的核对图像进行腐蚀(卷积)的操作,有兴趣的同学可以尝试其结果。
最后的变换结果如下
击中击不中变换 Hit or Miss opencv实现_第4张图片


以下是代码

#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.

你可能感兴趣的:(Opencv,数字图像处理,C++)