天天看點

【halcon】模闆比對和仿射變換總結前言情況一情況二 圖像擺正從圖中得到模闆,和從模闆檔案中得到模闆的細微差別小結

前言

        模闆比對和仿射變換,經常一起使用,他們之前的位置變換一般有兩種情況!

情況一

        模闆是一個很正的圖,利用模闆的位置,将歪的圖像擺正。

【halcon】模闆比對和仿射變換總結前言情況一情況二 圖像擺正從圖中得到模闆,和從模闆檔案中得到模闆的細微差別小結

情況二 

模闆和圖檔正不正都無所謂,隻需想模闆的位置,比對到目前圖檔的位置。

【halcon】模闆比對和仿射變換總結前言情況一情況二 圖像擺正從圖中得到模闆,和從模闆檔案中得到模闆的細微差別小結

 先從比較簡單的第二種情況說起:

我們首先從标準的原圖中擷取模闆(後面會講到,從圖中得到模闆,和從模闆檔案中得到模闆的細微差別。)比如從原圖裡扣出一部分作為模闆如:

reduce_domain (Image, RegionErosion, ImageReduced)
           

建立模闆

然後,就可以通過 create_shape_model  建立模闆了。

*建立模闆
create_shape_model (ImageReduced, 3, 0, rad(360), 'auto', 'auto', 'use_polarity', 'auto', 'auto', ModelID)
           

觀察模闆

接下來可以看看,模闆大概的樣子,幫助後面模闆比對時,确認相關參數(該函數也可忽略):

* 觀察模闆
inspect_shape_model (ImageReduced, ShapeModelImage, ShapeModelRegion, 4, 65)
           

模闆比對

接下來就是 抓取新的一張圖 做模闆比對。兩張圖在同一鏡頭參數,是以共用一坐标系,這是前提,注意這點,友善接下來的了解。

* 模闆比對
find_shape_model (SearchImage, ModelID, 0, rad(360), 0.3, 1, 0.5, 
'least_squares', 0, 1, 
RowMatch, ColumnMatch, AngleMatch, Score)
           

這裡的 SearchImage就是新的一張圖,ModelID就是建立模闆時的輸出參數,和模闆對應。

這裡和 仿射變換 密切相關的參數是:  RowMatch, ColumnMatch, AngleMatch。也就是 XY和角度。

find_shape_model 通過 ModelID,擷取到模闆的相關資訊.(比如,模闆的形狀)

拿到了資訊之後,就開始在新圖中找比對,輸出比對的内容的坐标以及旋轉角度,這個旋轉的角度是相對應模闆圖像的偏移角度,坐标就是比對内容區域中心在圖中的坐标。

仿射變換

*擷取标準圖的摳圖中心
area_center(ImageReduced, Area, Row1, Column1)
*根據兩個中心和角度,算出旋轉矩陣
vector_angle_to_rigid (Row1, Column1, 0, RowMatch, ColumnMatch, AngleMatch, MovementOfModel)
*根據旋轉中心做仿射變換
affine_trans_region(RegionOpening1, RegionAffineTrans, MovementOfModel, 
'nearest_neighbor')
           

模闆比對隻是告訴了我,新的圖像中被比對到的位置(XY)以及對應模闆圖像的偏移角度。

那,如何将 模闆本身 移動到 新圖像中比對到的内容,與之重合?

vector_angle_to_rigid 

我們需要算子:vector_angle_to_rigid 

可以認為,這個算子需要兩個輸入,需要移動的圖形的位姿(xy和角度),以及目标點的位姿(xy和角度)。最後會輸出一個矩陣,這個矩陣,這個矩陣可以完成圖形仿射變換。

那模闆本身在原圖中的坐标,我們可以通過 area_center 這個算子計算得到。(需要知道角度嗎?答案是不需要,因為模闆比對給出的角度是比對到的内容和模闆的角度偏移量。是以模闆的角度預設為0)

是以,就有:

*根據兩個中心和角度,算出旋轉矩陣
vector_angle_to_rigid (Row1, Column1, 0, RowMatch, 
ColumnMatch, AngleMatch, MovementOfModel)
           

Row1, Column1, 0: 就是 模闆的位姿資訊。注意這裡角度就是0

RowMatch, ColumnMatch, AngleMatch:這個就是模闆比對找到的目标資訊。

