图像处理笔记(五)

孔洞填充

将上一个笔记中的那个英文段落图片中的孔洞做填充:

dev_close_window()

dev_open_window (0, 0, 512, 512, 'black', WindowHandle)

read_image(Image, 'words')

threshold(Image, Region, 45, 255)

* 模板图像(原图求补集)
*threshold(Image, Region1, 0, 44)
complement(Region, Region1)

dilation_circle (Region, RegionDilation, 4.7)

* 标记图像
complement(RegionDilation, RegionComplement)

for Index := 1 to 20 by 1
    * 3*3的SE给标记图像做膨胀
    dilation_rectangle1(RegionComplement, RegionDilation1, 3, 3)

    intersection(Region1, RegionDilation1, RegionIntersection)
    
    RegionComplement := RegionIntersection
endfor

complement(RegionComplement, RegionComplement1)

效果图:

因为真的不知道按照书上的说的标记图像F(x, y)是怎么求出来的,在网上找到了另一篇文章,按照他的算法实现了一下,效果不错,感谢博主。
原文链接:
https://blog.csdn.net/walk_on_the_cloud/article/details/51971115

简要实现步骤:

  1. 标记图像:原图像区域膨胀到看不到字母的孔时的区域的补集(本例中使用了半径为4.7的圆形结构元素)
  2. 模板图像:原图像区域的补集
  3. 对标记图像用3*3的SE做膨胀,然后与标记图像求交集
  4. 第三步重复n次,直到图像趋于稳定(两次膨胀求交集区域的差别为0,我的代码中没有做这样的处理,直接通过调整次数看效果差不多了就停下来了)
  5. 对第4步处理好的区域求补集

插播一条学习计划

经过大约1个星期的计划和尝试,预估学习一个章节加练习需要4-5天的时间,暂计划:
从第三章灰度变换与空间滤波开始学习,每章时间必须控制在5天以内,第二章内容穿插在其他章节中学习,其他章节提到第二章的内容就去看相关的部分。
第三章到十二章共计十章,今天解决第九章形态学图像处理之后还剩九章,计划在45天以后将这本书学完,并对图像处理有一个系统性的认识。需要在学完之前输出一个使用Halcon的较为完整的项目。

灰度级形态学

膨胀和腐蚀

被腐蚀的灰度级图像比原始图像更暗,亮特征的尺寸将会被减小,暗特征的尺寸将会被增大;
被膨胀的灰度级图像与腐蚀相反,亮特征变大,暗特征降低。

练习

用书本中的图片来做练习,从左到右分别是用一个3*3灰度为2的SE膨胀后的图像,原图,相同SE腐蚀后的图像

dev_close_window()

dev_open_window (0, 0, 512, 512, 'white', WindowHandle)

read_image(Image, 'grayErosion')

* 生成拥有常数灰度的3*3的图像
gen_image_const(Image1, 'byte', 3, 3)
for Index := 0 to 2 by 1
    for Index1 := 0 to 2 by 1
        * 设置灰度
        set_grayval(Image1, Index, Index1, 2)
    endfor
endfor

* 灰度腐蚀,因为没有直接提供使用圆形或方形SE进行腐蚀的算子,所以上面创建了一个常数灰度的Image
gray_erosion(Image, Image1, ImageErosion)

* 灰度膨胀
gray_dilation(Image, Image1, ImageDilation)

开操作和闭操作

还是基本的腐蚀和膨胀,这边不做额外练习。
通常,开操作用于去除较小的明亮细节,而保持整体灰度级和较大的明亮特征相对不变;开操作对图像的暗特征影响可忽略不计,也不影响背景。
闭操作和开操作相反,削弱了暗细节,对亮的细节和背景影响可以忽略不计。

形态学平滑

因为开操作抑制比结构元小的亮细节,闭操作抑制暗细节,所以常常以形态滤波的形式结合起来用作图像的平滑和去噪。书中举了一个先对原始图像开操作再闭操作的例子。

形态学梯度

膨胀和腐蚀可与图像相减结合起来得到一副图像的形态学梯度,由g来定义:

\[g = (f \oplus b) - (f \ominus b) \]

膨胀和腐蚀的差强调了区域间的边界,只要SE相对较小,同质区域不受影响,相减操作区域消除同质区域,最终结果是边缘被增强而同质区域被抑制掉了,产生了类似于微分(梯度)的效果。

练习

使用书中的图片做练习
四幅图片依次是原图,膨胀,腐蚀,相减后的图像

dev_close_window ()

dev_open_window (0, 0, 512, 512, 'black', WindowHandle)

read_image(Image, 'g')

gen_image_const(Image1, 'byte', 3, 3)
for Index := 0 to 2 by 1
    for Index1 := 0 to 2 by 1
        * 设置灰度
        set_grayval(Image1, Index, Index1, 1)
    endfor
endfor
* 膨胀
gray_dilation(Image, Image1, ImageDilation)

* 腐蚀
gray_erosion(Image, Image1, ImageErosion)

* 使用difference比较两个区域的不同获取到的是一个空区域,
* 可能是因为两幅图像经过腐蚀和膨胀后的灰度都发生了变化,difference不能做灰度上的相减
* difference(ImageDilation, ImageErosion, RegionDifference)

* 图像相减,得到的是绝对值
abs_diff_image(ImageDilation, ImageErosion, ImageAbsDiff, 1)

* 图像相减,得到的不是绝对值,相减具有方向性,反过来减会影响结果
sub_image(ImageDilation, ImageErosion, ImageSub, 1, 0)

主要要注意一下对图像灰度上的运算有些算子和之前不一样。

顶帽变化和底帽变换

