例程功能

 检查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

要点

  1. 模糊测量——对标准测量的一种扩展,并不意味着测量是“模糊的”,而是用模糊隶属函数来控制边缘的选择。所谓的模糊隶属函数,就是将边缘的特征值转换为隶属度值(我理解为权重值),基于这些隶属值做出是否选择边缘的决定,即当隶属值大于你设定模糊阈值时,边缘就会被选中,反之则同理。这种方法的优点是即使使用很低的最小阈值或平滑,也能灵活处理额外的边缘
      直接用一维测量会产生错误的结果,这时将“引线的宽度的大约为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——查询字符串输出大小的宽度和高度,挺好用的函数,可以让显示美观些;

01-23 15:05