图像处理——二值填充

作者:追风剑情 发布于:2022-4-11 12:23 分类:Algorithms

图像填充是形态学的一种常用操作,它通过膨胀等操作,根据像素边界求出像素区域。若所用的 非边界元素均标为 0,下述过程将把这个区域用 1 来填充:设 B 为对称结构元素,在图像4中,从区 域边界内的一点 P 开始,将1 赋给 P,X0=P,按下列迭代程序填充整个区域。
22222.png
式中,k= 1,2,3,…结束条件为Xk=Xk-1 。集合Xk和A的并集包含被填充的集合和它的边界。

示例:数学形态学填充

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Drawing;
  4. using System.Drawing.Imaging;
  5. using System.Windows.Forms;
  6. using System.Threading;
  7.  
  8. namespace ImageCorrosion
  9. {
  10. public partial class Form1 : Form
  11. {
  12. public Form1()
  13. {
  14. InitializeComponent();
  15. Image image2 = ComplementaryImage(pictureBox1.Image as Bitmap);
  16. pictureBox2.Image = image2;
  17. Image image3 = FillImage(pictureBox1.Image as Bitmap);
  18. pictureBox3.Image = image3;
  19. }
  20.  
  21. /// <summary>
  22. /// 数学形态学-填充
  23. /// 步骤:
  24. /// (1) 通过原图像A求A的补集图像Ac
  25. /// (2) (创建一张干净的新图A1)在要填充的区域内任选一点P(对应到新图A1的位置),并将此点置为填充色
  26. /// (3) 对A1进行膨胀处理
  27. /// (4) 用膨胀后的A1与Ac求交集(避免超出填充区边界)
  28. /// (5) 重复(3)和(4)直到图像不再改变
  29. /// (6) 用不再膨胀的图像A1与原图像A求并集(将填充区域合并到原图中),得到最终填充后的图像
  30. /// </summary>
  31. /// <param name="src_bmp">原始图</param>
  32. /// <returns></returns>
  33. private Image FillImage(Bitmap src_bmp)
  34. {
  35. //补集图
  36. Bitmap cpl_bmp = pictureBox2.Image as Bitmap;
  37. //填充图
  38. Bitmap dst_bmp = new Bitmap(src_bmp.Width, src_bmp.Height, src_bmp.PixelFormat);
  39.  
  40. //定义初始点坐标(选择填充区域内任意一点)
  41. int orgX = 130;
  42. int orgY = 145;
  43. //将初始点设为目标色
  44. dst_bmp.SetPixel(orgX, orgY, Color.White);
  45.  
  46. //迭代膨胀
  47. while (DilateImage(src_bmp, dst_bmp, cpl_bmp)) ;
  48. //原图与膨胀后的图求并集
  49. UnionImage(src_bmp, dst_bmp);
  50.  
  51. return dst_bmp;
  52. }
  53.  
  54. //数学形态学-补集图(交换背景与前景色)
  55. private Image ComplementaryImage(Bitmap src_bmp)
  56. {
  57. Rectangle rect = new Rectangle(0, 0, src_bmp.Width, src_bmp.Height);
  58. Bitmap bmp_clone = src_bmp.Clone(rect, PixelFormat.Format24bppRgb);
  59. for (int y = 0; y < src_bmp.Height; y++)
  60. {
  61. for (int x = 0; x < src_bmp.Width; x++)
  62. {
  63. Color c = src_bmp.GetPixel(x, y);
  64. bmp_clone.SetPixel(x, y, (c.R==255) ? Color.Black : Color.White);
  65. }
  66. }
  67. return bmp_clone;
  68. }
  69.  
  70. //数学形态学-求并集图
  71. private void UnionImage(Bitmap src_bmp, Bitmap dst_bmp)
  72. {
  73. for (int i=0; i<src_bmp.Height; i++)
  74. {
  75. for (int j=0; j<src_bmp.Width; j++)
  76. {
  77. Color c = src_bmp.GetPixel(j, i);
  78. if (c.R == 0)
  79. continue;
  80. dst_bmp.SetPixel(j, i, Color.White);
  81. }
  82. }
  83. }
  84.  
  85. //数学形态学—膨胀图片
  86. private bool DilateImage(Bitmap src_bmp, Bitmap dst_bmp, Bitmap cpl_bmp)
  87. {
  88. //对于八连通图需使用4连通模板进行膨胀
  89. //对于四连通图需使用8连通模板进行膨胀
  90. //定义一个3x3的结构模板,原点[1,1]。
  91. int[,] templet = new int[,] {
  92. { 0, 1, 0 },
  93. { 1, 1, 1 },
  94. { 0, 1, 0 }
  95. };
  96.  
  97. //这里为了简单起见,直接忽略图像边缘
  98. bool result = false;
  99. for (int y=1; y<src_bmp.Height-1; y++)
  100. {
  101. for (int x=1; x<src_bmp.Width-1; x++)
  102. {
  103. if (IsMatchTemplet(x, y, dst_bmp, templet))
  104. {
  105. //膨胀(即,腐蚀背景)
  106. bool rst = DilateTemplet(x, y, dst_bmp, templet, cpl_bmp);
  107. if (rst)
  108. result = rst;
  109. }
  110. }
  111. }
  112. return result;
  113. }
  114.  
  115. //判断模板原点是否击中目标图像
  116. //模板中1对应目标图像,0对应背景
  117. private bool IsMatchTemplet(int x, int y, Bitmap dst_bmp, int[,] templet)
  118. {
  119. Color c = dst_bmp.GetPixel(x, y);
  120. return c.R == 255;
  121. }
  122.  
  123. //对模板覆盖区域进行膨胀处理
  124. private bool DilateTemplet(int x, int y, Bitmap dst_bmp, int[,] templet, Bitmap cpl_bmp)
  125. {
  126. bool result = false;
  127. int endX = x + 1;
  128. int endY = y + 1;
  129.  
  130. for (int py=y-1,ty=0; py<=endY; py++,ty++)
  131. {
  132. for (int px=x-1,tx=0; px<=endX; px++,tx++)
  133. {
  134. //模板为0的位置所覆盖的区域不做处理
  135. int tv = templet[tx,ty];
  136. if (tv == 0)
  137. continue;
  138. //判断补集图中的此点像素,
  139. //如果为背景色,则做忽略处理,避免膨胀操作超出填充区域边界。
  140. Color cpl = cpl_bmp.GetPixel(px, py);
  141. if (cpl.R == 0)
  142. continue;
  143. Color c = dst_bmp.GetPixel(px, py);
  144. if (c.R == 0)
  145. {
  146. dst_bmp.SetPixel(px, py, Color.White);
  147. result = true;//图像被膨胀了
  148. }
  149. }
  150. }
  151. return result;
  152. }
  153. }
  154. }

111111.png

标签: Algorithms

Powered by emlog  蜀ICP备18021003号-1   sitemap

川公网安备 51019002001593号