圖像處理筆記(五)

孔洞填充

將上一個筆記中的那個英文段落圖片中的孔洞作填充:算法

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.7的圓形結構元素)
  2. 模板圖像:原圖像區域的補集
  3. 對標記圖像用3*3的SE作膨脹,而後與標記圖像求交集
  4. 第三步重複n次,直到圖像趨於穩定(兩次膨脹求交集區域的差異爲0,個人代碼中沒有作這樣的處理,直接經過調整次數看效果差很少了就停下來了)
  5. 對第4步處理好的區域求補集

插播一條學習計劃

通過大約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)

還須要研究一下爲何效果很差?
第一次作重建開操做的時候的效果仍是很好的,水平方向的反射都消得挺清楚的,字母顯示也挺清楚的
可是在消豎直方向的反射的時候明顯問題很大,反射是消掉了,可是不少須要的豎線也沒有了,並且以後的修復效果也很通常。

第九章小結

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:求出兩個圖片每個像素的最大值(按照最大像素得出一個新圖片)
相關文章
相關標籤/搜索