例程功能
检查IC的引线宽度和引线距离。
代码如下
dev_close_window ()
read_image (Image, 'board/board-06')
get_image_size (Image, Width, Height)
dev_open_window (0, 0, Width, Height, 'black', WindowHandle)
*
* --- Fuzzy Measure:
Row1 := 305.5
Col1 := 375.5
Phi1 := 0.982
Length1 := 167
Length2 := 8
gen_measure_rectangle2 (Row1, Col1, Phi1, Length1, Length2, Width, Height, 'nearest_neighbor', MeasureHandle1)
Row2 := 188.5
Col2 := 202.5
Phi2 := Phi1 - rad(180)
gen_measure_rectangle2 (Row2, Col2, Phi2, Length1, Length2, Width, Height, 'nearest_neighbor', MeasureHandle2)
* Create a fuzzy member function to select edge pairs of size of the chip pins (about 11 Pixels)
create_funct_1d_pairs ([0.0, 0.3], [1.0, 0.0], FuzzyAbsSizeDiffFunction)
set_fuzzy_measure_norm_pair (MeasureHandle1, 11.0, 'size_abs_diff', FuzzyAbsSizeDiffFunction)
set_fuzzy_measure_norm_pair (MeasureHandle2, 11.0, 'size_abs_diff', FuzzyAbsSizeDiffFunction)
fuzzy_measure_pairs (Image, MeasureHandle1, 1, 30, 0.5, 'positive', RowEdgeFirst1, ColumnEdgeFirst1, AmplitudeFirst1, RowEdgeSecond1, ColumnEdgeSecond1, AmplitudeSecond1, RowEdgeMiddle1, ColumnEdgeMiddle1, FuzzyScore1, IntraDistance1, InterDistance1)
fuzzy_measure_pairs (Image, MeasureHandle2, 1, 30, 0.5, 'positive', RowEdgeFirst2, ColumnEdgeFirst2, AmplitudeFirst2, RowEdgeSecond2, ColumnEdgeSecond2, AmplitudeSecond2, RowEdgeMiddle2, ColumnEdgeMiddle2, FuzzyScore2, IntraDistance2, InterDistance2)
*
* --- Visualization:
dev_display (Image)
* Measuring area
dev_display_measure_object (Row1, Col1, Phi1, Length1, Length2)
dev_display_measure_object (Row2, Col2, Phi2, Length1, Length2)
* Edge pairs
dev_set_draw ('fill')
Pin := 1
dev_display_profile_points ([RowEdgeFirst1,RowEdgeSecond1], [ColumnEdgeFirst1,ColumnEdgeSecond1], Row1, Col1, Phi1, Length1, Length2)
for I := 0 to |ColumnEdgeFirst1| - 1 by 1
disp_message (WindowHandle, 'size:' + IntraDistance1[I]$'.2f' + ' score:' + FuzzyScore1[I]$'.2f', 'image', RowEdgeSecond1[I], ColumnEdgeSecond1[I] + 10, 'yellow', 'false')
MRow := RowEdgeSecond1[I] - 5
MCol := ColumnEdgeSecond1[I] - 20
dev_set_color ('white')
gen_circle (Circle, MRow, MCol, 10)
dev_display (Circle)
get_string_extents (WindowHandle, Pin, Ascent, Descent, SWidth, SHeight)
disp_message (WindowHandle, Pin, 'window', MRow - SHeight / 2, MCol - SWidth / 2, 'black', 'false')
Pin := Pin + 1
endfor
dev_display_profile_points ([RowEdgeFirst2,RowEdgeSecond2], [ColumnEdgeFirst2,ColumnEdgeSecond2], Row2, Col2, Phi2, Length1, Length2)
for I := 0 to |ColumnEdgeFirst2| - 1 by 1
dev_set_color ('yellow')
disp_message (WindowHandle, 'size:' + IntraDistance2[I]$'.2f' + ' score:' + FuzzyScore2[I]$'.2f', 'image', RowEdgeFirst2[I], ColumnEdgeFirst2[I] + 10, 'yellow', 'false')
MRow := RowEdgeFirst2[I] - 5
MCol := ColumnEdgeFirst2[I] - 20
dev_set_color ('white')
gen_circle (Circle, MRow, MCol, 10)
dev_display (Circle)
get_string_extents (WindowHandle, Pin, Ascent, Descent, SWidth, SHeight)
disp_message (WindowHandle, Pin, 'window', MRow - SHeight / 2, MCol - SWidth / 2, 'black', 'false')
Pin := Pin + 1
endfor
要点
- 模糊测量——对标准测量的一种扩展,并不意味着测量是“模糊的”,而是用模糊隶属函数来控制边缘的选择。所谓的模糊隶属函数,就是将边缘的特征值转换为隶属度值(我理解为权重值),基于这些隶属值做出是否选择边缘的决定,即当隶属值大于你设定模糊阈值时,边缘就会被选中,反之则同理。这种方法的优点是即使使用很低的最小阈值或平滑,也能灵活处理额外的边缘;
直接用一维测量会产生错误的结果,这时将“引线的宽度的大约为9
像素宽度”这个信息转换为模糊隶属函数。即预期的宽度9
像素,对应的隶属值为1
;对于与预期的大小相差3
个像素(6
/9
)以上,则隶属值为0
,中间的值采用线性插值,即宽度大于8
像素的隶属值为0.67
;当你设置的阈值为0.5
时,那宽度为7.5~10.5
像素之间的像素边缘对才会被选中。通过这样的模糊测量则可以正确测量引线的宽度;
gen_measure_rectangle2(Row1, Col1, Phi1, Length1, Length2, Width, Height, 'nearest_neighbor', MeasureHandle1)
create_funct_1d_pairs([0.0, 0.3], [1.0, 0.0], FuzzyAbsSizeDiffFunction)
set_fuzzy_measure_norm_pair(MeasureHandle1, 11.0, 'size_abs_diff', FuzzyAbsSizeDiffFunction)
fuzzy_measure_pairs (Image, MeasureHandle1, 1, 30, 0.5, 'positive', RowEdgeFirst1, ColumnEdgeFirst1, AmplitudeFirst1, RowEdgeSecond1, ColumnEdgeSecond1, AmplitudeSecond1, RowEdgeMiddle1, ColumnEdgeMiddle1, FuzzyScore1, IntraDistance1, InterDistance1)
create_funct_1d_pairs
——从参数对中创建一个函数创建模糊函数;
XValues
:入参,函数点的x
值;
YValues
:入参,函数点的y
值;
Function
:出参,返回的函数;
set_fuzzy_measure_norm_pair
——为边对指定模糊函数(就上面创建的那个);
MeasureHandle
:入参,测量句柄;
PairSize
:入参,指定边对内部的宽度(猜的,也许是边对与边对间的宽度);
SetType
:入参,模糊集的选择方式;
Function
:入参,模糊函数;
fuzzy_measure_pairs
——进行模糊测量操作;
Image
:入参,测量句柄;
MeasureHandle
:入参,测量句柄;
Sigma
:入参,高斯模糊参数;
AmpThresh
:入参,最小边沿振幅;
FuzzyThresh
:入参,最小模糊值;
Transition
:入参,边对灰度值过渡的标准;
RowEdgeFirst
:出参,第一个边点的行值(纵坐标);
ColumnEdgeFirst
:出参,第一个边点的列值(横坐标);
AmplitudeFirst
:出参,第一条边的边缘振幅(带符号);
RowEdgeSecond
:出参,第二个边点的行值(纵坐标);
ColumnEdgeSecond
:出参,第二个边点的列值(横坐标);
AmplitudeSecond
:出参,第二条边的边缘振幅(带符号);
RowEdgeCenter
:出参,边对中心行值;
ColumnEdgeCenter
:出参,边对中心列值;
FuzzyScore
:出参,边缘对的模糊评估分数;
IntraDistance
:出参,边对内边缘距离;
InterDistance
:出参,边对间边缘距离;
2. dev_display_profile_points
——官方文档没解释;
3. get_string_extents
——查询字符串输出大小的宽度和高度,挺好用的函数,可以让显示美观些;