HalCon学习笔记3

一、实例 透视形变图像校正

透视形变图形校正步骤如下

1.读取图像,并对图像进行简单的处理,分割出目标形变区域

2.获取形变区域的轮廓,并计算出顶点坐标信息

3.利用上一步得出的坐标信息,计算投影变换矩阵

4.进行投影变换

二、实现代码

1.将图像转化为灰度图像

rgb1_to_gray (Image_display, GrayImage)

rgb1_to_gray将RGB图像转换为灰度图像

RGB图像的三个通道作为输入图像的前三个通道传递

根据以下公式对图像进行变换:

灰色= 0.299 *红色+ 0.587 *绿色+ 0.114 *蓝色

2.获取图像尺寸

get_image_size(Image_display,imageWidth, imageHeight)

算子get_image_size返回输入图像的大小(宽度和高度)

3.阈值处理,提取较暗的区域DarkRegion

threshold(GrayImage,DarkRegion,0, 80)

阈值选择输入图像中灰度值g满足以下条件的像素:MinGray≤g≤MaxGray

4.分离不相连的区域

connection (DarkRegion, ConnectedRegions)

5.选择面积最大的暗色区域

select_shape_std (ConnectedRegions, displayRegion, 'max_area', 70)

max_area:选择面积最大的区域

6.裁剪屏幕区域

reduce_domain (GrayImage, displayRegion, displayImage)

算子reduce_domain将给定图像的定义域缩小到指定的区域。新定义域计算为旧定义域与区域的交点。因此,新的定义域可以是区域的子集。矩阵的大小没有改变。

指定图像:GrayImage    指定区域:displayRegion   输出图像:displayImage

7.创建边缘轮廓

gen_contour_region_xld (displayRegion, Contours, 'border')

gen_contour_region_xld生成XLD轮廓。如果区域是通过分割操作获得的,则该操作符很有用,但更高层次的操作符,如多边形近似和平行提取,将在边界上执行。对于输入区域的每个连接分量,生成边界的闭合轮廓。

'center':边界像素的中心被用作轮廓点。

'border':边界像素的外部边界被用作轮廓点。

8.将轮廓分割为边

segment_contours_xld (Contours, ContoursSplit, 'lines', 5, 4, 2)

SmoothCont :用于平滑轮廓的点数,取值范围:0、3、5(default)、7、9

MaxLineDist1:轮廓线和近似线之间的最大距离,默认值:4.0

MaxLineDist2:等高线与近似线之间的最大距离,默认值:2.0

9.获取边的数量

count_obj (ContoursSplit, Number)

算子count_obj为对象参数Objects确定它包含的对象数量。在这个连接中,应该注意对象与连接组件是不同的(参见连接)。例如,一个区域由三个未连通的部分组成,其对象数为1。

10.

*存储每条边的起点位置
for index:=1 to Number by 1
   select_obj(ContoursSplit, ObjectCurrent, index)
   *拟合每条边
   fit_line_contour_xld (ObjectCurrent, 'tukey', -1, 0, 5, 2, RowBegin, ColBegin, RowEnd, ColEnd, Nr, Nc, Dist)
   *存储每条边的顶点x坐标
   tuple_concat (XCoordCorners, RowBegin, XCoordCorners)
   *存储每条边的顶点y坐标
   tuple_concat (YCoordCorners, ColBegin, YCoordCorners)
endfor

select_obj将带有Index(从1开始)给出的索引的图标对象从图标输入对象元组objects复制到输出对象ObjectSelected。没有为区域和映像分配新的存储空间。相反,将创建包含对现有对象引用的新对象。对象元组中的对象个数可以通过操作符count_obj查询。

fit_line_contour_xld通过线段逼近XLD轮廓。它不执行输入轮廓的分割。因此,必须确保每个轮廓对应一个且仅对应一个线段。算子返回每个轮廓线的起点(RowBegin, ColBegin),终点(RowEnd, ColEnd),以及由直线的法向量(Nr, Nc)及其距原点的距离Dist给出的轮廓线的回归线,即直线方程由r·Nr+c·Nc-Dist=0。

MaxNumPoints用于计算的轮廓点的最大数量(所有点为-1)

ClippingEndPoints拟合时在轮廓的开始和结束处要忽略的点的数量

Iterations迭代最大迭代次数

ClippingFactor剔除异常值的裁剪因子(典型值:“huber”和“drop”为1.0,“tukey”为2.0)

RowBegin线段起始点的行坐标。

ColBegin线段起始点的列坐标。

RowEnd线段端点的行坐标。

ColEnd线段端点的列坐标。

Nr线参数:法向量的行坐标

Nc线参数:法向量的列坐标

Dist 直线参数:直线到原点的距离

tuple_concat将输入元组T1和T2连接到一个新的元组Concat。Concat的第一个元素符合T1的元素,Concat的其余元素符合T2的元素