注意:如果找打的是多個目标,那麼這些變量代表的都是數組。

最後一個參數,MovementOfModel,就是輸出的 變換矩陣。

affine_trans_region

最後,移動這個操作可以通過,affine_trans_region,完成:

*根據旋轉中心做仿射變換
affine_trans_region(RegionOpening1, RegionAffineTrans, MovementOfModel, 
'nearest_neighbor')
           

如果是移動圖檔可以使用,affine_trans_image。

圖像擺正

擺正的思路就是,先去一個擷取一個正的模闆。讀取的圖檔可能是偏的。是以這次不動的是模闆,移動的是圖檔。

* 圖像擺正
area_center(SearchImage, Area, Row2, Column2)

vector_angle_to_rigid (RowMatch, ColumnMatch, AngleMatch, Row2, Column2, 0,  MovementOfModel)

affine_trans_image (SearchImage, ImageAffineTrans, MovementOfModel, 
'constant', 'false')
           

是以這次,在算子vector_angle_to_rigid 中,模闆比對得到的坐标放在前面(誰動,誰放在前面),而圖檔坐标放在後面。如果隻考慮擺正,這裡其實有用的隻是角度。

從圖中得到模闆,和從模闆檔案中得到模闆的細微差別

如果是從圖像裡得到模闆,那麼模闆的位置,以及其他資訊可以直接拿到。

還有更常見的一種用法,就是先将模闆儲存成檔案。也就是先制作一個模闆。

create_shape_model (ImageReduced, 2, 0, rad(360), 'auto', 'auto', 
'use_polarity', 'auto', 'auto', ModelID)
write_shape_model (ModelID, name +'.mb')
           

write_shape_model

建立模闆之後,通過 write_shape_model 将建立的模闆進行儲存。

read_shape_model 

需要使用模闆比對時,在将其讀出:

* 讀取模闆
read_shape_model ('數字05.mb', ModelID)
* 産生的輪廓在原點
get_shape_model_contours (ModelContours, ModelID, 1)
           

get_shape_model_contours 

讀出模闆,得到 ModleID, 然後 get_shape_model_contours 可以根據 ModleID 得到模闆的輪廓。

但是此時,輪廓的位置時在圖檔原點上。(是以,儲存的模闆檔案是不包含位置資訊的)

是以要通過 vector_angle_to_rigid  計算矩陣時,位置參數XY可以填0,角度當然也是0.

【halcon】模闆比對和仿射變換總結前言情況一情況二 圖像擺正從圖中得到模闆,和從模闆檔案中得到模闆的細微差別小結

這個就是通過模闆生成的輪廓,可以看到有點小瑕疵,我們要處理一下:

select_contours_xld (UnionContours, SelectedContours, 
'contour_length', 20, 20000, -0.5, 0.5)
           

上面這句話的意思就是較短的輪廓線不要:

【halcon】模闆比對和仿射變換總結前言情況一情況二 圖像擺正從圖中得到模闆,和從模闆檔案中得到模闆的細微差別小結

還有些輪廓線雖然連在一起,但是不是一個整體,這樣不利于我們進行填充(有時,我們需要對輪廓線進行填充)。

union_adjacent_contours_xld

union_adjacent_contours_xld,可以将連着的輪廓線變成一個對象:

【halcon】模闆比對和仿射變換總結前言情況一情況二 圖像擺正從圖中得到模闆,和從模闆檔案中得到模闆的細微差別小結

 gen_region_contour_xld 

gen_region_contour_xld ,對輪廓線進行填充

* 填充
gen_region_contour_xld (SelectedContours, RegionXLD, 'filled')
           

但是,如果此時填充,會遇到一個問題,前面說到,get_shape_model_contours 擷取的輪廓中心坐标在圖檔原點,那麼,就會有部分的輪廓在圖檔的外面,在外面的部分無法填充。是以,一般我們需要将輪廓移到圖檔内在填充。不過這裡需要注意的是,再進行仿射變換的話,起始坐标,必須是這個移到後的點,而不是(0,0)。

小結

        這篇文章,主要介紹了模闆比對和仿射變換的相關内容,模闆比對的很多相關參數,沒有一一講解。我覺得 模闆比對和仿射變換 的關系 這個更為重要,也更難了解。後續有時間,我也會将模闆比對的關參數記錄一下。歡迎評論區讨論。

繼續閱讀