Halcon/C# 图像窗口、读取图片及仿射变换

一、Halcon 清理窗口

清除图像窗口的显示。

cs 复制代码
dev_clear_window()

二、Halcon 读取图片

(一) 读取一张图片

cs 复制代码
read_image (Image, 'printer_chip/printer_chip_01')

Image:(输出参数)读取到的图片变量名
第二个参数:图片路径,这里可以自行修改为本地图片路径

(二) 转为灰度图

cs 复制代码
rgb1_to_gray(Image, GrayImage)

三、Halcon 仿射变换

(一) 概述

仿射变换,即在二维平面内,对象进行平移、缩放、翻转、旋转和斜切等操作。

仿射变换可以保持原来的线共点,点共线的关系不变,保持原来相互平行的线仍然平行;保持原来的中点仍是中点,保持原来在一直线上几段线段之间的比例关系不变,但不能保持原来的线段长度和夹角不变。

(二) 仿射变换类型

仿射变换有:平移、缩放、翻转、旋转和斜切(就是将斜体字导正)。

(三) 仿射变换流程

仿射变换的步骤主要有以下三步:

  1. 获取特征点坐标、角度;
  2. 对图像、区域、轮廓进行仿射变换。
  3. 计算仿射变换矩阵;

(四) 根据特征点、角度计算仿射变换矩阵

1. 从空变换矩阵创建仿射变换矩阵

产生仿射变换矩阵(产生一个空的二维空变换矩阵)

cs 复制代码
hom_mat2d_identity(:::HomMat2dIdentity)

2. 仿射变换图片

在后续向空变换矩阵添加了需求(旋转、缩放等)之后,可以根据需要把仿射变换之后的图片显示出来。

cs 复制代码
affine_trans_image(Image,ImageAffineTrans,HomMat2d,'constant','false')

Image:原始图片变量
ImageAffineTrans:仿射变换后的图片变量
HomMat2D(输入参数):仿射变换矩阵

3. 把旋转角度添加到仿射变换矩阵

把旋转角度添加到仿射变换矩阵

cs 复制代码
hom_mat2d_rotate(::HomMat2d, Phi, Px, Py : HomMat2dRotate)

HomMat2D(输入参数):仿射变换矩阵
Phi:旋转角度(单位弧度)
Px:变换的固定点行坐标。固定点是指以该点为支撑进行仿射变换(这里是指围绕这点进行旋转)
Py:变换的固定点列坐标
HomMt2DRotate:变换的固定点列坐标

rad(角度) 函数用于旋转一定的角度。若为正,则顺时针旋转,若为负数,则逆时针旋转。

例如有:

cs 复制代码
dev_clear_window()
read_image (Image, 'C:/Users/L/Desktop/练习.bmp')
hom_mat2d_identity (HomMat2DIdentity)
*创建一个旋转的仿射变换矩阵
hom_mat2d_rotate (HomMat2DIdentity, rad(90), 0, 0, HomMat2DRotate)
affine_trans_image (Image, ImageAffineTrans, HomMat2DRotate, 'constant', 'false')

4. 把缩放添加到仿射变换矩阵

把缩放添加到仿射变换矩阵

cs 复制代码
hom_mat2d_scale(::HomMat2D, Sx, Sy, Px, Py :HomMat2DScale)

HomMat2D(输入参数):仿射变换矩阵
Sx(输入参数):x 轴方法的缩放因子
Sy(输入参数):y 轴方法的缩放因子
Px(输入参数):变换的固定点行坐标
Py(输入参数):变换的固定点列坐标
HomMat2DScale(输出参数):输出缩放变换矩阵

例如有:

cs 复制代码
dev_clear_window ()
read_image (Image, 'C:/Users/L/Desktop/练习.bmp')
hom_mat2d_identity (HomMat2DIdentity)
*创建一个缩放的仿射变换矩阵
hom_mat2d_scale (HomMat2DIdentity, 0.5, 0.5, 0, 0, HomMat2DScale)
affine_trans_image (Image, ImageAffineTrans, HomMat2DScale, 'constant', 'false')

5. 把平移添加到仿射变换矩阵

把平移添加到仿射变换矩阵

