本例程来做halcon10.0版本中的一维函数中check_smd_tilt.hdev例程,通过此例程可以学习到如何使用halcon中算子measure_projection通过投影图像上垂直于剖面线方向的灰度值来提取1D灰度剖面,如下是对此算子的详细理解:

更多关于测量的算子理解,可以参考北京大恒宣讲的PPT halcon测量技术。
下面例程是检测SMDS是否与近水平或者相对相机是否倾斜。分析图像发现相机的景深很小,因此倾斜的拍摄的图像是模糊的。
因此才程序采用了首先对图像进行分割,然后计算边缘的振幅(灰度值的一阶导数)。发现边缘模糊的区域是弱振幅,因此倾斜的SMDS可以通过边缘的振幅来进行检测。
本例程主要学习shape_trans ,gen_measure_rectangle2 ,measure_projection ,tuple_gen_sequence ,create_funct_1d_pairs ,plot_funct_1d ,gen_arrow_contour_xld等算子的使用。
例程代码:
dev_update_off ()
dev_close_window ()
dev_open_window (0, 0, 640*.7, 512*.7, 'black', WindowHandle)
dev_set_draw ('margin')
dev_set_line_width (3)
dev_open_window (0, 640*.7+12, 640*.7, 512*.7, 'black', GrayProfileWindow)
set_display_font (WindowHandle, 16, 'mono', 'true', 'false')
set_display_font (GrayProfileWindow, 16, 'mono', 'true', 'false')
*
NumImages := 10
for Index := 1 to NumImages by 1
read_image (Image, 'smd/smd_tilted_'+Index$'02')
*
* Segment the SMD 提取SMD 通过阈值分割,根据面积选取形状 最后裁剪出SMD
var_threshold (Image, Region, 20, 20, 0.1, 2, 'dark')
connection (Region, ConnectedRegions)
select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 15000, 99999999)
shape_trans (SelectedRegions, RegionTrans, 'convex')
reduce_domain (Image, RegionTrans, ImageReduced)
*
* Check if the SMD is tilted
*边缘提取
sobel_amp (ImageReduced, EdgeAmplitude, 'sum_abs', 3)
*求最小外接矩形,并获得与水平偏转角度 同事获得矩形的长半轴和短半轴
smallest_rectangle2 (RegionTrans, Row, Column, Phi, Length1, Length2)
*产生矩形框
gen_rectangle2 (Rectangle, Row, Column, Phi, Length1-3, 20)
*产生测量矩形框
gen_measure_rectangle2 (Row, Column, Phi, Length1-3, 20, 640, 512, 'nearest_neighbor', MeasureHandle)
*测量剖面线投影的灰度值
measure_projection (EdgeAmplitude, MeasureHandle, GrayValues)
close_measure (MeasureHandle)
*产生离散序列点
tuple_gen_sequence (1, |GrayValues|, 1, Sequence)
*创建一维函数
create_funct_1d_pairs (Sequence, GrayValues, Function)
gen_arrow_contour_xld (Arrow, [Row,Row], [Column,Column], [Row-Length1*sin(Phi),Row+Length1*sin(Phi)], [Column+Length1*cos(Phi),Column-Length1*cos(Phi)], 25, 25)
*
* Evaluate the edge amplitude of the SMD profile
*计算左右两边的投影灰度值的分布情况
Length := |GrayValues|
PartLeft := GrayValues[0:Length/2]
PartRight := GrayValues[Length/2:Length-1]
RangeLeft := max(PartLeft)-min(PartLeft)
RangeRight := max(PartRight)-min(PartRight)
TiltRatio := RangeLeft/RangeRight
*根据分布情况,判断是否拍摄有问题
if (TiltRatio>3 or TiltRatio<1.0/3)
color := 'red'
String := 'Not OK:\nSMD is tilted'
else
color := 'green'
String := 'OK:\nSMD is aligned'
endif
*
* Display the results
dev_set_window (WindowHandle)
dev_display (Image)
dev_set_color (color)
dev_display (Arrow)
dev_display (RegionTrans)
disp_message (WindowHandle, String, 'window', 12, 12, 'black', 'true')
dev_set_window (GrayProfileWindow)
dev_clear_window ()
dev_set_color (color)
*绘制一维函数图象
plot_funct_1d (GrayProfileWindow, Function)
disp_message (GrayProfileWindow, ['Edge amplitude','Tilt ratio = ' + TiltRatio$'3.2f'], 'window', 12, 12, 'white', 'false')
if (Index#NumImages)
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
endif
endfor图像清晰的振幅图像:

图像边缘模糊的振幅图像:

---------------------
作者:不系之舟913
来源:CSDN
原文:https://blog.csdn.net/lixianjun913/article/details/11727797
版权声明:本文为博主原创文章,转载请附上博文链接!


少有人走的路


