灰度级图像f的 顶帽变换 定义为f减去其开操作:

\[T_{hat}(f) = f - (f \circ b) \]

底帽变换 定义为f的闭操作减去f:

\[B_{hat}(f) = (f \bullet b) - f \]

主要应用:从一幅图像中删除物体,而不是拟合被删除的物体,然后,差操作得到一幅仅保留已删除分量的图像。
顶帽变换常用于暗背景上的亮物体,而底帽变换运用于亮背景上的暗物体。因此,常常称这两个变换为白顶帽变换和黑底帽变换。
顶帽变换的重要用途是校正不均匀光照的影响,

一个很极端的练习

关了个灯。。。
我想让灯光变得更均匀一点,结果确实均匀了,就是黑得很均匀

dev_close_window ()

dev_open_window (0, 0, 512, 512, 'black', WindowHandle)

read_image(Image, 'lamp.jfif')

rgb1_to_gray(Image, GrayImage)

* 这是一个足够大的结构元
gen_image_const(Image1, 'byte', 50, 50)
for Index := 0 to 2 by 1
    for Index1 := 0 to 2 by 1
        * 设置灰度
        set_grayval(Image1, Index, Index1, 1)
    endfor
endfor

* 顶帽变换
* 开操作(先腐蚀,再膨胀)
gray_erosion(GrayImage, Image1, ImageErosion)
gray_dilation(ImageErosion, Image1, ImageDilation)

abs_diff_image(GrayImage, ImageDilation, ImageAbsDiff, 1)

* 底帽变换
* 闭操作(先膨胀,再腐蚀)
gray_dilation (GrayImage, Image1, ImageDilation1)
gray_erosion(ImageDilation1, Image1, ImageErosion1)

abs_diff_image(ImageErosion1, GrayImage, ImageAbsDiff1, 1)

三张图从左到右分别是原图转换成的灰度图像,顶帽变换后的图像,底帽变换后的图像

灰度级形态学重建

测地膨胀和腐蚀和之前的是差不多的,使用上也就是针对灰度上的不同,在halcon中计算交集和并集要使用一些关于灰度上的算子,这点要稍微注意一下。
直接上例子。书中的键盘的例子。
试了一下,按照书中说的那样设置SE,效果不好,稍微调整了一下,还是不太好

dev_close_window ()

dev_open_window (0, 0, 512, 512, 'black', WindowHandle)

read_image(Image, 'keyboard')


* 重建开操作,消除水平反射和变化的背景
* 使用71*1的SE腐蚀原图
gen_image_const(Image1, 'byte', 71, 1)
for Index := 0 to 70 by 1
    set_grayval(Image1, 0, Index, 1)
endfor

gray_erosion(Image, Image1, ImageErosion)

for Index1 := 1 to 60 by 1
    gray_dilation(ImageErosion, Image1, ImageDilation)
    min_image(ImageDilation, Image, ImageMin)
    ImageErosion := ImageMin
endfor

* 重建顶帽操作
abs_diff_image(ImageMin, Image, ImageAbsDiff, 1)

* 标准的顶帽操作
* 标准的开操作
gray_erosion(Image, Image1, ImageErosion1)
gray_dilation(ImageErosion1, Image1, ImageDilation1)
* 顶帽操作
abs_diff_image(ImageDilation1, Image, ImageAbsDiff1, 1)

* 重建开操作,消除竖直反射的影响(效果不好,很多竖都不见了)
gen_image_const(Image2, 'byte', 1, 21)
for Index2 := 0 to 20 by 1
    set_grayval(Image2, Index2, 0, 1)
endfor
gray_erosion(ImageAbsDiff, Image2, ImageErosion2)

for Index3 := 1 to 15 by 1
    gray_dilation(ImageErosion2, Image2, ImageDilation2)
    min_image (ImageDilation2, ImageAbsDiff, ImageMin1)
    ImageErosion2 := ImageMin1
endfor
abs_diff_image(ImageMin1, ImageAbsDiff, ImageAbsDiff2, 1)

* 用一个1*31的水平SE膨胀以修复一些字母
gen_image_const (Image3, 'byte', 31, 2)
for Index4 := 0 to 30 by 1
    for Index5 := 0 to 1 by 1
        set_grayval(Image3, Index5, Index4, 1)
    endfor
endfor
gray_dilation(ImageAbsDiff2, Image3, ImageDilation3)

min_image(ImageDilation3, ImageAbsDiff, ImageMin2)

还需要研究一下为什么效果不好?
第一次做重建开操作的时候的效果还是很好的,水平方向的反射都消得挺清楚的,字母显示也挺清楚的
但是在消竖直方向的反射的时候明显问题很大,反射是消掉了,但是很多需要的竖线也没有了,而且之后的修复效果也很一般。

第九章小结

Halcon中本次常用算子小结

仅列出算子,算子的使用建议通过F1查看文档,会比我的总结要明了很多

  1. complement:求区域的补集
  2. intersection:求两个区域的交集
  3. gen_image_const:生成指定大小的常数灰度的图像
  4. set_grayval:设置灰度
  5. gray_erosion:灰度腐蚀
  6. gray_dilation:灰度膨胀
  7. abs_diff_image:图像相减,返回绝对值结果
  8. sub_image:图像相减,具有方向性,减数和被减数交换顺序会导致结果不同
  9. min_image:求出两个图片每一个像素的最小值(按照最小像素得出一个新图片)
  10. max_image:求出两个图片每一个像素的最大值(按照最大像素得出一个新图片)
posted @ 2019-06-25 18:14  yutou2016  阅读(528)  评论(0编辑  收藏  举报