HALCON学习之旅(三)
1、创建自适应图形窗口
原因
:默认的图形窗口尺寸为512*512。当图像变量尺寸与图形窗口尺寸不一致时,展示的效果总是不如人意。
方法1:手动调整自适应窗口💪
方法2:代码调整自适应窗口(强烈推荐)😍
*创建自适应图像窗口的两种方式
*读取图像
*参数1 图像变量
*参数2 图像所在路径
read_image (Image1, 'C:/Users/Administrator/Desktop/1.jpg')
*打开图像窗口
dev_open_window (0, 0, 512, 512, 'black', WindowHandle)
*获取图像大小
get_image_size (Image1, Width, Height)
*打开具有给定最小和最大范围的新图形窗口,以便保留给定图像的纵横比
*WidthLimit设置为-1,则使用以下默认值:[500,800]
*HeightLimit设置为-1,则使用以下默认值:[400,600]
*如果根据窗口宽高限制无法创建窗口,则忽略最小窗口大小的限制
dev_open_window_fit_image (Image1, 0, 0, -1, -1, WindowHandle1)
*指定活动窗口ID
dev_set_window (WindowHandle1)
*展示图像变量
dev_display(Image1)
*打开具有给定最小和最大范围的新图形窗口,以便保留给定图像大小的宽高比
*WidthLimit设置为-1,则使用以下默认值:[500,800]
*HeightLimit设置为-1,则使用以下默认值:[400,600]
*如果根据窗口宽高限制无法创建窗口,则忽略最小窗口大小的限制
dev_open_window_fit_size (0, 0, Width, Height, -1, -1, WindowHandle2)
*指定活动窗口ID
dev_set_window (WindowHandle2)
*展示图像变量
dev_display(Image1)
效果展示
在此,分享一个读取本地图像的小诀窍:🍌
图示如下:
2、霍夫变换寻找图像直线
*读取一张图像
read_image (Image, 'C:/Users/Administrator/Desktop/矩形.png')
*获取图像的宽高
get_image_size (Image, Width, Height)
*打开图形窗口
dev_open_window_fit_image (Image, 0, 0, -1, -1, WindowHandle)
上述算子接口说明注释,可参考之上的案列。(往后的算子接口详解,除没有接触过得,只对复杂一点的算子进行说明)。🏄
*裁剪指定矩形的图像
*参数1 原始图像
*参数2 裁剪之后的图像
*参数3 左上角y
*参数4 左上角x
*参数5 右下角y
*参数6 右下角x
rectangle1_domain(Image, ImageReduced, 76, 120.938, 464.875, 966.813)
*寻找图像中矩形的边缘
*参数1 裁剪之后的图像
*参数2 边缘检测之后的图像
*参数3 滤波器方式
*参数4 滤波器大小
sobel_amp (ImageReduced, EdgeAmplitude, 'thin_sum_abs', 3)
rectangle1_domain接口的作用是裁剪图像,获取想要的矩形区域。主要注意一下后面四个参数顺序,不要搞混。
sobel_amp接口的作用是边缘检测,跟Opencv中的cv::Sobel()函数功能类似,着重讲解一下该接口的计算流程。
使用的卷积核基于以下过滤器掩码:
- | 1 | 2 | 1 | …… | - | 1 | 0 | -1 |
---|---|---|---|---|---|---|---|---|
A | 0 | 0 | 0 | B | 2 | 0 | -2 | |
- | -1 | -2 | -1 | …… | - | 1 | 0 | -1 |
流程1:
用A、B卷积核分别对图像进行卷积运算提取纵向特征图a和横向特征图b。
流程2:
对a、b两张图进行合并。合并的方式:
sum_sqrt :
d s t = a 2 + b 2 / 4. dst= \sqrt{a^2 + b^2} / 4. dst=a2+b2/4.
sum_abs :
d s t = ( ∣ a ∣ + ∣ b ∣ ) / 4. dst= (|a| + |b|) / 4. dst=(∣a∣+∣b∣)/4.
thin_sum_abs :
d s t = ( t h i n ( ∣ a ∣ ) + t h i n ( ∣ b ∣ ) ) / 4. dst= (thin(|a|) + thin(|b|)) / 4. dst=(thin(∣a∣)+thin(∣b∣))/4.
thin_sum_abs :
d s t = m a x ( t h i n ( ∣ a ∣ ) , t h i n ( ∣ b ∣ ) ) / 4. dst= max(thin(|a|) , thin(|b|)) / 4. dst=max(thin(∣a∣),thin(∣b∣))/4.
x :
d s t = b / 4. dst= b / 4. dst=b/4.
y :
d s t = a / 4. dst= a / 4. dst=a/4.
其他详解sobel_amp接口,可参考该博客。
若想了解更多边缘检测算子的,可参考毛星云的这篇博客(Opencv)。干货多多🏄
*设置活动图形窗口输出颜色
dev_set_color('red')
*对上面获取的边缘图像进行阈值操作
*参数1 边缘检测之后的图像
*参数2 阈值分割之后的图像
*参数3 分割阈值
*参数4 分割阈值后的像素值
threshold (EdgeAmplitude, Region, 10, 255)
*对阈值后的区域进行连通处理
*参数1 阈值分割之后的图像
*参数2 连通图像
connection (Region, ConnectedRegions)
*根据面积过滤出图像中的外接矩
*参数1 连通图像
*参数2 外矩形区域图像
*参数3 参数特征选择
*参数4 特征关系符('and', 'or') 只有在多个特征条件下才有用
*参数5 输入参数下限值
*参数6 输入参数上限值
select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 2500, 99999)
threshold接口的作用是全局阈值分割,也相当于Opencv中的二值化操作。可通过灰度直方图菜单快速获取指定阈值。
灰度直方图菜单使用流程:
1、先选中需要进行阈值分割的图像变量🌑
2、点击灰度直方图🌓
3、调整灰度直方图参数,获取指定阈值🌕
connection接口的作用是获取连通区域,相当于Opencv中的cv::findcontours()接口。
select_shape接口的作用是对连通区域进行特征查询,将满足特征的连通区域保留。
其中(Region)特征类别有如下几种:
特征 | 代表 |
---|---|
area | 对象的面积 |
row | 中心点的行坐标 |
width | 区域的宽度 |
height | 区域的高度 |
row1 | 左上角行坐标 |
column1 | 左上角列坐标 |
row2 | 右下角行坐标 |
column2 | 右下角列坐标 |
circularity | 圆度 |
compactness | 紧密度 |
contlength | 轮廓线总长 |
convexity | 凸性 |
rectangularity | 矩形度 |
ra | 等效椭圆长轴半径长度 |
rb | 等效椭圆短轴半径长度 |
phi | 等效椭圆方向 |
anisometry | 椭圆参数,Ra/Rb长轴与短轴的比值 |
bulkiness | 椭圆参数,蓬松度πRaRb/A |
struct_factor | 椭圆参数,Anisometry*Bulkiness-1 |
outer_radius | 最小外接圆半径 |
inner_radius | 最大内接圆半径 |
inner_width | 最大内接矩形宽度 |
inner_height | 最大内接矩形高度 |
dist_mean | 区域边界到中心的平均距离 |
dist_deviation | 区域边界到中心距离的偏差 |
roundness | 圆度,与circularity计算方法不同 |
num_sides | 多边形边数 |
connect_num | 连通数 |
holes_num | 区域内洞数 |
area_holes | 所有洞的面积 |
max_diameter | 最大直径 |
orientation | 区域方向 |
euler_number | 欧拉数,即连通数和洞数的差 |
rect2_phi | 最小外接矩形的方向 |
rect2_len1 | 最小外接矩形长度的一半?? |
rect2_len2 | 最小外接矩形宽度的一半 |
moments_m11 | 几何矩 |
moments_xxx | 几何矩 |
其他更多有关Region特征类别的,可参考该博客:https://blog.csdn.net/huachizi/article/details/88016415
特征直方图菜单可快速获取Region特征
参数。
流程1、先选中需要进行特征选择的图像变量🌑
流程2、点击特征直方图(跟灰度直方图路径一致)🌓
流程3、调整特征直方图参数,获取指定阈值🌕
*霍夫变换寻找区域中的直线
*参数1 外矩形区域图像
*参数2 角度迭代步长
*参数3 霍夫图像的像素点累加阈值
*参数4 霍夫图像中两个最大值的最小距离(角度) 默认值为5
*参数5 霍夫图像中两个最大值的最小距离(距离) 默认值为5
*参数6 检测到的线的法向量的角度
*参数7 检测到的线与原点的距离
hough_lines(SelectedRegions, 4, 50, 5, 5, Angle, Dist)
*设置输出对象的颜色
dev_set_color('blue')
*将直线转换到图像区域
*参数1 直线绘制图像
*参数2 直线的角度
*参数3 直线到原点的距离
gen_region_hline(Regions, Angle, Dist)
*根据方向特征来过滤想要的直线
select_shape (Regions, SelectedRegions1, 'orientation', 'and', 1.5, 1.6)
select_shape (Regions, SelectedRegions2, 'orientation', 'and', 0, 0.1)
*显示图像和结果直线
dev_display (Image)
dev_display (SelectedRegions1)
dev_display (SelectedRegions2)
hough_lines接口的作用是检测特征区域内的直线。若要了解每个参数的实际作用,须知霍夫直线原理。
具体原理流程如下:😎
1、对于直角坐标系中的任意一点A(x,y),经过点A的直线满足y = kx + b。(k是斜率,b是截距)
2、那么在X-Y平面过点A(x,y)的直线簇可以用y = kx + b表示,但对于垂直与X轴的之间斜率是无穷大的则无法表示。因此将直角坐标系转换到极坐标系解决该特殊情况。
在此,对不了解极坐标系的
,我补充一下,大佬可以跳过往下看哦😸😸😸
极坐标系:在平面上取一个定点O,叫做极点,引一条射线Ox,叫做极轴,在选定一个长度单位和角度的正方向(通常取逆时针方向)。对于平面内任何一点M,用ρ表示线段OM的长度,θ表示从Ox到OM的角度,ρ叫做点M的极径,θ叫做点M的极角,有序数对 (ρ,θ)就叫点M的极坐标,如图所示。
3、在极坐标系中表示直线的方程为ρ= xCosθ + ysinθ(ρ为原点到直线的距离),如图所示。
4、假定在一个88的平面像素中有一条直线,并且从左上角(1,8)像素点开始分别计算θ为0°、45°、90°、135°、180°时的ρ,图中可以看出ρ分别为1、(9√2)/2、8、(7√2)/2、-1,并给这5个值分别记一票,同理计算像素点(3,6)点θ为0°、45°、90°、135°、180°时的ρ,再给计算出来的5个ρ值分别记一票,此时就会发现ρ = (9√2)/2的这个值已经记了两票了,以此类推,遍历完整个88的像素空间的时候ρ = (9√2)/2就记了5票, 别的ρ值的票数均小于5票,所以得到该直线在这个88的像素坐标中的极坐标方程为 (9√2)/2=xCos45°+y*Sin45°,到此该直线方程就求出来了,但实际中θ的取值不会跨度这么大,一般是PI/180。
5、由上述结论可知在同一条直线上的点具有相同的极坐标(ρ,θ),而该极坐标对应的该直线的极径和极角。因此,若对于一个给定点(x,y),我们在极坐标对极径极角平面绘出所有通过它的直线,将得到一条正弦曲线. 例如, 对于给定点 x = 8,y= 6 我们可以绘出下图 (在平面 θ - r),
6、另外再对与该点所处同一个直线上的两个点,分别在极坐标对极径极角平面绘出所有通过它的直线,若它们所在的曲线平面 θ - r相交与一点,则说明同一条直线上的点具有相同的极径和极角。如下图,对 x1 = 4, y2 = 9 和点 x2 = 12, y2 = 3 绘图,发现这三个曲线在 θ - r平面相交与点(0.925,9.6)。
这也说明,一条直线的点数能通过在平面θ - r相交与一点的曲线数量来统计. 越多曲线交于一点也就意味着这个交点表示的直线由更多的点组成。
7、由上我们可以通过设置直线上点的阈值来定义多少条曲线交于一点我们才认为检测到了一条直线.。这就是霍夫线变换要筛选的,它追踪图像中每个点对应曲线间的交点,如果交于一点的曲线的数量超过了阈值,那么可以认为这个交点所代表的参数对 (θ,ρ) 在原图像中为一条直线。
huogh直线原理讲解参考该博客:https://www.cnblogs.com/fcfc940503/p/11305092.html。若想了解更多,可以进入该博客进行学习。👍
霍夫直线的原理了解清楚后,分析参数:
参数1:进行直线检测的边缘二值图;
参数2:角度迭代步长。这里相当于(θ-r坐标系)θ的刻度单位。
参数3:交于一点(θ-r平面)曲线个数,即直线检测的点位数个数筛选阈值;
参数4:找到的两个相邻的极值坐标角度差值不能小于指定值,默认值5;
参数5:找到的两个相邻的极值坐标距离不能小于指定值,默认值5;
参数6:检测到线的极角(弧度单位);
参数7:检测到线的极径。
gen_region_hline接口的作用是将找到的直线绘制到指定图像变量上。
最后,特征筛选,根据角度方向特征筛选出正确的线条。筛选参数的获取依照上面的特征直方图菜单教程实现即可。
效果展示