在C,C++中实现侵蚀,扩张

8 c++ image-processing mathematical-morphology

我对二进制图像中的扩张是如何完成有理论上的理解.

AFAIK,如果我的SE(结构元素)是这个

0 1
1 1. 
Run Code Online (Sandbox Code Playgroud)

哪里.代表中心,我的形象(二进制就是这个)

0 0 0 0 0
0 1 1 0 0
0 1 0 0 0
0 1 0 0 0
0 0 0 0 0
Run Code Online (Sandbox Code Playgroud)

所以扩张的结果是

0 1 1 0 0 
1 1 1 0 0
1 1 0 0 0
1 1 0 0 0
0 0 0 0 0
Run Code Online (Sandbox Code Playgroud)

根据SE,我通过在0,+ 1(向上)和-1(向左)方向上移动Image获得上述结果,并取得所有这三个移位的并集.

现在,我需要弄清楚如何在C,C++中实现它.我不知道如何开始以及如何采用集合的联合.我想到了表示原始图像,三个移位图像和通过结合获得的最终图像; 全部使用矩阵.

我有什么地方可以获得一些样本解决方案或任何想法继续下去吗?

谢谢.

Amr*_*mro 13

那里有大量的示例实现.. 谷歌是你的朋友:)

编辑
以下是该过程的伪代码(非常类似于在2D中进行卷积).我确定有更聪明的方法:

// grayscale image, binary mask
void morph(inImage, outImage, kernel, type) {
 // half size of the kernel, kernel size is n*n (easier if n is odd)
 sz = (kernel.n - 1 ) / 2;

 for X in inImage.rows {
  for Y in inImage.cols {

   if ( isOnBoundary(X,Y, inImage, sz) ) {
    // check if pixel (X,Y) for boundary cases and deal with it (copy pixel as is)
    // must consider half size of the kernel
    val = inImage(X,Y);       // quick fix
   }

   else {
    list = [];

    // get the neighborhood of this pixel (X,Y)
    for I in kernel.n {
     for J in kernel.n {
      if ( kernel(I,J) == 1 ) {
       list.add( inImage(X+I-sz, Y+J-sz) );
      }
     }
    }

    if type == dilation {
     // dilation: set to one if any 1 is present, zero otherwise
     val = max(list);
    } else if type == erosion {
     // erosion: set to zero if any 0 is present, one otherwise
     val = min(list);
    }
   }

   // set output image pixel
   outImage(X,Y) = val;
  }
 }
}
Run Code Online (Sandbox Code Playgroud)

上面的代码基于本教程(检查页面末尾的源代码).


编辑2:

list.add(inImage(X + I-sz,Y + J-sz));

我们的想法是,我们希望在位于(X,Y)的当前图像像素上叠加以sz(掩模的一半大小)为中心的内核掩码(大小为nxn),然后只获得掩码中像素的强度value是一(我们将它们添加到列表中).一旦提取了该像素的所有邻居,我们将输出图像像素设置为该列表的最大值(最大强度)以进行扩张,并将min设置为侵蚀(当然这仅适用于灰度图像和二进制掩模)
两个X的索引假设上面的语句中的/ Y和I/J从0开始.如果您愿意,您总是可以用掩码大小的一半(从-sz到+ sz)重写I/J的索引.小改动(我链接的教程正在使用的方式)......


示例:
考虑将此3x3内核掩码放置在像素(X,Y)上并居中,并查看我们如何遍历它周围的邻域:

 --------------------
|      |       |     |    sz = 1;
 --------------------     for (I=0 ; I<3 ; ++I)
|      | (X,Y) |     |      for (J=0 ; J<3 ; ++J)
 --------------------         vect.push_back( inImage.getPixel(X+I-sz, Y+J-sz) );
|      |       |     |
 --------------------
Run Code Online (Sandbox Code Playgroud)