cs 复制代码
hom_mat2d_translate(::HomMat2D, Tx, Ty :HomMat2DTranslate)

HomMat2D(输入参数):仿射变换矩阵
Tx(输入参数):沿 x 轴方向平移的距离
Ty(输入参数):沿 y 轴方向平移的距离
HomMat2DTranslate(输出参数):输出平移变换矩阵

例如有:

cs 复制代码
dev_clear_window ()
read_image (Image, 'C:/Users/L/Desktop/练习.bmp')
hom_mat2d_identity (HomMat2DIdentity)
*创建一个平移的仿射变换矩阵
hom_mat2d_translate (HomMat2DIdentity, 200, 200, HomMat2DTranslate)
affine_trans_image (Image, ImageAffineTrans, HomMat2DTranslate, 'constant', 'false')

6. 把斜切添加到仿射变换矩阵

把斜切添加到仿射变换矩阵

cs 复制代码
hom_mat2d_slant(::HomMat2D, Theta, Axis, Px, Py :HomMat2DSlant)

HomMat2D(输入参数):仿射变换矩阵
Theta(输入参数):斜切角度(单位弧度)
Axis(输入参数):斜切的坐标值、取值列表:x,y
Px(输入参数):变换的固定点行坐标
Py(输入参数):变换的固定点列坐标
HomMat2DSlant(输出参数):输出斜切变换矩阵

例如有:

cs 复制代码
dev_clear_window ()
read_image (Image, 'C:/Users/L/Desktop/练习.bmp')
hom_mat2d_identity (HomMat2DIdentity)
*创建一个斜切的仿射变换矩阵
hom_mat2d_slant (HomMat2DIdentity, rad(10), 'x', 130, 120, HomMat2DSlant)
affine_trans_image (Image, ImageAffineTrans, HomMat2DSlant, 'constant', 'false')

7. 根据点和角度计算刚性仿射变换矩阵

根据点和角度计算刚性仿射变换矩阵,支持旋转和平移。一般用于处理斜着的图片,也就是将想要处理的地方转正。

cs 复制代码
vector_angle_to_rigid(::Row1, Column1, Angle1, Row2, Column2, Angle2 :HomMat2D)

Row1(输入参数):原始点行坐标
Column1(输入参数):原始点列坐标
Angle1(输入参数):原始点角度
Row1(输入参数):变换的目的点行坐标
Column1(输入参数):变换的目的点列坐标
Angle1(输入参数):变换的目的点角度
HomMat2D(输出参数):输出仿射变换矩阵

原始坐标可以通过一个算子获得:area_center(Image, Area, Row, Column),这里获得的是图片的中心点和对应面积 Area。原始角度也可以通过一个算子获得:orientation_region(Image, Phi),这时在使用点和角度计算刚性仿射变换矩阵时可以使用这两个算子,但需要注意变换的目的点角度需要更改,例如有:

cs 复制代码
dev_clear_window ()
read_image (Image, 'C:/Users/L/Desktop/练习.bmp')
*获取当前图片中心点及对应面积
area_center (Image, Area, Row, Column)
*获取图片原始弧度
orientation_region (Image, Phi)
*创建一个根据点和角度计算刚性仿射变换矩阵
vector_angle_to_rigid (Row, Column, Phi, Row, Column, rad(0), HomMat2D)
*仿射变换图片
affine_trans_image (Image, ImageAffineTrans, HomMat2D, 'constant', 'false')

在获取图片原始弧度时,若获得的角度为负数,则变换的目的点角度一般为0°,若获得的角度为正数,则变换的目的点角度一般为180°。

(五) 根据多个特征点计算仿射变换矩阵

1. 根据两个以上特征点计算刚性仿射变换矩阵

根据两个以上点计算刚性仿射变换矩阵,支持旋转和平移

复制代码
vector_to_rigid(::Px, Py, Qx, Qy :HomMat2D)

Px(输入参数):原始点组的 x 坐标
Py(输入参数):原始点组的 y 坐标
Qx(输入参数):变换的目的点组的 x 坐标
Qy(输入参数):变换的目的点组的 y 坐标
HomMat2D(输出参数):输出仿射变换矩阵

例如有:

