天天看點

Halcon裡的9點标定

所謂“标定”就是為了得到數學裡的一個矩陣關系。空間中一點(x,y,z) 到空間中另外一點(x1,y1,z1)可以經過平移,旋轉重合。

這個平移和旋轉的過程(仿射變換)被記錄在矩陣關系中(齊次矩陣)。

例如下面簡單的Halcon代碼(二維變化)

hom_mat2d_identity (HomMat2DIdentity)
    tx:=20
    ty:=30
    * 平移20,30像素
    hom_mat2d_translate (HomMat2DIdentity, tx, ty, HomMat2DTranslate)  
    * 旋轉90度
    angle:=rad(90)    
    hom_mat2d_rotate (HomMat2DTranslate, angle, 0, 0, HomMat2DRotate)   
    
    *計算點(20,30)經過上面的平移旋轉後的坐标點(-60,40)
    affine_trans_point_2d (HomMat2DRotate, 20, 30, Qx1, Qy1)
           
Halcon裡的9點标定

 請注意,齊次矩陣作為元組逐行存儲;最後一行不存儲,因為它對于描述仿射變換的所有齊次矩陣都是相同的。 是以,Hom Mat2DIdentity被存儲為元組[1,0,0,1,0]。

标定的目的就是為了得到上面代碼裡的 HomMat2DRotate。有了這個變換矩陣,再給定一個點,就可以得到相同變化後目标點(Qx1,Qy1)

常見的标定有:九點标定和标定闆标定。

九點标定

原理:簡單來了解,假如有人告訴你A坐标系(例如相機圖像坐标系)的一點(x=10,y=20像素),在B坐标系(例如機械手所在坐标系)裡看到的是(x1=2,y1=4), 接下來,他問你如果是(x'=20,y'=30)在B裡看到的是多少呢?

此時會有無數種答案,但如果給定更多的限制條件,例如更多的點(3個以上)在A、B坐标系的對應關系被找到,此時再來問(x'=20,y'=30)在B裡看到的是多少,則答案就是唯一的。

為何有要求3個點以上,就是求解三元一次方程的要求至少有3個已知條件。9點标定是為了提高精度。

标定的行為就是完成上面的發現更多點的對應關系,已知A坐标系的一些點(x,y),在B坐标系裡去行走或視覺識别得到(x',y')。

然後通過求解(x,y)到(x',y')的關系,得到仿射變換齊次矩陣。

Halcon裡的9點标定

執行個體:

*已知A坐标系的9個點
Ax:=[-30,0,30,-30,0,30,-30,0,30]
Ay:=[30,30,30,0,0,0,-30,-30,-30]

*待識别的B坐标點,和上面的A坐标系點一一對應
Bx:=[]
By:=[]
for Index := 1 to 9 by 1
    dev_display (Image)
    * 以下過程為在B坐标系找A中的9個點
    draw_rectangle1 (200000, Row1, Column1, Row2, Column2)
    gen_rectangle1 (Rectangle, Row1, Column1, Row2, Column2)
    reduce_domain (Image, Rectangle, ImageReduced)
    binary_threshold (ImageReduced, Region, 'max_separability', 'light', UsedThreshold)
    connection (Region, ConnectedRegions)
    select_shape (ConnectedRegions, SelectedRegions, 'roundness', 'and', 0.7, 1)
    select_shape (SelectedRegions, SelectedRegion2, 'rb', 'and', 32, 100)
    fill_up (SelectedRegions, RegionFillUp)
    *找到了B坐标系的點(Row,Column)
    area_center (RegionFillUp, Area, Row, Column)
    Bx:=[Bx,Column]
    By:=[By,Row]
endfor
*得到目标變換矩陣HomMat2D
vector_to_hom_mat2d (Bx, By, Ax, Ay, HomMat2D)


*儲存變換矩陣
serialize_hom_mat2d (HomMat2D, SerializedItemHandle)
open_file ('my_vector.mat', 'output_binary', FileHandle) 
fwrite_serialized_item (FileHandle, SerializedItemHandle) 
close_file (FileHandle)

stop ()
*讀取變換矩陣,測試
open_file ('my_vector.mat', 'input_binary', FileHandle) 
fread_serialized_item (FileHandle, SerializedItemHandle) 
deserialize_hom_mat2d (SerializedItemHandle, HomMat2D_9p) 
close_file (FileHandle)

tx:=20
ty:=30
affine_trans_point_2d (HomMat2D_9p, tx, ty, Qx, Qy)
           

繼續閱讀