图像形态学处理(膨胀腐蚀开闭运算)——数字图像处理学习八(C++版)

一、基本概念

1)形态学的基本思想是利用一种特殊的结构元来测量或提取输入图像中相应的形状或特征,以便进一步进行图像分析和目标识别。

2)图像的形态学处理是对二值图像进行处理,所以在形态学处理前需要将图像二值化

3)结构元可以是任意形状,结构元有一个锚点,如下结构元,中间红色则为锚点

图像形态学处理(膨胀腐蚀开闭运算)——数字图像处理学习八(C++版)_第1张图片

 二、膨胀

可以知道,二值图像就是由黑色和白色组成,那么膨胀简单来说就是将图像的白色部分变大

膨胀的原理就是结构元在图像上滑动,当锚点对应的像素为白色时,那么结构元对应为1的元素点也变为白色。

举个栗子:

结构元为,图像形态学处理(膨胀腐蚀开闭运算)——数字图像处理学习八(C++版)_第2张图片锚点为中心点

那么膨胀就是如下过程(深色像素为白色):

图像形态学处理(膨胀腐蚀开闭运算)——数字图像处理学习八(C++版)_第3张图片

代码:

这里的结构元为3*3,值全为1

//全局二值化后再进行形态学处理
double f[9];
  f[0] = 1;
  f[1] = 1;
  f[2] = 1;
  f[3] = 1;
  f[4] = 1;
  f[5] = 1;
  f[6] = 1;
  f[7] = 1;
  f[8] = 1;
  double* new_data = new double[biHead1.biHeight * biHead1.biWidth]();
  //膨胀就是图像中的白的变大
  for (int i = 0; i < biHead1.biHeight-2; i++)
    for (int j = 0; j < biHead1.biWidth-2; j++)
    {
      if (double_data[(i + 1) * biHead1.biWidth + j + 1] + f[4] == 256)
      {
        new_data[i * biHead1.biWidth + j] = 255;
        new_data[i* biHead1.biWidth + j + 1] = 255;
        new_data[i * biHead1.biWidth + j + 2] = 255;
        new_data[(i + 1) * biHead1.biWidth + j ] = 255;
        new_data[(i + 1) * biHead1.biWidth + j + 1] = 255;//锚点
        new_data[(i + 1) * biHead1.biWidth + j + 2] = 255;
        new_data[(i + 2) * biHead1.biWidth + j ] = 255;
        new_data[(i + 2) * biHead1.biWidth + j + 1] = 255;
        new_data[(i + 2) * biHead1.biWidth + j + 2] = 255;
      }
    }
  //显示
  for (int i = 0; i < biHead1.biHeight; i++)
    for (int j = 0; j < biHead1.biWidth; j++)
    {
      dc.SetPixel(j / time, (biHead1.biHeight - i) / time, RGB(new_data[j + i * biHead1.biWidth], new_data[j + i * biHead1.biWidth], new_data[j + i * biHead1.biWidth]));
    }

 结果:

图像形态学处理(膨胀腐蚀开闭运算)——数字图像处理学习八(C++版)_第4张图片

三、腐蚀

与膨胀同理,腐蚀简单来说就是将图像的白色部分变小

腐蚀的原理就是结构元在图像上滑动,当结构元上所有对应的像素都为白色时,那么只保留锚点的白色,其余像素变黑。

举个栗子:

结构元为,图像形态学处理(膨胀腐蚀开闭运算)——数字图像处理学习八(C++版)_第5张图片锚点为中心点

那么腐蚀就是如下过程(深色像素为白色):

图像形态学处理(膨胀腐蚀开闭运算)——数字图像处理学习八(C++版)_第6张图片

代码:

这里结构元为图像形态学处理(膨胀腐蚀开闭运算)——数字图像处理学习八(C++版)_第7张图片

