我在Gitee上建了個倉庫,會將學習書本的時候打的一些代碼上傳上去,筆記中所有代碼都在倉庫里,初學的朋友可以一起交流哦!地址(Gitee)
第五章 圖像運算
圖像的代數運算
加法運算
以平均處理的方法將圖像加法運用到圖像的去噪中,先將噪聲\(\eta(x,y)\)加入原始圖像\(f(x,y)\)中,即$ g(x,y)=f(x,y)+\eta(x,y) $
然后重復操作數次,將得到的\(K\)張不同的噪聲圖取平均值,得到平均值圖像\(\overline{g}(x,y)\),即
用到的算子
add_image(Image1, Image2 : ImageResult : Mult, Add : )
作用:將兩幅圖像相加
新圖像ImageResult
的灰度值計算如下
圖像加法的平均處理程序如下
dev_close_window ()
read_image (Image, '噪點圖')
get_image_size (Image, Width, Height)
dev_open_window (0, 0, Width*1.5, Height*1.5, 'black', WindowHandle)
dev_display (Image)
rgb1_to_gray (Image, GrayImage)
* 將數據類型轉換為實數
convert_image_type (GrayImage, ImageConverted, 'real')
* 復制圖片,保護原圖
copy_image (ImageConverted, DupImage)
* 生成空圖像數組
gen_empty_obj (ImageNoiseArray)
* 循環生成白噪聲圖存入數組
for i:=1 to 10 by 1
add_noise_white (DupImage, ImageNoise, 60)
concat_obj (ImageNoiseArray, ImageNoise, ImageNoiseArray)
endfor
* 疊加圖像
for i:=2 to 10 by 1
if(i=2)
* 選擇前兩張圖片相加
select_obj (ImageNoiseArray, ObjectSelected, 1)
select_obj (ImageNoiseArray, ObjectSelected1, 2)
add_image (ObjectSelected, ObjectSelected1, ImageResult, 1, 0)
else
* 循環疊加圖片
select_obj (ImageNoiseArray, ObjectSelected2, i)
add_image (ObjectSelected2, ImageResult, ImageResult, 1, 0)
endif
endfor
* 對生成的圖片求平均值
scale_image (ImageResult, ImageScaled, 0.1, 10)
運行結果感覺不是很好
圖像合成的程序如下
read_image (Image, 'patras')
read_image (Image1, 'brycecanyon1')
Width:=720
Height:=480
* 裁剪兩張圖片得到形同大小區域
crop_part (Image, ImagePart, 0, 0, Width, Height)
crop_part (Image1, ImagePart1, 0, 0, Width, Height)
dev_close_window ()
dev_open_window (0, 0, Width, Height, 'black', WindowHandle)
dev_display (ImagePart)
* 設置字體
set_display_font (WindowHandle, 16, 'mono', 'true', 'false')
disp_message (WindowHandle, 'Image', 'window', 20, 20, 'black', 'true')
stop ()
dev_display (ImagePart1)
disp_message (WindowHandle, 'Image1', 'window', 20, 20, 'black', 'true')
stop ()
add_image (ImagePart, ImagePart1, ImageResult, 0.5, 0)
dev_display (ImageResult)
disp_message (WindowHandle, 'Composite Image', 'window', 20, 20, 'black', 'true')
運行結果如下圖
圖像減法
對兩幅圖像的差異可以用圖像減法檢測出,HLACON中計算圖像差異通常是計算兩幅圖像的對應像素點的差異。
HLACON實現圖像減法的算子如下
sub_image(ImageMinuend, ImageSubtrahend : ImageSub : Mult, Add : )
作用:圖像相減,ImageMinuend
-ImageSubtrahend
得到的ImageSub
灰度值g'
表達式如下
圖像減法程序運行結果如下
圖像乘法
圖像乘法可以用來將圖像中所需的部分提取出來,就是將掩模圖和待處理圖片相乘(掩模圖和待處理圖像必須是同一通道的圖像)
HALCON中實現圖像乘法的算子如下
mult_image(Image1, Image2 : ImageResult : Mult, Add : )
作用:圖像相乘
得到的圖像ImageResult
的灰度值g'
表達式如下
圖像乘法程序如下
dev_close_window ()
read_image (Image, 'fabrik')
get_image_size (Image, Width, Height)
dev_open_window (0, 0, Width, Height, 'black', WindowHandle)
dev_display (Image)
read_image (Image1, '掩模')
* 將圖像轉為單通道
rgb1_to_gray (Image1, GrayImage)
* 圖像相乘
mult_image (Image, GrayImage, ImageResult, 0.005, 0)
程序運行結果如下圖
圖像除法
圖像除法可以用於校正成像設備的非線性影響,除法也可以檢測圖像的變化,但是除法操作給出的是相應像素間的變化比率,而不是像素的絕對差異,因此圖像除法也被稱為比率變換
HALCON中實現圖像除法的算子如下
div_image(Image1, Image2 : ImageResult : Mult, Add : )
作用:圖像相除
得到的圖像ImageResult
的灰度值g'
表達式如下
圖像除法程序如下
dev_close_window ()
dev_update_off ()
read_image (Image, 'autobahn/scene_00')
* 創建灰度斜坡圖
gen_image_gray_ramp (ImageGrayRamp, 0.2, 0.2, 128, 256, 256, 512, 512)
dev_open_window_fit_image (Image, 0, 0, -1, -1, WindowHandle)
* 設置字體
set_display_font (WindowHandle, 16, 'mono', 'true', 'false')
dev_display (Image)
disp_message (WindowHandle, 'Origin Image', 'window', 12, 12, 'black', 'true')
stop ()
dev_display (ImageGrayRamp)
disp_message (WindowHandle, 'Gray Value Image', 'window', 12, 12, 'black', 'true')
stop ()
* 圖像相除
div_image (Image, ImageGrayRamp, ImageResult, 255, 0)
dev_display (ImageResult)
disp_message (WindowHandle, 'Resulting Image', 'window', 12, 12, 'black', 'true')
程序運行結果如下圖
圖像邏輯運算(位操作)
圖像位操作的程序如下
read_image (Image, 'fabrik')
read_image (Image1, '掩模')
read_image (Image2, '1.bmp')
read_image (Image3, '2.bmp')
rgb1_to_gray (Image1, GrayImage)
* 按位與
bit_and (Image, GrayImage, ImageAnd)
* 按位或
bit_or (Image, GrayImage, ImageOr)
* 按位異或
bit_xor (Image2, Image3, ImageXor)
* 按位取反
bit_not (Image2, ImageNot)
* 按位左移
bit_lshift (Image3, ImageLShift, 3)
* 按位右移
bit_rshift (Image3, ImageRShift, 3)
程序運行效果如下圖
圖像的幾何變換
圖像幾何變換的一般表達式
-
點變換
圖像處理其實就是針對圖像的每個像素點的處理,點處理分為幾種,有比例變換、原點變換、繞x/y/x=y軸翻轉、剪移等 -
直線變換——兩個點的變換
判斷兩條直線平行與否只需要判斷直線上的兩個點即可 -
單位正方形變換
在單位正方形和平行四邊形之間建立映射關系,達到互相轉換
仿射變換
仿射變換可以做到對圖像上的物體進行平移和角度修正,仿射變換的一般表達式為
HLAOCN中做仿射變換需要先定義變換矩陣,然后對矩陣進行平移、縮放、旋轉等操作后在應用矩陣到圖像或區域上,有關算子列舉一些在下面
hom_mat2d_identity( : : : HomMat2DIdentity)
作用:定義仿射變換矩陣
hom_mat2d_translate( : : HomMat2D, Tx, Ty : HomMat2DTranslate)
作用:在2D齊次仿射變換中增加平移變換
hom_mat2d_scale( : : HomMat2D, Sx, Sy, Px, Py : HomMat2DScale)
作用:在2D齊次仿射變換中增加縮放變換
hom_mat2d_rotate( : : HomMat2D, Phi, Px, Py : HomMat2DRotate)
作用:在2D齊次仿射變換中增加旋轉變換
affine_trans_region(Region : RegionAffineTrans : HomMat2D, Interpolate : )
作用:針對區域做仿射變換
affine_trans_image(Image : ImageAffinTrans : HomMat2D, Interpolation, AdaptImageSize : )
作用:針對圖像做仿射變換
仿射變換的程序如下
dev_close_window ()
dev_open_window (0, 0, 512, 512, 'white', WindowHandle)
dev_set_color ('red')
gen_rectangle1 (Rectangle, 20, 20, 100, 100)
dev_display (Rectangle)
* 定義仿射變換矩陣
hom_mat2d_identity (HomMat2DIdentity)
* 增加平移變換量
hom_mat2d_translate (HomMat2DIdentity, 0, 120, HomMat2DTranslate)
* 應用仿射變換
affine_trans_region (Rectangle, RegionAffineTrans, HomMat2DTranslate, 'nearest_neighbor')
dev_display (RegionAffineTrans)
* 增加縮放變換量
hom_mat2d_scale (HomMat2DTranslate, 1.2, 1.2, 16, 16, HomMat2DScale)
* 應用仿射變換
affine_trans_region (RegionAffineTrans, RegionAffineTrans1, HomMat2DScale, 'nearest_neighbor')
dev_display (RegionAffineTrans1)
* 增加旋轉變化量
hom_mat2d_rotate (HomMat2DTranslate, 0.6, 256,256, HomMat2DRotate)
* 偏移一下位置
hom_mat2d_translate (HomMat2DRotate, 150, 50, HomMat2DTranslate1)
* 適當變大
hom_mat2d_scale (HomMat2DTranslate1, 2, 2, 64, 64, HomMat2DScale1)
* 應用仿射變換
affine_trans_region (RegionAffineTrans, RegionAffineTrans2, HomMat2DScale1, 'nearest_neighbor')
dev_display (RegionAffineTrans2)
程序運行結果如下圖
投影變換
投影變換也是一種平面映射,可以稱為特殊的投影變換,它的正變換和逆變換都是單值的,而且可以保證任意方向上的直線經過變換還能保持直線
投影變換的算子如下
hom_vector_to_proj_hom_mat2d( : : Px, Py, Pw, Qx, Qy, Qw, Method : HomMat2D)
作用:確定投影變換矩陣HomMat2D
指定矩陣的四個點,從而確定矩陣
灰度插值
- 最近鄰插值法
最近鄰插值法也稱為零階插值,即令變換后像素的灰度值等於距離它最近的輸入像素的灰度值。這種方法造成的空間偏移誤差為\(\frac{1}{\sqrt{2}}\)像素
- 雙線性插值法
雙線性插值法也稱為一階插值,這種方法是沿着圖像矩陣的每一行(列)進行插值,然后對插值后得到的矩陣再沿着行(列)方向進行線性插值
這種方法在對相鄰4個像素點的時候得到的表面在鄰域是吻合的,但是斜率是不同的,這樣會讓圖像的細節產生退化
- 卷積插值法
卷積插值法在輸入圖像的兩行列之間插入零值,然后通過低通模版濾波得到插值后的圖像
灰度插值法程序如下
dev_update_window ('off')
dev_update_var ('off')
dev_update_time ('off')
dev_update_pc ('off')
dev_set_color ('red')
read_image (Image, 'forest_road')
dev_display (Image)
threshold (Image, Regions, 160, 218)
* 開運算
opening_circle (Regions, RegionOpening, 9)
dev_display (RegionOpening)
disp_message (3600,'Ready to rotate', 'window', 12, 12, 'black', 'true')
stop ()
* 定義仿射變換矩陣
hom_mat2d_identity (HomMat2DIdentity)
Scale:=1 //縮放比例
*循環旋轉和縮放
for Phi := 0 to 360 by 1
hom_mat2d_rotate (HomMat2DIdentity, rad(Phi), 256, 256, HomMat2DRotate)
hom_mat2d_scale (HomMat2DRotate, Scale, Scale, 256, 256, HomMat2DScale)
* 對圖像和區域應用仿射變換
affine_trans_image (Image, ImageAffinTrans, HomMat2DScale, 'nearest_neighbor', 'false')
affine_trans_region (RegionOpening, RegionAffineTrans, HomMat2DScale, 'nearest_neighbor')
dev_display (ImageAffinTrans)
dev_display (RegionAffineTrans)
* 更改縮放比例
Scale:=Scale/1.005
endfor
stop ()
*循環旋轉和縮放
for Phi := 0 to 360 by 1
hom_mat2d_rotate (HomMat2DIdentity, rad(-Phi), 256, 256, HomMat2DRotate)
hom_mat2d_scale (HomMat2DRotate, Scale, Scale, 256, 256, HomMat2DScale)
* 對圖像和區域應用仿射變換
affine_trans_image (Image, ImageAffinTrans, HomMat2DScale, 'nearest_neighbor', 'false')
affine_trans_region (RegionOpening, RegionAffineTrans, HomMat2DScale, 'nearest_neighbor')
dev_display (ImageAffinTrans)
dev_display (RegionAffineTrans)
* 更改縮放比例
Scale:=Scale*1.005
endfor
disp_message (3600, '好玩吧', 'window', 12, 12, 'black', 'true')
stop ()
dev_update_window ('on')
dev_update_var ('on')
dev_update_time ('on')
dev_update_pc ('on')
程序運行結果如下圖
圖像校正
圖像校正非常有用,在"掃描全能王"之類的掃描軟件里面經常用到,可以將不是正對着屏幕的文件變成正常的矩形顯示出來,在HLACON中也可以實現這種效果,只是我現在功力還不足,只能做到手動標注矩陣點
圖像校正程序運行結果如下圖
第五章的筆記就到這里啦,如果你一路看到了這里,幫我點個贊吧O(∩_∩)O~,祝大家學習能有所收獲!😀