与基于透视形变的匹配类似,基于描述符的匹配允许一定程度的透视形变,并且能在有标定和无标定的图像中进行。但是不同的是,基于描述符的匹配与物体的轮廓无关,而是与目标的纹理密切相关,或者说与目标中的特征点相关。基于描述符的匹配步骤如下。
(1)选择ROI。与其他几种方法类似,在创建模板之前,先读取输入图像,选择ROI,可以是任意形状,也可以包含孔洞区域,尽量包含检测目标的突出特征。然后对ROI进行裁剪,得到模板图像。
(2)创建基于描述符的匹配模型。由于基于描述符的匹配模型也有无标定和有标定两种情况,因此可以针对不同的方法选择对应的模型创建方式。可以使用create_uncalib_descriptor_model 算子或者create_calib_descriptor_model算子,分别对应无标定和有标定两种情况。对于有标定的情况,还需要知道相机的内部参数和位姿。
(3)搜索目标。基于描述符的模板也分两种情况,即使用find_uncalib_descriptor_model算子或者find_calib_descriptor_model算子,分别对应无标定和有标定两种情况,返回目标的三维位姿和匹配分数。
(4)优化匹配过程。如果一次匹配的效果不理想,可以通过调整匹配参数来优化匹配结果。例如,修改搜索空间、限制图像金字塔的层级等。
(5)清除模型。匹配结束后,使用clear_component_model算子将模板清除,并释放内存资源。当目标匹配成功后,会得到目标的位置坐标、旋转角度、缩放值、二维投影矩阵和匹配分值等参数。
这些参数可以作为继续匹配的输入,也可以用来进行其他的视觉处理,如图像对齐、几何计算等。其代码如下:
dev_close_window ()
*读取参考图像,这里的参考图像应只包含识别的关键区域,用于创建模板
read_image (ImageLabel, 'data/labelShape-0')
*设置窗口参数用于显示图像
get_image_size (ImageLabel, Width, Height)
dev_open_window (0, 0, Width, Height, 'black', WindowHandle1)
dev_set_draw ('margin')
dev_display (ImageLabel)
*设置用于存储特征点和感兴趣区域的变量
NumPoints := []
RowRoi := [10,10,Height - 10,Height - 10]
ColRoi := [10,Width - 10,Width - 10,10]
*将参考图像中的除边缘外的区域都设为感兴趣区域。因为参考图像已经近似于匹配的纹理样本
gen_rectangle1 (Rectangle, 10, 10, Height - 10, Width - 10)
*显示参考图像上选择的ROI区域
dev_set_line_width (4)
dev_display (Rectangle)
stop ()
*将感兴趣区域剪裁为模板图像
reduce_domain (ImageLabel, Rectangle, ImageReduced)
dev_clear_window ()
dev_display (ImageLabel)
*创建基于描述符的模板
create_uncalib_descriptor_model (ImageReduced, 'harris_binomial', [], [], ['min_rot','max_rot','min_scale','max_scale'], [-90,90,0.2,1.1], 42, ModelID)
*设置模型的原点,为了后面获取坐标作参照
set_descriptor_model_origin (ModelID, -Height / 2, -Width / 2)
*获取模型中特征点的位置
get_descriptor_model_points (ModelID, 'model', 'all', Row_D, Col_D)
*将模型中计算出的特征点存入NumPoints变量中
NumPoints := [NumPoints,|Row_D|]
*读取测试图像,这里读取的是单通道灰度图像,因此省略了通道转化的步骤
read_image (ImageGray, 'data/labelShape-1')
dev_resize_window_fit_image (ImageGray, 0, 0, -1, -1)
dev_display (ImageGray)
*对描述符特征点进行匹配
find_uncalib_descriptor_model (ImageGray, ModelID, 'threshold', 800, ['min_score_descr','guided_matching'], [0.003,'on'], 0.25, 1, 'num_points', HomMat2D, Score)
*显示匹配结果,将特征点用不同的颜色绘制出来
if ((|HomMat2D| > 0) and (Score > NumPoints[0] / 4))
get_descriptor_model_points (ModelID, 'search', 0, Row, Col)
*创建十字标识符
gen_cross_contour_xld (Cross, Row, Col, 6, 0.785398)
projective_trans_region (Rectangle, TransRegion, HomMat2D, 'bilinear')
projective_trans_pixel (HomMat2D, RowRoi, ColRoi, RowTrans, ColTrans)
angle_ll (RowTrans[2], ColTrans[2], RowTrans[1], ColTrans[1], RowTrans[1], ColTrans[1], RowTrans[0], ColTrans[0], Angle)
Angle := deg(Angle)
if (Angle > 70 and Angle < 110)
area_center (TransRegion, Area, Row, Column)
dev_set_color ('green')
dev_set_line_width (4)
dev_display (TransRegion)
dev_set_colored (6)
dev_display (Cross)
endif
endif
stop ()
*匹配结束,释放模板资源
clear_descriptor_model (ModelID)