复制代码
* 生成椭圆
gen_ellipse_contour_xld (ContEllipse, 200, 100, 0, 70, 95, rad(0), rad(360), 'positive', 2.5)
get_contour_xld (ContEllipse, Row, Col)
* 根据多个点生成仿射变换矩阵
vector_to_rigid (Col, Row, Col, Row, HomMat2D)
* 平移
hom_mat2d_translate (HomMat2D, 50, 150, HomMat2DTranslate)
* 仿射变换图片
affine_trans_contour_xld (ContEllipse, ContoursAffineTrans, HomMat2DTranslate)

2. 根据两个以上特征点计算近似仿射变换矩阵

复制代码
vector_to_similarity(::Px, Py, Qx, Qy :HomMat2D)

Px(输入参数):原始点组的 x 坐标
Py(输入参数):原始点组的 y 坐标
Qx(输入参数):变换的目的点组的 x 坐标
Qy(输入参数):变换的目的点组的 y 坐标
HomMat2D(输出参数):输出仿射变换矩阵

例如有:

复制代码
dev_clear_window ()

* 生成椭圆
gen_ellipse_contour_xld (ContEllipse, 200, 100, rad(60), 70, 95, rad(0), rad(360), 'positive', 1.5)
* 得到椭圆的轮廓
get_contour_xld (ContEllipse, Row, Col)

* 创建一个矩阵
hom_mat2d_identity (HomMat2DIdentity)
hom_mat2d_translate (HomMat2DIdentity, 200, 150, HomMat2DTranslate)
affine_trans_contour_xld (ContEllipse, ContoursAffineTrans, HomMat2DTranslate)
hom_mat2d_rotate (HomMat2DTranslate, rad(90), 200, 150, HomMat2DRotate)
affine_trans_contour_xld (ContoursAffineTrans, ContoursAffineTrans1, HomMat2DRotate)
affine_trans_point_2d (HomMat2DRotate, Col, Row, Col1, Row1)

* 生成一个近似的仿射变换矩阵
vector_to_similarity (Col1, Row1, Col1, Row1, HomMat2D)

affine_trans_contour_xld (ContoursAffineTrans1, ContoursAffineTrans2, HomMat2D)

计算刚性的仿射变换矩阵所获的的图片与计算近似的仿射变换矩阵所获的的图片基本相似。

3. 根据三个以上特征点获取仿射变换矩阵

根据三个以上特征点计算仿射变换矩阵,支持旋转、平移、缩放、斜切。一般用于处理将图像坐标与物理坐标进行对应。

复制代码
vector_to_hom_mat2d(::Px, Py, Qx, Qy :HomMat2D)

Px(输入参数):原始点组的 x 坐标
Py(输入参数):原始点组的 y 坐标
Qx(输入参数):变换的目的点组的 x 坐标
Qy(输入参数):变换的目的点组的 y 坐标
HomMat2D(输出参数):输出仿射变换矩阵

例如有:

复制代码
* 图像坐标
r:=[400,350,680,50,45]
c:=[350,300,600,25,65]

* 物理坐标(例如机械手臂)
r1:=[0,2,-2,-1,1]
c1:=[0,1,-4,-2,10]

* 生成仿射变换矩阵
vector_to_hom_mat2d (r, c, r1, c1, HomMat2D)

*图像坐标仿射变换为物理坐标
affine_trans_point_2d (HomMat2D, 500, 200, Qx, Qy)

* 物理坐标放射为图像坐标
hom_mat2d_invert (HomMat2D, HomMat2DInvert)

affine_trans_point_2d (HomMat2DInvert, Qx, Qy, Qx1, Qy1) 

4. 计算仿射变换参数

根据仿射变换矩阵(齐次二维变换矩阵)计算仿射变换参数,主要用于得到一些列仿射变换(旋转、平移、缩放等)的数据。

复制代码
hom_mat2d_affine_par(::HomMat2D :Sx, Sy, Phi, Theta, Tx, Ty)

