將上一個筆記中的那個英文段落圖片中的孔洞作填充:算法
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/51971115spa
簡要實現步驟:.net
通過大約1個星期的計劃和嘗試,預估學習一個章節加練習須要4-5天的時間,暫計劃:
從第三章灰度變換與空間濾波開始學習,每章時間必須控制在5天之內,第二章內容穿插在其餘章節中學習,其餘章節提到第二章的內容就去看相關的部分。
第三章到十二章共計十章,今天解決第九章形態學圖像處理以後還剩九章,計劃在45天之後將這本書學完,並對圖像處理有一個系統性的認識。須要在學完以前輸出一個使用Halcon的較爲完整的項目。code
被腐蝕的灰度級圖像比原始圖像更暗,亮特徵的尺寸將會被減少,暗特徵的尺寸將會被增大;
被膨脹的灰度級圖像與腐蝕相反,亮特徵變大,暗特徵下降。blog
用書本中的圖片來作練習,從左到右分別是用一個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)
仍是基本的腐蝕和膨脹,這邊不作額外練習。
一般,開操做用於去除較小的明亮細節,而保持總體灰度級和較大的明亮特徵相對不變;開操做對圖像的暗特徵影響可忽略不計,也不影響背景。
閉操做和開操做相反,削弱了暗細節,對亮的細節和背景影響能夠忽略不計。ci
由於開操做抑制比結構元小的亮細節,閉操做抑制暗細節,因此經常以形態濾波的形式結合起來用做圖像的平滑和去噪。書中舉了一個先對原始圖像開操做再閉操做的例子。文檔
膨脹和腐蝕可與圖像相減結合起來獲得一副圖像的形態學梯度,由g來定義:
\[ g = (f \oplus b) - (f \ominus b) \]
膨脹和腐蝕的差強調了區域間的邊界,只要SE相對較小,同質區域不受影響,相減操做區域消除同質區域,最終結果是邊緣被加強而同質區域被抑制掉了,產生了相似於微分(梯度)的效果。get
使用書中的圖片作練習
四幅圖片依次是原圖,膨脹,腐蝕,相減後的圖像
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)
還須要研究一下爲何效果很差?
第一次作重建開操做的時候的效果仍是很好的,水平方向的反射都消得挺清楚的,字母顯示也挺清楚的
可是在消豎直方向的反射的時候明顯問題很大,反射是消掉了,可是不少須要的豎線也沒有了,並且以後的修復效果也很通常。
第九章小結
僅列出算子,算子的使用建議經過F1查看文檔,會比個人總結要明瞭不少