傅里葉變換
-
快速傅里葉正逆變換的兩對算子:
- fft_image和fft_image_inv:分別是把圖像變換到傅里葉頻譜圖和把傅里葉頻譜圖變換為圖像
- fft_generic(Image, ImageFFT, Direction, Exponent, Norm, Mode, ResultType)
這個算子通過不同的Direction來做正逆變換。Direction:to_freq,Exponent:-1;Direction:from_freq,Exponent:1
-
gen_lowpass(ImageLowpass, Frequency, Norm, Mode, Width, Height)
生成一個低通濾波器,截至頻率在0-1之間可選,長寬應當與需要做濾波的圖像長寬一致,這個低通濾波器應當作用於頻率域,可以用來消除周期噪聲。
這里的mode應當與原圖像做fft變換時的mode一致。
截止頻率越小,對噪聲的消除作用越好,但是圖像會越模糊。截止頻率代表了濾波后圖像中心橢圓區域的大小,看圖:
圖像分別是原圖和使用0.1和使用0.5截止頻率濾波的圖像及傅里葉頻譜圖
-
gen_highpass(ImageHighpass, Frequency, Norm, Mode, Width, Height)
構造一個高通濾波器,參數和低通濾波器相似,用高通濾波器做頻率域濾波后,只有中心的亮區域被過濾掉了,剩下的是周圍的區域,從頻譜圖上看,正好與低通濾波器相反。
高通濾波器用來銳化圖像,不能做噪聲過濾。 -
binomial_filter(Image, ImageBinomial, MaskWidth, MaskHeight)
使用二項式濾波光滑處理圖像。需要注意的點在於halcon中已經定義好的filter往往可以直接作用在圖像上,而不能作用在頻譜圖上(像素類型為complex)。
一個頻率域濾波消除噪聲的例子,使用兩種方法:
- 直接使用一個低通濾波器
- 找出頻譜圖上較亮的非中心亮區域,將這些區域過濾掉。
使用了一幅沒有明顯噪聲的圖像疊加了一幅僅含有周期性噪聲的圖像作為原圖像。
read_image(Image3, 'Fig0222(a)(face)')
* 將圖像大小轉換成和噪聲圖像一樣大
zoom_image_size(Image3, ImageZoom, Width, Height, 'constant')
* 圖像與噪聲圖像疊加,代碼中省略了噪聲圖像的構造過程
add_image(ImageResult2, ImageZoom, ImageAdd, 1, 0)
fft_image(ImageAdd, ImageFFT5)
fft_image(ImageZoom, ImageFFT6)
* 方法1,構造一個低通濾波器濾波
gen_lowpass(ImageLowpass1, 0.2, 'none', 'dc_center', Width, Height)
convol_fft(ImageFFT5, ImageLowpass1, ImageConvol2)
* 濾波后的結果
fft_image_inv(ImageConvol2, ImageFFTInv3)
* 方法2
* 使用二項式濾波光滑圖像
binomial_filter(ImageResult3, ImageSmooth, 9, 9)
* 篩選出亮點
threshold(ImageSmooth, Region, 100, 1800)
connection(Region, ConnectedRegions)
select_shape(ConnectedRegions, SelectedRegions, 'area', 'and', 5, 100)
union1(SelectedRegions, RegionUnion)
reduce_domain(ImageSmooth, RegionUnion, ImageReduced)
* 檢測出區域內的局部最大值,這里可以檢測出每個亮點區域中最亮的點
local_max(ImageReduced, LocalMaxima)
dilation_circle(LocalMaxima, RegionDilation, 12.5)
* 把上面找出來的這些膨脹后的亮區域塗成黑色(可以理解為把這些區域過濾掉了)
paint_region(RegionDilation, ImageFFT5, ImageResult4, 0, 'fill')
* 效果圖
fft_image_inv(ImageResult4, ImageFFTInv4)
四張圖分別是原圖,疊加噪聲后的圖,方法1的效果圖,方法2的效果圖。
# 邊緣分析
__Halcon中輪廓線窗口的使用__ :
打開輪廓線窗口,點擊窗口左上角的繪制線段(或繪制弧形),在原圖像上繪制線段,繪制完成后鼠標右擊,就可以在輪廓線窗口上看到這條線上灰度值的變化
halcon中有多種現成的求邊緣的算子,他們之間主要的區別是使用了不同的濾波器來提取輪廓。
```
read_image(Image, 'Fig0219(rose1024)')
laplace_of_gauss(Image, ImageLaplace, 2)
threshold_sub_pix(ImageLaplace, Border, -2)
derivate_gauss(Image, DerivGauss, 0.6, 'gradient')
threshold_sub_pix(DerivGauss, Border1, 15)
frei_amp(Image, ImageEdgeAmp)
threshold_sub_pix(ImageEdgeAmp, Border2, 50)
prewitt_amp(Image, ImageEdgeAmp1)
threshold_sub_pix(ImageEdgeAmp1, Border3, 90)
sobel_amp(Image, EdgeAmplitude, 'sum_abs', 3)
threshold_sub_pix(EdgeAmplitude, Border4, 35)
kirsch_amp(Image, ImageEdgeAmp2)
threshold_sub_pix(ImageEdgeAmp2, Border5, 110)
robinson_amp(Image, ImageEdgeAmp3)
threshold_sub_pix(ImageEdgeAmp3, Border6, 120)
```
使用高斯光滑的拉普拉斯算子最特別,會出現一些負數值,這個值應該不是灰度,而是導數。
## 輪廓的分割合並
上面的求輪廓的算子最終求出來的都是一些不連續的邊緣,需要進一步將這些邊緣做分割合並。
邊緣擬合用於將輪廓線擬合成直線/圓/橢圓。算子普遍以fit_開頭,contour_xld結尾;
輪廓合並用於將距離較近的輪廓合並到一起,算子一般以union_開頭,contours_xld結尾;
輪廓分割:segment_contoures_xld,將輪廓分割為直線/直線和圓弧
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 分割線 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# 標定
目的是減弱相機拍攝引起的圖形畸變。
我決定先跳過這一節
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 分割線 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# 模板匹配
這個知識點的實用性比較強。
書上的灰度匹配的算子已經棄用了。
做了一個小實驗,用一個一條邊和y軸重合的等邊三角形做的模板,去在一幅圖上找匹配,這幅圖上有一個旋轉角度和模板一致的等邊三角形和一個底邊和x軸平行的等邊三角形,結果前一個三角形匹配上了。這也是在預期之中的。
```
gen_contour_polygon_xld(Contour, [0, 100, 50, 0], [0, 0, 50 * sqrt(2), 0])
gen_contour_polygon_xld(Contour1, [200, 50 * sqrt(2) + 200, 50 * sqrt(2) + 200, 200], [50, 0, 100, 50])
gen_region_contour_xld(Contour, Region, 'filled')
gen_region_contour_xld(Contour1, Region1, 'filled')
gen_image_const(Image, 'byte', 512, 512)
overpaint_region(Image, Region, 100, 'fill')
overpaint_region(Image, Region1, 200, 'fill')
gen_image_const(Image1, 'byte', 100, 100)
overpaint_region(Image1, Region, 255, 'fill')
create_shape_model(Image1, 'auto', -0.39, 0.79, 'auto', 'auto', 'use_polarity', 'auto', 'auto', ModelID)
find_shape_model(Image, ModelID, -0.39, 0.79, 0.5, 1, 0.5, 'least_squares', 0, 0.9, Row, Column, Angle, Score)
```