hom_vector_to_proj_hom_mat2d (XCoordCorners, YCoordCorners, [1,1,1,1], [YOff,YOff,imageHeight-YOff,imageHeight-YOff], [XOff,imageWidth-XOff,imageWidth-XOff,XOff], [1,1,1,1], 'normalized_dlt', HomMat2D)

hom_vector_to_proj_hom_mat2d确定齐次射影变换矩阵HomMat2D,它最优地满足由至少4个点.如果给出的点对(Px,Py,Pw), (Qx,Qy,Qw)少于4对,则不存在唯一解;如果给出的点对恰好是4对,则矩阵HomMat2D完全按照所需的方式对它们进行变换;如果给出的点对多于4对,则hom_vector_to_projec_hom_mat2d寻求将变换误差最小化。为了实现这样的最小化,有两种不同的算法可用。使用的算法可以通过参数Method来选择。对于传统的几何问题,Method='normalized_dlt'通常会得到更好的结果。但是,如果坐标Qw或Pw中的一个等于0,则必须选择Method='dlt'。

与vector_to_proj_hom_mat2d相反,hom_vector_to_proj_hom_mat2d对点使用齐次坐标,因此可以使用无穷远处的点(Pw = 0或Qw = 0)来确定转换。如果使用有限点,通常将Pw和Qw设为1。在这种情况下,也可以使用vector_to_proj_hom_mat2d。Vector_to_proj_hom_mat2d的优点是可以使用一个额外的优化方法,并且可以考虑到点的协方差。如果还没有确定点之间的对应关系,那么应该使用proj_match_points_ransac来确定对应关系以及转换。

如果要转换的点是在标准图像坐标中指定的,那么它们的行坐标必须传递为Px,列坐标传递为Py。这对于获取图像的右手坐标系是必要的。特别是,这保证了旋转是在正确的方向上进行的。注意,矩阵的(x,y)顺序很自然地对应于图像中坐标的通常顺序(行,列)。

 

11.投影变换

projective_trans_image (Image_display, Image_rectified, HomMat2D, 'bilinear', 'false', 'false')

 projecve_trans_image将齐次变换矩阵HomMat2D确定的射影变换(homography)应用到输入图像image上,并将结果存储到输出图像TransImage中。

完整实现代码

*关闭当前显示窗口,清空屏幕
dev_close_window ()
*读取测试图像
read_image (Image_display, 'C:/Users/Desktop/code/data/display.jpg')
*将图像转化为灰度图像
rgb1_to_gray (Image_display, GrayImage)
*获取图像的尺寸
get_image_size(Image_display,imageWidth, imageHeight)
*新建显示窗口,适应图像尺寸
dev_open_window (0, 0, imageWidth, imageHeight, 'black', WindowHandle1)
dev_display (GrayImage)
*初始化角点坐标
XCoordCorners := []
YCoordCorners := []
*阈值处理,提取较暗的区域
threshold(GrayImage,DarkRegion,0, 80)
*分离不相连的区域
connection (DarkRegion, ConnectedRegions)
*选择面积最大的暗色区域,即屏幕区域
select_shape_std (ConnectedRegions, displayRegion, 'max_area', 70)
*裁剪屏幕区域
reduce_domain (GrayImage, displayRegion, displayImage)
*创建边缘轮廓
gen_contour_region_xld (displayRegion, Contours, 'border')
*将轮廓分割为边
segment_contours_xld (Contours, ContoursSplit, 'lines', 5, 4, 2)
*获取边的数量
count_obj (ContoursSplit, Number)
*存储每条边的起点位置
for index:=1 to Number by 1
   select_obj(ContoursSplit, ObjectCurrent, index)
   *拟合每条边
   fit_line_contour_xld (ObjectCurrent, 'tukey', -1, 0, 5, 2, RowBegin, ColBegin, RowEnd, ColEnd, Nr, Nc, Dist)
   *存储每条边的顶点x坐标
   tuple_concat (XCoordCorners, RowBegin, XCoordCorners)
   *存储每条边的顶点y坐标
   tuple_concat (YCoordCorners, ColBegin, YCoordCorners)
endfor
* 投影变换给四个特征点与校正后的坐标建立关联
XOff:= 100
YOff:= 100*imageHeight/imageWidth
hom_vector_to_proj_hom_mat2d (XCoordCorners, YCoordCorners, [1,1,1,1], [YOff,YOff,imageHeight-YOff,imageHeight-YOff], [XOff,imageWidth-XOff,imageWidth-XOff,XOff], [1,1,1,1], 'normalized_dlt', HomMat2D)
*投影变换
projective_trans_image (Image_display, Image_rectified, HomMat2D, 'bilinear', 'false', 'false')
* 显示校正结果
dev_display (Image_rectified)

三、显示结果

HalCon学习笔记3_第1张图片

 

你可能感兴趣的:(机器视觉,halcon,学习,计算机视觉,图像处理)