HomMat2D(输入参数):仿射变换矩阵
Sx(输入参数):x 方向的缩放因子(如果从图像空间变换到物理空间,就是 x 方向的像素单量)
Sy(输入参数):y 方向的缩放因子(如果从图像空间变换到物理空间,就是 y 方向的像素单量)
Phi(输出参数):旋转角度
Theta(输出参数):斜切角度
Tx(输出参数):沿 x 方向平移的距离
Ty(输出参数):沿 y 方向平移的距离

例如有:

复制代码
hom_mat2d_identity (HomMat2DIdentity)
hom_mat2d_translate (HomMat2DIdentity, 100, 100, HomMat2DTranslate)
hom_mat2d_scale (HomMat2DTranslate, 5, 5, 0, 0, HomMat2DScale)
hom_mat2d_rotate (HomMat2DScale, rad(90), 0, 0, HomMat2DRotate)
hom_mat2d_slant (HomMat2DRotate, rad(60), 'x', 0, 0, HomMat2DSlant)
hom_mat2d_to_affine_par (HomMat2DSlant, Sx, Sy, Phi, Theta, Tx, Ty)

(六) 对图像、region 和 XLD 进行仿射变换

1. 对 XLD 进行仿射变换

对 XLD 轮廓进行二维仿射变换,支持缩放、平移、旋转、斜切

复制代码
affine_trans_contour_xld(Contours :ContoursAffinTrans :HomMat2D :)

Contours(输入参数):输入 XLD 轮廓
ContoursAffinTrans(输出参数):输出变换的 XLD 轮廓
HomMat2D(输入参数):仿射变换矩阵

例如有:

复制代码
dev_clear_window ()
read_image (Image, 'printer_chip/printer_chip_01')

* 二值化
threshold (Image, Region, 128, 255)
connection (Region, ConnectedRegions)
select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 25000, 50000)
* 筛选左边第一个
select_obj (SelectedRegions, ObjectSelected, 4)
* 生成区域轮廓
gen_contour_region_xld (ObjectSelected, Contours, 'border')
* 将该区域移动到图像中心
area_center_xld (Contours, Area, Row, Column, PointOrder)
orientation_xld (Contours, Phi)
get_image_size (Image, Width, Height)
vector_angle_to_rigid (Row, Column, Phi, Width/2, Height/2, Phi, HomMat2D)
affine_trans_contour_xld (Contours, ContoursAffineTrans, HomMat2D)

2. 对图像 Image 进行仿射变换

对图形轮廓进行二维仿射变换,支持缩放、平移、旋转、斜切

复制代码
affine_trans_image(Image :ImageAffineTrans : HomMat2D,Interpolation,AdaptImageSize)

Image(输入参数):输入图像
ImageAffineTrans(输出参数):变换后的图像
HomMat2D(输入参数):仿射变换矩阵
Interpolation(输入参数):插值算法。参数值列表 nearest_neighbor, bilinear,constant,weighted
AdaptImageSize(输入参数):结果图像尺寸是否自适应。默认值:false

例如有:

复制代码
dev_clear_window ()
read_image (Image, 'printer_chip/printer_chip_01')
hom_mat2d_identity (HomMat2DIdentity)
hom_mat2d_translate (HomMat2DIdentity, 100, 100, HomMat2DTranslate)
affine_trans_image (Image, ImageAffineTrans, HomMat2DTranslate, 'constant', 'false')

3. 对 region 进行仿射变换

对区域进行任意二维仿射变换,主要用于处理上述第四点的第7小节((四)、7),将要处理的斜着的图片中部分区域(例如:斜着拍到一张汽车图,将汽车图内斜着的车牌照扶正)筛选出来并进行仿射变换,这时就要用到区域仿射变换。

复制代码
affine_trans_region(Region :RegionAffineTrans :HomMat2D, Interpolate)

Region(输入参数):输入区域
RegionAffineTrans(输出参数):变换的区域
HomMat2D(输入参数):仿射变换矩阵
Interpolate(输入参数):插值算法。默认值 nearest_neighbor, 参数值列表 constant, nearest_neighbor

例如有:

复制代码
dev_clear_window ()
read_image (Image, 'printer_chip/printer_chip_01')
hom_mat2d_identity (HomMat2DIdentity)
hom_mat2d_translate (HomMat2DIdentity, 100, 100, HomMat2DTranslate)
* 仿射变换区域
affine_trans_region (Image, RegionAffineTrans, HomMat2DTranslate, 'nearest_neighbor')
affine_trans_image (Image, ImageAffineTrans, HomMat2DTranslate, 'constant', 'false')

