Halcon中的坐标系的原點在左上角,而一般二維平面坐标系的原點在左下角。
請注意,使用read_polygon_xld_dxf讀取DXF檔案所産生的幾何資訊與使用read_contour_xld_dxf讀取檔案完全相同。 但是,資料結構不同。
draw_xld_mod — Interactive modification of a contour.
read_contour_xld_dxf (Contours, 'AAA.dxf', 'min_num_points', 100, DxfStatus)
hom_mat2d_identity (HomMat2DIdentity)
get_image_size (Image, Width, Height)
hom_mat2d_scale (HomMat2DIdentity, 0.06, 0.06, Height/2.0, Width/2.0, HomMat2DScale)
affine_trans_contour_xld(Contours, ContoursAffinTrans1, HomMat2DScale)
1、Halcon讀取dxf檔案,得到的是dxf檔案的機械坐标數值,舉例說明:
*Create locally deformable model
read_contour_xld_dxf (DxfContours, 'C:/Users/firecat/neiyi1.dxf', [], [], DxfStatus)
*合并鄰近的XLD,使得細小線段拼接起來
union_adjacent_contours_xld (DxfContours, UnionContours, 10, 1, 'attr_keep')
count_obj(UnionContours, NumberContours)
for i := 1 to NumberContours by 1
select_obj (UnionContours, ObjectSelected, i)
length_xld (ObjectSelected, Length)
get_contour_xld (ObjectSelected, row, col)
endfor
create_local_deformable_model_xld (UnionContours, 'auto', rad(-10), rad(20), 'auto', 1, 1, 'auto',
1, 1, 'auto', 'auto', 'ignore_local_polarity', 5, [], [], ModelID)
get_deformable_model_contours (ModelContours, ModelID, 1)
2、如何實作xld的縮放?通過縮放XLD中每個點的坐标值來實作。xld需要先縮放,後拼接!
read_contour_xld_dxf (DxfContours, 'C:/Users/firecat/neiyi1.dxf', [], [], DxfStatus)
Scale := 4
count_obj(DxfContours, NumberContours)
gen_empty_obj (ScaleContours)
for i := 1 to NumberContours by 1
select_obj (DxfContours, ObjectSelected, i)
get_contour_xld (ObjectSelected, row, col)
Row1 := []
Col1 := []
for j := 0 to |row|-1 by 1
Row1:=[Row1, row[j] * Scale]
Col1:=[Col1, col[j] * Scale]
endfor
*判斷輪廓是不是閉合,如果是閉合的,那麼使最後一個點與第一個點重合(即讓縮放後的XLD也閉合)
test_closed_xld (ObjectSelected, IsClosed)
if (IsClosed == 1)
Row1:=[Row1, row[0] * Scale]
Col1:=[Col1, col[0] * Scale]
endif
gen_contour_polygon_xld (Contour1, Row1, Col1)
smooth_contours_xld (Contour1, SmoothedContours, 5)
concat_obj (ScaleContours, SmoothedContours, ScaleContours)
endfor
*xld拼接
union_adjacent_contours_xld (ScaleContours, UnionContours, 10, 1, 'attr_keep')
其中:
get_contour_xld (Contour, Row, Col)是得到XLD中的一系列點;
gen_contour_polygon_xld (Contour1, Row1, Col1)是通過一系列點重建XLD。
3、鏡像(因為DXF坐标系和halcon坐标系存在上下翻轉的對應關系)
*使用仿射變換實作鏡像,這裡是上下翻轉
hom_mat2d_identity (HomMat2DIdentity)
hom_mat2d_reflect (HomMat2DIdentity, 0, 0, 0, 32, HomMat2DReflect)
affine_trans_contour_xld (UnionContours, ContoursAffinTrans, HomMat2DReflect)
hom_mat2d_reflect算子的參數說明:
Px (input_control) point.x → (real / integer)
First point of the axis (x coordinate).
Default value: 0
Suggested values: 0, 16, 32, 64, 128, 256, 512, 1024
Py (input_control) point.y → (real / integer)
First point of the axis (y coordinate).
Qx (input_control) point.x → (real / integer)
Second point of the axis (x coordinate).
Default value: 16
Qy (input_control) point.y → (real / integer)
Second point of the axis (y coordinate).
Default value: 32
4、更詳細的實踐
read_contour_xld_dxf (DxfContours, 'C:/Users/firecat/Downloads/1.dxf', [], [], DxfStatus)
*合并鄰近的XLD,使得細小線段拼接起來
union_adjacent_contours_xld (DxfContours, UnionContours, 5, 1, 'attr_keep')
*找出面積最大的輪廓,方法1
count_obj(UnionContours, NumberContours)
maxArea := 0
index := 0
for i := 1 to NumberContours by 1
select_obj (UnionContours, ObjectSelected, i)
length_xld (ObjectSelected, Length)
area_center_xld (ObjectSelected, Area, Row1, Column1, PointOrder)
if (Area > maxArea)
maxArea := Area
index := i
endif
get_contour_xld (ObjectSelected, row, col)
endfor
select_obj (UnionContours, MaxAreaSelected, index)
get_contour_xld (MaxAreaSelected, Row2, Column2)
stop()
*找出面積最大的輪廓,方法2
area_center_xld (UnionContours, Area, Row, Column, PointOrder)
*先将Area中各元素按升序排序,然後将排序後的每一個Area分别在原Area元組中的索引放在元組Indices 中
tuple_sort_index (Area, Indices)
Num := |Indices|
*tuple的下标從0開始計數;Obj的下标從1開始計數;
index := Indices[Num-1] + 1
select_obj (UnionContours, MaxAreaSelected, Indices[Num-1] + 1)
get_contour_xld (MaxAreaSelected, Row1, Col1)
stop()
*把最大輪廓裁剪出來,生成圖檔
gen_region_contour_xld (MaxAreaSelected, Region, 'filled')
gen_image_const (NewImage, 'byte', 1000, 1000)
*Create an image with a specified constant gray value
gen_image_proto (NewImage, ImageCleared1, 255)
*Paint regions into an image
paint_region (Region, ImageCleared1, ImageResult, 0, 'fill')
write_image (ImageResult, 'jpeg', 0, 'D:/1.jpg')
再優化更新一稿:
read_contour_xld_dxf (DxfContours, 'C:/Users/firecat/Downloads/match/neiyi/M-OK180503.dxf', [], [], DxfStatus)
*合并鄰近的XLD,使得細小線段拼接起來
union_adjacent_contours_xld (DxfContours, UnionContours, 5, 1, 'attr_keep')
*找出面積最大的輪廓,方法1
count_obj(UnionContours, NumberContours)
maxArea := 0
index := 0
for i := 1 to NumberContours by 1
select_obj (UnionContours, ObjectSelected, i)
length_xld (ObjectSelected, Length)
area_center_xld (ObjectSelected, Area, Row1, Column1, PointOrder)
if (Area > maxArea)
maxArea := Area
index := i
endif
get_contour_xld (ObjectSelected, row, col)
endfor
select_obj (UnionContours, MaxAreaSelected, index)
get_contour_xld (MaxAreaSelected, Row2, Column2)
stop()
*找出面積最大的輪廓,方法2
area_center_xld (UnionContours, Area, Row, Column, PointOrder)
*先将Area中各元素按升序排序,然後将排序後的每一個Area分别在原Area元組中的索引放在元組Indices 中
tuple_sort_index (Area, Indices)
Num := |Indices|
*tuple的下标從0開始計數;Obj的下标從1開始計數;
index := Indices[Num-1] + 1
select_obj (UnionContours, MaxAreaSelected, Indices[Num-1] + 1)
get_contour_xld (MaxAreaSelected, Row1, Col1)
stop()
*求出外接矩形
shape_trans_xld(MaxAreaSelected, XLDTrans, 'rectangle1')
area_center_xld (XLDTrans, Area, Row2, Column2, PointOrder)
smallest_rectangle1_xld (MaxAreaSelected, Row11, Column11, Row21, Column21)
width := Column21 - Column11 + 1
height := Row21 - Row11 + 1
*建立圖檔,圖檔左上角是零點,準備用來存放最大面積
gen_image_const (NewImage, 'byte', width, height)
area_center (NewImage, Area, Row1, Column1)
*Create an image with a specified constant gray value
gen_image_proto (NewImage, ImageCleared, 255)
*仿射變換,讓外接矩形的最大面積和圖檔重合
hom_mat2d_identity (HomMat2DIdentity)
hom_mat2d_translate (HomMat2DIdentity, Row1 - Row2, Column1 - Column2, HomMat2DTranslate)
affine_trans_contour_xld (MaxAreaSelected, ContoursAffineTrans, HomMat2DTranslate)
*把最大輪廓區域裁剪出來
gen_region_contour_xld (ContoursAffineTrans, Region, 'filled')
*Paint regions into an image
paint_region (Region, ImageCleared, ImageResult, 0, 'fill')
*注意儲存路徑的斜杆,是/
write_image (ImageResult, 'jpeg', 0, 'D:/test.jpg')
stop()