is called the profile
get_image_size(Fuse,Width,Height)
Row := 297
Column := 545
Lenght1 :=80
Lenght2 :=10
Angle :=rad(90)
*Length1 为矩形宽 Length2为矩形高
'bilinear',MeasureHandle)
* ColumnEdgeFirst,\
* ColumEdgeSecond 数组中
ColumnEdgeFirst,AmpliudeFirst,RowEdgeSecond,\
ColumEdgeSecond,AmpliudeSecond,IntraDistance,\
InterDistance)
*gen_contour_polygon_xld(Edge,[0,1,2,2,2],[0,0,0,1,2]) 可以得到这样的图形
gen_contour_polygon_xld (EdgeFirst, \
[-sin(Angle+rad(90))*Lenght2+RowEdgeFirst[i],\
-sin(Angle-rad(90))*Lenght2+RowEdgeFirst[i]],\
[cos(Angle+rad(90))*Lenght2+ColumnEdgeFirst[i], \
cos(Angle-rad(90))*Lenght2+ColumnEdgeFirst[i]])
gen_contour_polygon_xld (EdgeSecond, \
[-sin(Angle+rad(90))*Lenght2+RowEdgeSecond[i],\
-sin(Angle-rad(90))*Lenght2+RowEdgeSecond[i]],\
[cos(Angle+rad(90))*Lenght2+ColumEdgeSecond[i], \
cos(Angle-rad(90))*Lenght2+ColumEdgeSecond[i]])
dev_set_color ('cyan')
dev_display (EdgeFirst)
dev_set_color ('magenta')
dev_display (EdgeSecond)
dev_set_color ('blue')
endfor
read_image(Zeiss1,'zeiss1')
get_image_size(Zeiss1,Width,Height)
dev_close_window()
dev_open_window(0,0,Width/2,Height/2,'black',WindowHandle)
dev_display(Zeiss1)
Row := 275
Column :=335
Radius :=107
AngleStart :=-rad(55)
AngleExtent :=rad(170)
*获取椭圆指定角度的点坐标
get_points_ellipse(AngleStart+AngleExtent,Row,Column,0,Radius,Radius,\
RowPoint,ColPoint )
dev_set_draw('fill')
dev_set_color('green')
dev_set_line_width(1)
disp_arc (WindowHandle, Row, Column, AngleExtent,RowPoint, ColPoint)
*生成测量圆弧
gen_measure_arc(Row,Column,Radius,AngleStart,AngleExtent,10,\
Width,Height,'nearest_neighbor',MeasureHandle)
*测量
measure_pos(Zeiss1,MeasureHandle,1,10,'all','all',RowEdge,\
ColumnEdge,Amplitude,Distance)
*计算距离
distance_pp(RowEdge[1],ColumnEdge[1],RowEdge[2],ColumnEdge[2],IntermeDist)
dev_set_color('red')
dev_set_line_width(3)
disp_line(WindowHandle,RowEdge[1],ColumnEdge[1],RowEdge[2],ColumnEdge[2])
disp_message(WindowHandle,'Distance: ' + IntermeDist , 'image',\
250,8,'yellow','false')
close_measure(MeasureHandle)
例子:Measuring Leads of a Moving IC 测量电路板的针脚边缘
dev_update_pc('off')
dev_update_window('off')
dev_update_var('off')
open_framegrabber ('File', 1, 1, 0, 0, 0, 0, 'default', -1, \
'default', 'default', 'default', 'board/board.seq', 'default',\
-1, -1, FGHandle)
grab_image(Image,FGHandle)
get_image_size(Image,Width,Height)
dev_close_window()
dev_open_window(0,0,Width,Height,'black',WindowHandle)
dev_set_window(WindowHandle)
dev_display(Image)
Row1 :=188
Column1 :=182
Row2 :=298
Column2 :=412
gen_rectangle1(Rectangle,Row1,Column1,Row2,Column2)
area_center(Rectangle,Area,Row,Column)
dev_display(Rectangle)
Rect1Row :=-102
Rect1Col :=5
Rect2Row :=107
Rect2Col :=5
RectPhi :=0
RectLength1 :=170
RectLength2 :=5
gen_rectangle2 (Rectangle1, Row+Rect1Row, Column+Rect1Col, RectPhi, RectLength1, RectLength2)
gen_rectangle2 (Rectangle2, Row+Rect2Row, Column+Rect2Col, RectPhi, RectLength1, RectLength2)
dev_display(Rectangle1)
dev_display(Rectangle2)
*创建模型
reduce_domain(Image,Rectangle,ImageReduced)
create_shape_model (ImageReduced,'auto', 0, rad(360), rad(1), 'none', 'use_polarity', 30, 'auto', ModelID)
*获取模型轮廓 shapeModel 在下面有用到哦
*shapeMode 是基准 ,这里shapemodel 的中心点 是原点(0,0) 也就是图像的左上角
get_shape_model_contours(ShapeModel,ModelID,1)
*这段代码没用 囧 ~~ 例子里写这段干嘛 不嫌长啊
*
*创建变换矩阵
*hom_mat2d_identity(HomMat2DIndentity)
*平移矩阵
*hom_mat2d_translate(HomMat2DIndentity,Row,Column,HomMat2DTranslate)
*shapeModel平移 ,这样就到了原来的位置
*因为没有旋转,所以不需要旋转变换了
*affine_trans_contour_xld(ShapeModel,ShapeMOdelTrans,HomMat2DTranslate)
disp_message(WindowHandle,['Press left button to start','and stop the demo'],\
'image',12,12,'black','true')
get_mbutton(WindowHandle,Row3,Column3,Button1)
Button :=0
while(Button #1)
dev_set_window(WindowHandle)
dev_set_part(0,0,Height-1,Width-1)
grab_image(ImageCheck,FGHandle)
dev_display(ImageCheck)
*得到匹配模型的位置和旋转角度
find_shape_model (ImageCheck, ModelID, rad(0), rad(360), 0.7, 1, 0.5, 'least_squares', 4, 0.7,\
RowCheck, ColumnCheck, AngleCheck, Score)
if(|Score| > 0)
dev_set_color('green')
*这里对shapeModel(基准shapemodel 是在图像原点的) 做平移和旋转操作.
hom_mat2d_identity(HomMat2DIndentity)
hom_mat2d_translate(HomMat2DIndentity,RowCheck,ColumnCheck,HomMat2DTranslate)
hom_mat2d_rotate(HomMat2DTranslate,AngleCheck,RowCheck,ColumnCheck,HomMat2DRotate)
affine_trans_contour_xld(ShapeModel,ShapeModelTrans,HomMat2DRotate)
dev_display(ShapeModelTrans)
*这里是对测量区域做校准,图像变换后,测量区域也是要跟着变的饿
*根据新的变换矩阵,以 测量区域 Rect1Row等 求出变换后的 新Rect1RowCheck
*这样就可以创建新的 测量区域了
affine_trans_pixel(HomMat2DRotate,Rect1Row,Rect1Col,Rect1RowCheck,Rect1ColCheck)
affine_trans_pixel(HomMat2DRotate,Rect2Row,Rect2Col,Rect2RowCheck,Rect2ColCheck)
gen_rectangle2(Rectangle1Check,Rect1RowCheck,Rect1ColCheck,AngleCheck,RectLength1,RectLength2)
gen_rectangle2(Rectangle2Check,Rect2RowCheck,Rect2ColCheck,AngleCheck,RectLength1,RectLength2)
dev_set_color('blue')
dev_set_draw('margin')
dev_set_line_width(3)
dev_display(Rectangle1Check)
dev_display(Rectangle2Check)
gen_measure_rectangle2 (Rect1RowCheck, Rect1ColCheck, AngleCheck, RectLength1, RectLength2,\
Width, Height, 'nearest_neighbor', MeasureHandle1)
gen_measure_rectangle2 (Rect2RowCheck, Rect2ColCheck, AngleCheck, RectLength1, RectLength2,\
Width, Height, 'nearest_neighbor', MeasureHandle2)
measure_pairs (ImageCheck, MeasureHandle1, 2, 90, 'positive', 'all', RowEdgeFirst1, \
ColumnEdgeFirst1, AmplitudeFirst1, RowEdgeSecond1, ColumnEdgeSecond1, AmplitudeSecond1, IntraDistance1, InterDistance1)
measure_pairs (ImageCheck, MeasureHandle2, 2, 90, 'positive', 'all', RowEdgeFirst2, \
ColumnEdgeFirst2, AmplitudeFirst2, RowEdgeSecond2, ColumnEdgeSecond2, AmplitudeSecond2, IntraDistance2, InterDistance2)
close_measure(MeasureHandle1)
close_measure(MeasureHandle2)
dev_set_color('red')
dev_set_draw('fill')
disp_line (WindowHandle, RowEdgeFirst1-RectLength2*cos(AngleCheck), ColumnEdgeFirst1-RectLength2*sin(AngleCheck), RowEdgeFirst1+RectLength2*cos(AngleCheck), ColumnEdgeFirst1+RectLength2*sin(AngleCheck))
disp_line (WindowHandle, RowEdgeSecond1-RectLength2*cos(AngleCheck), ColumnEdgeSecond1-RectLength2*sin(AngleCheck), RowEdgeSecond1+RectLength2*cos(AngleCheck), ColumnEdgeSecond1+RectLength2*sin(AngleCheck))
disp_line (WindowHandle, RowEdgeFirst2-RectLength2*cos(AngleCheck), ColumnEdgeFirst2-RectLength2*sin(AngleCheck), RowEdgeFirst2+RectLength2*cos(AngleCheck), ColumnEdgeFirst2+RectLength2*sin(AngleCheck))
disp_line (WindowHandle, RowEdgeSecond2-RectLength2*cos(AngleCheck), ColumnEdgeSecond2-RectLength2*sin(AngleCheck), RowEdgeSecond2+RectLength2*cos(AngleCheck), ColumnEdgeSecond2+RectLength2*sin(AngleCheck))
wait_seconds(2)
endif
* get_mposition (WindowHandle, R, C, Button)
endwhile
图3 sigma =3.0
*************************************************************
dev_close_window()
read_image(Image,'ic_pin')
get_image_size(Image,Width,Height)
dev_open_window(0,0,Width/2,Height/2,'black',WindowHandle)
dev_display(Image)
Row :=47
Column :=485
Phi :=0
Length1 :=420
Length2 :=10
dev_set_color('green')
dev_set_draw('margin')
dev_set_line_width(3)
gen_rectangle2(Rectangle,Row,Column,Phi,Length1,Length2)
gen_measure_rectangle2(Row,Column,Phi,Length1,Length2,Width,Height,\
'nearest_neighbor',MeaserHandle)
* If Transition = 'negative', the edge points with a light-to-dark transition
*in the direction of the major axis of the rectangle are returned in RowEdgeFirst
*and ColumnEdgeFirst. In this case, the corresponding edges with a drak-to-light
*transition are returned in RowEdgeSecond and ColumnEdgeSecond
measure_pairs (Image, MeaserHandle, 1.5, 30, 'negative', 'all', RowEdgeFirst,\
ColumnEdgeFirst, AmplitudeFirst, RowEdgeSecond, ColumnEdgeSecond,\
AmplitudeSecond, PinWidth, PinDistance)
disp_line (WindowHandle, RowEdgeFirst, ColumnEdgeFirst, RowEdgeSecond,\
ColumnEdgeSecond)
avgPinWidth :=sum(PinWidth)/|PinWidth|
avgPinDistance :=sum(PinDistance)/|PinDistance|
numPins :=|PinWidth|
dev_set_color('yellow')
disp_message(WindowHandle,'Number of pins :'+numPins,'image',200,100,'yellow','false')
disp_message(WindowHandle,'Average Pin Width:' +avgPinWidth,'image',260,100,'yellow','false')
*来个特写
stop()
Row1 := 0
Column1 := 600
Row2 := 100
Column2 := 700
dev_set_color ('blue')
disp_rectangle1 (WindowHandle, Row1, Column1, Row2, Column2)
dev_set_part(Row1,Column1,Row2,Column2)
dev_display(Image)
dev_set_color('green')
dev_display(Rectangle)
dev_set_color('red')
disp_line (WindowHandle, RowEdgeFirst, ColumnEdgeFirst, RowEdgeSecond,\
ColumnEdgeSecond)
close_measure(MeaserHandle)
stop()
dev_set_part(0,0,Height-1,Width-1)
dev_display(Image)
dev_set_line_width(3)
Row := 508
Column := 200
Phi := -rad(90)
Length1 := 482
Length2 := 35
gen_rectangle2 (Rectangle, Row, Column, Phi, Length1, Length2)
gen_measure_rectangle2 (Row, Column, Phi, Length1, Length2, Width, Height, 'nearest_neighbor', MeasureHandle)
measure_pos (Image, MeasureHandle, 1.5, 30, 'all', 'all', RowEdge, ColumnEdge, Amplitude, Distance)
disp_line(WindowHandle,RowEdge,ColumnEdge-Length2,RowEdge,ColumnEdge+Length2)
PinHeight1 :=RowEdge[1] - RowEdge[0]
PinHeight2 :=RowEdge[3] - RowEdge[2]
disp_message(WindowHandle,'Pin Height:'+PinHeight1,'image',\
RowEdge[1],ColumnEdge[1]+100,'yellow','false')
disp_message(WindowHandle,'Pin Height:'+PinHeight2,'image',\
RowEdge[3]-50,ColumnEdge[3]+100,'yellow','false')
close_measure(MeasureHandle)
Suppress Clutter ro Noise 抑制噪声
In many applications there is clutter or noise that must be suppressed. The measure operators offer
multiple approaches to achieve this. The best one is to increase the threshold for the edge extraction to
eliminate faint edges. In addition, the value for the smoothing parameter can be increased to smooth
irrelevant edges away.
When grouping edges to pairs, noise edges can lead to an incorrect grouping if they are in the vicinity of
the “real” edge and have the same polarity. In such a case you can suppress the noise edges by selecting
only the strongest edges of a sequence of consecutive rising and falling edges.
If no alignment is needed, the measure object can, for example, be created offline and reused for each
image. If the alignment involves only a translation, translate_measure can be used to correct the
position.
threshold by using the operator measure_thresh. Here, all positions where the gray value crosses the
given threshold are selected.
In case there are extra edges that do not belong to the measurement, HALCON offers an extended
version of measuring: fuzzy measuring. This tool allows to define so-called fuzzy rules, which describe
the features of good edges. Possible features are, e.g., the position, the distance, the gray values, or the
amplitude of edges. These functions are created with create_funct_1d_pairs and passed to the tool
with set_fuzzy_measure. Based on these rules, the tool will select the most appropriate edges.
The advantage of this approach is the flexibility to deal with extra edges even if a very low min-
imum threshold or smoothing is used. An example for this approach is the example program
fuzzy_measure_pin.hdev on page 53.
Please refer to the Solution Guide III-A, chapter 4 on page 33, for more information.
To have full control over the evaluation of the gray values along the measurement line or arc, you can use
measure_projection. The operator returns the projected gray values as an array of numbers, which
can then be further processed with HALCON operators for tuple or function processing (see the chapters
“Tuple” and “Tools . Function” in the Reference Manual). Please refer to the Solution Guide III-A,
section 3.4 on page 22, for more information.