4. 对 polygon_xld 进行仿射变换

轮廓线的点获取:

复制代码
算子:get_region_contour(region, Rows, Columns)

功能:获取已知区域 region 的散点,保存在 Rows,Columns 内

获取线段区域:

复制代码
算子:get_region_line(regline, row1, col1, row2, col2)

功能:获取一条线段的区域,注意 regline 是个区域,不是像素列表,若要获取散列点如下:
get_region_line(RegionLines, 100, 50, 150, 250)
get_region_points(RegionLines, Rows, Columns)

获取区域的像素元组:

复制代码
算子:gen_region_points(regline, Rows, Columns)

功能:将个别的像素存储为图像区域

生成多边形:

复制代码
算子:gen_region_polygon

功能:将一个多边形存储为一个区域

生成多边形实心:

复制代码
算子:gen_region_polygon_filled(region, rows, cols)

功能:将一个多边形存储为一个已填充区域

从区域获取 xld :

复制代码
算子:gen_contour_region_xld(reg, Contours, 'border')

reg:输入区域
Contours:得到的 xld 对象

生成多边形区域:

复制代码
算子:gen_region_polygon_xld

功能:创建一个 XLD 多边形中的区域

对 XLD 多边形进行任意二维仿射变换,一般用于不是对图片而是对轮廓进行仿射变换时

复制代码
affine_trans_polygon_xld(Polygon :PolygonsAffineTrans :HomMat2D:)

Polygon(输入参数):输入 XLD 多边形
PolygonsAffineTrans(输出参数):变换的 XLD 多边形
HomMat2D(输入参数):仿射变换矩阵

例如有:

复制代码
dev_clear_window ()
row:=[100,50,50,100,300,300,300,100]
col:=[50,100,200,400,400,200,50,50]
* 空心多边形
*gen_region_polygon (PolygonRegion, row, col)
* 实心多边形
gen_region_polygon_filled (Region, row, col)
* 生成多边形轮廓
gen_contour_region_xld (Region, Contours, 'border')
area_center_xld (Contours, Area, Row, Column, PointOrder)
orientation_xld (Contours, Phi)
* 生成仿射变换矩阵
vector_angle_to_rigid (Phi, Phi, Phi, Phi, Phi, Phi, HomMat2D)
hom_mat2d_scale (HomMat2D, 0.5, 0.5, 0, 0, HomMat2DScale)
* 仿射变换多边形轮廓
affine_trans_contour_xld (Contours, ContoursAffineTrans, HomMat2DScale)

5. 对点进行仿射变换

对点进行任意二维仿射变换,支持缩放、平移、旋转、斜切

复制代码
affine_trans_point_2d(::HomMat2D, Px, Py :Qx, Qy)
    
HomMat2D(输入参数):仿射变换矩阵
Px(输入参数):原始点 x 或行坐标
Py(输入参数):原始点 y 或列坐标
Qx(输出参数):变换点 x 或行坐标
Qy(输出参数):变换点 y 或列坐标
相关推荐
蓝胖子不会敲代码4 小时前
跟着AI学习C# Day29
人工智能·学习·c#
老刘忙Giser4 小时前
C# Process.Start多个参数传递及各个参数之间的空格处理
java·前端·c#
CoderIsArt8 小时前
C# WPF常用调试工具汇总
开发语言·c#·wpf
gc_229910 小时前
C#测试调用ClosedXML根据批注设置excel单元格内容
c#·批注·closedxml
唐青枫12 小时前
C#.NET HttpClient 使用教程
c#·.net
夜空晚星灿烂13 小时前
C# 网络编程-关于HttpClient使用方式(三)
开发语言·网络·c#
甄天14 小时前
WPF Style样式 全局样式资源字典
c#·wpf
夜空晚星灿烂16 小时前
C# 网络编程-关于HttpWebRequest使用方式(二)
开发语言·c#
王中阳Go1 天前
北京京东,看看难度
c#·linq