//全局二值化后再进行形态学处理
double f[9];
  f[0] = 0;
  f[1] = 1;
  f[2] = 0;
  f[3] = 1;
  f[4] = 1;
  f[5] = 1;
  f[6] = 0;
  f[7] = 1;
  f[8] = 0;
  double* new_data = new double[biHead1.biHeight * biHead1.biWidth]();
  //腐蚀,腐蚀就是原图中的白的变小
  for (int i = 0; i < biHead1.biHeight-2; i++)
    for (int j = 0; j < biHead1.biWidth-2; j++)
    {
      if ((double_data[i * biHead1.biWidth + j + 1] + f[1] == 256) &&(double_data[(i + 1) * biHead1.biWidth + j] + f[3] == 256) && (double_data[(i + 1) * biHead1.biWidth + j + 1] + f[4] == 256) && (double_data[(i + 1) * biHead1.biWidth + j + 2] + f[5] == 256)&& (double_data[(i + 2) * biHead1.biWidth + j + 1] + f[7] == 256))
      {
        new_data[(i + 1) * biHead1.biWidth + j + 1] = 255;//锚点
      }
    }
  //显示
  for (int i = 0; i < biHead1.biHeight; i++)
    for (int j = 0; j < biHead1.biWidth; j++)
    {
      dc.SetPixel(j / time, (biHead1.biHeight - i) / time, RGB(new_data[j + i * biHead1.biWidth], new_data[j + i * biHead1.biWidth], new_data[j + i * biHead1.biWidth]));
}

结果:

图像形态学处理(膨胀腐蚀开闭运算)——数字图像处理学习八(C++版)_第8张图片 

 四、开运算 

开运算实质上是先腐蚀再膨胀,它一般会平滑物体的轮廓,断开较窄的狭颈并消除细的突出物。

举个栗子:

结构元为,图像形态学处理(膨胀腐蚀开闭运算)——数字图像处理学习八(C++版)_第9张图片锚点为中心点

那么开运算就是如下过程(深色像素为白色):

图像形态学处理(膨胀腐蚀开闭运算)——数字图像处理学习八(C++版)_第10张图片

 代码:

double f[9];
  f[0] = 0;
  f[1] = 1;
  f[2] = 0;
  f[3] = 1;
  f[4] = 1;
  f[5] = 1;
  f[6] = 0;
  f[7] = 1;
  f[8] = 0;
  //先腐蚀再膨胀(开操作,一般会平滑物体的轮廓,断开较窄的狭颈并消除细的突出物。
  //腐蚀就是图像中的白的变小
  double* new_data2 = new double[biHead1.biHeight * biHead1.biWidth]();
  for (int i = 0; i < biHead1.biHeight - 2; i++)
    for (int j = 0; j < biHead1.biWidth - 2; j++)
    {
      if ((double_data[i * biHead1.biWidth + j + 1] + f[1] == 256) && (double_data[(i + 1) * biHead1.biWidth + j] + f[3] == 256) && (double_data[(i + 1) * biHead1.biWidth + j + 1] + f[4] == 256) && (double_data[(i + 1) * biHead1.biWidth + j + 2] + f[5] == 256) && (double_data[(i + 2) * biHead1.biWidth + j + 1] + f[7] == 256))
      {
        new_data2[(i + 1) * biHead1.biWidth + j + 1] = 255;//锚点
      }
    }
  //膨胀就是图像中的白的变大
  double* new_data = new double[biHead1.biHeight * biHead1.biWidth]();
  for (int i = 0; i < biHead1.biHeight-2; i++)
    for (int j = 0; j < biHead1.biWidth-2; j++)
    {
      if (new_data2[(i + 1) * biHead1.biWidth + j + 1] + f[4] == 256)
      {
        new_data[i * biHead1.biWidth + j] = 255;
        new_data[i* biHead1.biWidth + j + 1] = 255;
        new_data[i * biHead1.biWidth + j + 2] = 255;
        new_data[(i + 1) * biHead1.biWidth + j ] = 255;
        new_data[(i + 1) * biHead1.biWidth + j + 1] = 255;//锚点
        new_data[(i + 1) * biHead1.biWidth + j + 2] = 255;
        new_data[(i + 2) * biHead1.biWidth + j ] = 255;
        new_data[(i + 2) * biHead1.biWidth + j + 1] = 255;
        new_data[(i + 2) * biHead1.biWidth + j + 2] = 255;
      }
    }

  //显示
  for (int i = 0; i < biHead1.biHeight; i++)
    for (int j = 0; j < biHead1.biWidth; j++)
    {
      dc.SetPixel(j / time, (biHead1.biHeight - i) / time, RGB(new_data[j + i * biHead1.biWidth], new_data[j + i * biHead1.biWidth], new_data[j + i * biHead1.biWidth]));
}

