隶属于:
C:\Users\Public\Documents\MVTec\HALCON-23.05-Progress\examples\hdevelop\Applications\Completeness-Check
此程序主要使用了measure_projection 来测量鱼柳边界,以及用50作为判断参数来确认边界,并显示后进行宽度宽度,宽度大于20的作为鱼的个数,大于48的则认为NG。使用了轮廓线思想。以及有将数组转化为函数来查找边缘。此法可借鉴找多个边缘使用。
算子:measure_projection
measure_projection 用于从图像中提取与矩形或环形弧线垂直的一维灰度值轮廓。这是通过在与矩形或弧线主轴垂直的“切片”中对灰度值进行平均计算来实现的。采样是在图像的亚像素位置上进行的,这些位置在矩形的坐标系中以整数行和列的距离从矩形的中心向外延伸。由于这些计算可以重复用于多个投影,因此使用 gen_measure_rectangle2 算子来一次性完成这些计算,从而显著提高 measure_projection 的运行速度。由于在灰度值的亚像素计算中存在精度与速度之间的权衡,因此可以在 gen_measure_rectangle2 中选择不同的插值方案(插值仅影响与图像轴不平行的矩形)。通过 gen_measure_rectangle2 生成的测量对象通过 measure_handle 传递给 measure_projection。
关于一维测量的概念,请参阅第1章“一维测量”的介绍。
注意:出于效率原因,measure_projection 会忽略图像的域。如果需要从测量中排除图像中的某些区域,应生成一个新的测量对象,并适当修改其参数。
- 该程序通过计算每个包装中所包含的鱼柳数量来执行完整性检查。
- 在这里,使用一维测量工具来确定相邻鱼柳之间的边界
初始化显示窗口,读入图之类的
直接使用轮廓线如下所示
程序中如下:以及此处的起始位置为矩形开始的位置是0,直到整个矩形的长度,就是274*2=548;也就是grayvalues的横坐标。
将数组转化为一个函数
计算函数的最大最小值,并将最小值反转镜像。
选出小于50灰度阶跃的的作为边位置。
找到边界之后,计算并显示边界和中心位置
总体显示
* 该程序通过计算每个包装中所包含的鱼柳数量来执行完整性检查。
* 在这里,使用一维测量工具来确定相邻鱼柳之间的边界
dev_update_off ()
dev_close_window ()
read_image (Image, 'food/fish_stick_package_01')
get_image_size (Image, Width, Height)
dev_open_window (0, 0, Width * .7, Height * .7, 'black', WindowHandle)
set_display_font (WindowHandle, 16, 'mono', 'true', 'false')
dev_set_draw ('margin')
dev_open_window (0, Width * .9 + 12, 420, 150, 'black', GraphicsWindow)
set_display_font (GraphicsWindow, 16, 'mono', 'true', 'false')
dev_set_color ('yellow')
*
* Read and process the images
NumImages := 6
for Index := 1 to NumImages by 1
read_image (Image, 'food/fish_stick_package_' + Index$'02')
*
* Segment the content of the fish stick package
threshold (Image, Region, 100, 255)
closing_circle (Region, RegionClosing, 5)
fill_up (RegionClosing, RegionFillUp)
difference (RegionFillUp, RegionClosing, RegionDifference)
fill_up (RegionDifference, RegionFillUp1)
closing_circle (RegionFillUp1, RegionClosing1, 10)
smallest_rectangle2 (RegionClosing1, Row, Column, Phi, Length1, Length2)
MeasureLength1 := Length1 - 5
* 测量鱼柳包装的灰度值轮廓。
* Measure the gray value profile of the fish stick package
gen_rectangle2 (Rectangle, Row, Column, Phi, Length1, 80)
gen_measure_rectangle2 (Row, Column, Phi, MeasureLength1, 60, Width, Height, \
'nearest_neighbor', MeasureHandle)
measure_projection (Image, MeasureHandle, GrayValues)
create_funct_1d_array (GrayValues, Function)
local_min_max_funct_1d (Function, 'plateaus_center', 'true', Minima, Maxima)
*
* Evaluate the gray profile评估灰度轮廓。
get_y_value_funct_1d (Function, Minima, 'mirror', YValues)
a:=YValues - 50
b:=sgn(YValues - 50)
c:=find(sgn(YValues - 50),-1)
SelectedMinima := subset(Minima,find(sgn(YValues - 50),-1))
Num := |SelectedMinima| + 1
StickEdges := [-5,SelectedMinima,2 * MeasureLength1 + 5]
StickWidth := StickEdges[1:Num] - StickEdges[0:Num - 1]
*
* Display the results
BorderX := Column + cos(Phi) * (MeasureLength1 * ((StickEdges - MeasureLength1) / MeasureLength1))
BorderY := Row - sin(Phi) * (MeasureLength1 * ((StickEdges - MeasureLength1) / MeasureLength1))
CenterX := (BorderX[1:Num] + BorderX[0:Num - 1]) / 2
CenterY := (BorderY[1:Num] + BorderY[0:Num - 1]) / 2
gen_cross_contour_xld (BorderCross, BorderY, BorderX, 15, rad(45))
gen_cross_contour_xld (CenterCross, CenterY, CenterX, 15, rad(45))
IndexFish := find(sgn(StickWidth - 20),1)
if (IndexFish != -1)
NumFish := |IndexFish|
gen_rectangle2 (FishRegions, subset(CenterY,IndexFish), subset(CenterX,IndexFish),\
gen_tuple_const(NumFish,Phi), subset(StickWidth,IndexFish) / 2, \
gen_tuple_const(NumFish,Length2) / 2)
else
NumFish := 0
endif
gen_empty_region (Flipped)
IndexFlipped := find(sgn(StickWidth - 48),1)
if (IndexFlipped != -1)
NumFlipped := |IndexFlipped|
gen_rectangle2 (Flipped, subset(CenterY,IndexFlipped), subset(CenterX,IndexFlipped), \
gen_tuple_const(NumFlipped,Phi), subset(StickWidth,IndexFlipped) / 2,\
gen_tuple_const(NumFlipped,Length2) / 2)
else
NumFlipped := 0
endif
*
dev_set_window (GraphicsWindow)
dev_clear_window ()
plot_funct_1d (GraphicsWindow, Function, [], [], 'yellow', 'axes_color', 'none')
disp_message (GraphicsWindow, 'Gray Profile', 'window', 12, 12, 'white', 'false')
dev_set_window (WindowHandle)
dev_clear_window ()
dev_display (Image)
dev_set_color ('yellow')
dev_set_line_width (1)
dev_display (FishRegions)
dev_display (BorderCross)
dev_set_color ('red')
dev_set_line_width (3)
dev_display (Flipped)
if (NumFish == 15 and NumFlipped == 0)
String := 'OK'
Color := 'green'
else
String := 'Not OK'
Color := 'red'
endif
String[1] := 'Number of fish sticks:' + NumFish$'3'
if (NumFish != 15)
Color := [Color,'red']
else
Color := [Color,'white']
endif
if (NumFlipped != 0)
String[2] := 'Flipped fishsticks: ' + NumFlipped$'3'
Color := [Color,'red']
endif
disp_message (WindowHandle, String, 'window', 12, 12, Color, 'false')
dev_set_color (Color[0])
dev_display (Rectangle)
if (Index < NumImages)
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
endif
endfor