对应示例程序:
apply_distance_transform_xld.hdev
目标: 比较算子distance_contours_xld 和算子 apply_distance_transform_xld的区别
一般情况下,在求解轮廓之间的距离时,distance_contours_xld都适用。但是对于参考XLD轮廓保持不变,被多次使用时,算子apply_distance_transform_xld可以缩短计算时间
思路为:
1.读入图像,并利用算子edges_sub_pix提取出亚像素边缘。
2.将原始图像进行算法弯曲,再利用算子edges_sub_pix得到弯曲后的亚像素边缘
3. 利用算子distance_contours_xld 计算两个轮廓之间的距离,并计时
4.利用算子create_distance_transform_xld 和pply_distance_transform_xld计算两个轮廓之间的距离,并计时
5.显示算子运行的时间
图像:
代码:
* Init visualization
dev_close_window ()
dev_open_window_fit_size (0, 0, 1280, 1024, -1, -1, WindowHandle)
set_display_font (WindowHandle, 16, 'mono', 'true', 'false')
*
* Show introduction
Message := 'This example shows the speed difference between the operators'
Message[1] := 'distance_contours_xld and apply_distance_transform_xld.'
Message[2] := 'Both operators measure the pointwise distance between'
Message[3] := 'two contours.'
Message[4] := ' '
Message[5] := 'While distance_contours_xld can always be used,'
Message[6] := 'apply_distance_transform_xld is used if one of the contours'
Message[7] := 'is reused many times as an unchanging reference contour.'
Message[10] := 'In that case some time-consuming calculations can be done'
Message[11] := 'offline in advance so that apply_distance_transform_xld is'
Message[12] := 'much faster.'
disp_message (WindowHandle, Message, 'window', 12, 12, 'white', 'false')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
*
* Choose one of two modes.
* 'point_to_point' is faster,
* 'point_to_segment' is more accurate.
Mode := 'point_to_point'
* Mode := 'point_to_segment'
Tolerance := 7
Loops := 4
Legend := ['Legend:','- template contour','- random test contour within tolerance','- random test contour outside of tolerance']
*
* PART I: distance_contours_xld
*
* distance_contours_xld calculates
* the pointwise distance between two contours
*
for I := 1 to Loops by 1
* Generate the two contours to be compared 生成测试轮廓
gen_test_contours (EdgeOriginal, EdgeWarped)
* Calculate pointwise distance.
* The distances from points of the first to the points of the second contour
* are stored in the 'distance' attribute of the output contour.
* Parts of the contour can be easily segmented based on the attributes.
count_seconds (S1)
distance_contours_xld (EdgeWarped, EdgeOriginal, EdgeWarpedWithDistances, Mode) //计算从一个轮廓到另一个轮廓的点距离。
count_seconds (S2)
get_contour_attrib_xld (EdgeWarpedWithDistances, 'distance', Distance) //返回XLD轮廓的相关属性值
//根据参数条件,分离XLD轮廓
segment_contour_attrib_xld (EdgeWarpedWithDistances, ContourPart, 'distance', 'and', Tolerance, 99999)
*
display_result (EdgeOriginal, EdgeWarped, ContourPart) //显示
Message := 'Part 1: Calculate distances with distance_contours_xld'
Message[1] := 'Execution time: ' + ((S2 - S1) * 1000)$'.2f' + ' ms'
disp_message (WindowHandle, Message, 'window', 12, 12, 'black', 'true')
disp_message (WindowHandle, Legend, 'image', 800, 12, ['grey','white','green','red'], 'false')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
endfor
*
* PART II: apply_distance_transform_xld
*
* apply_distance_transform_xld is used to calculate the
* pointwise distance to changing contours to a not
* changing reference contour.
* To accelerate the calculation, some information is
* pre-calculated and stored in a distance transform handle.
*
dev_clear_window ()
disp_message (WindowHandle, 'Please wait while pre-calculating distance transform...', 'window', 42, 12, 'white', 'false')
*
* Pre-calculate distance transform for the template contour
* (this may take a while, depending on the size of the contour
* and MaxDistance)
* The parameter MaxDistance is used to restrict the pre-calculated
* distance transform to the specified value. Distances larger than
* MaxDistance will not be calculated. Instead, the distances are
* clipped.
MaxDistance := 8
create_distance_transform_xld (EdgeOriginal, Mode, MaxDistance, DistanceTransformID) //建参考轮廓Contour 的XLD距离转换,并在DistanceTransformID中返回结果句柄。
for I := 1 to Loops by 1
gen_test_contours (NotUsedOriginal, TestContour)
count_seconds (S1)
apply_distance_transform_xld (TestContour, TestContourOut, DistanceTransformID) //使用XLD距离变换确定两个轮廓的点距离
count_seconds (S2)
* Note, that the calculated distances are clipped at MaxDistance
get_contour_attrib_xld (TestContourOut, 'distance', DistanceClipped) //返回XLD轮廓的相关属性值
segment_contour_attrib_xld (TestContourOut, ContourPart, 'distance', 'and', Tolerance, MaxDistance) //根据参数分离XLD轮廓
*
display_result (EdgeOriginal, TestContour, ContourPart) //显示结果
Message := 'Part 2: Calculate distances with apply_distance_transform_xld'
Message[1] := 'Execution time: ' + ((S2 - S1) * 1000)$'.2f' + ' ms'
disp_message (WindowHandle, Message, 'window', 12, 12, 'black', 'true')
disp_message (WindowHandle, Legend, 'image', 800, 12, ['grey','white','green','red'], 'false')
if (I < Loops)
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
endif
dump_window (WindowHandle, 'jpg', 'C:/Users/Bryce/Desktop/新建位图图像')
endfor
stop ()
clear_distance_transform_xld (DistanceTransformID) //释放句柄
用到的几个算子:
real_to_vector_field --将两幅实值图像转换成矢量场图像。
unwarp_image_vector_field-- 用矢量场解压图像
add_noise_white–向图像添加噪声
distance_contours_xld --计算从一个轮廓到另一个轮廓的点距离。
create_distance_transform_xld --建参考轮廓Contour 的XLD距离转换,并在DistanceTransformID中返回结果句柄。
apply_distance_transform_xld --使用XLD距离变换确定两个轮廓的点距离
get_contour_attrib_xld --返回XLD轮廓的相关属性值
segment_contour_attrib_xld --根据参数分离XLD轮廓
clear_distance_transform_xld --释放XLD距离变换句柄
参考资料:
[1]:https://www.gkbc8.com/forum.php?mod=viewthread&ordertype=1&tid=13765