结果:

 图像形态学处理(膨胀腐蚀开闭运算)——数字图像处理学习八(C++版)_第11张图片

五、闭运算

闭运算实质上是先膨胀再腐蚀,它也会平滑轮廓的一部分,但通常会弥合较窄的间断和细长的沟壑,消除小的孔洞,填补轮廓线中的断裂。

举个栗子:

结构元为,图像形态学处理(膨胀腐蚀开闭运算)——数字图像处理学习八(C++版)_第12张图片锚点为中心点

那么闭运算就是如下过程(深色像素为白色):

图像形态学处理(膨胀腐蚀开闭运算)——数字图像处理学习八(C++版)_第13张图片

代码:

double f[9];
  f[0] = 0;
  f[1] = 1;
  f[2] = 0;
  f[3] = 1;
  f[4] = 1;
  f[5] = 1;
  f[6] = 0;
  f[7] = 1;
  f[8] = 0;
  double* new_data = new double[biHead1.biHeight * biHead1.biWidth]();
  //先膨胀再腐蚀(闭操作弥合较窄的间断和细长的沟壑,消除小的空洞,填补轮廓线的中的断裂。
  //膨胀就是图像中的白的变大
  for (int i = 0; i < biHead1.biHeight-2; i++)
    for (int j = 0; j < biHead1.biWidth-2; j++)
    {
      if (double_data[(i + 1) * biHead1.biWidth + j + 1] + f[4] == 256)
      {
        new_data[i * biHead1.biWidth + j] = 255;
        new_data[i* biHead1.biWidth + j + 1] = 255;
        new_data[i * biHead1.biWidth + j + 2] = 255;
        new_data[(i + 1) * biHead1.biWidth + j ] = 255;
        new_data[(i + 1) * biHead1.biWidth + j + 1] = 255;//锚点
        new_data[(i + 1) * biHead1.biWidth + j + 2] = 255;
        new_data[(i + 2) * biHead1.biWidth + j ] = 255;
        new_data[(i + 2) * biHead1.biWidth + j + 1] = 255;
        new_data[(i + 2) * biHead1.biWidth + j + 2] = 255;
      }
    }
  //腐蚀就是图像中的白的变小
  double* new_data2 = new double[biHead1.biHeight * biHead1.biWidth]();
  for (int i = 0; i < biHead1.biHeight - 2; i++)
    for (int j = 0; j < biHead1.biWidth - 2; j++)
    {
      if ((new_data[i * biHead1.biWidth + j + 1] + f[1] == 256) && (new_data[(i + 1) * biHead1.biWidth + j] + f[3] == 256) && (new_data[(i + 1) * biHead1.biWidth + j + 1] + f[4] == 256) && (new_data[(i + 1) * biHead1.biWidth + j + 2] + f[5] == 256) && (new_data[(i + 2) * biHead1.biWidth + j + 1] + f[7] == 256))
      {
        new_data2[(i + 1) * biHead1.biWidth + j + 1] = 255;//锚点
      }
    }
  //显示
  for (int i = 0; i < biHead1.biHeight; i++)
    for (int j = 0; j < biHead1.biWidth; j++)
    {
      dc.SetPixel(j / time, (biHead1.biHeight - i) / time, RGB(new_data2[j + i * biHead1.biWidth], new_data2[j + i * biHead1.biWidth], new_data2[j + i * biHead1.biWidth]));
}

结果:

图像形态学处理(膨胀腐蚀开闭运算)——数字图像处理学习八(C++版)_第14张图片

 

你可能感兴趣的:(数字图像处理学习,图像处理)