Halcon一日一练:CAD类型的相关操作
大很多场合,需要在视觉程序中导入CAD文档,比如,在3C行业,需要对手机外壳进行CNC加工,或者点胶操作,此时,需要获取产品的各个点的数据。如果将CAD直接导入,就会大的减少编程工作量,同时也能达到很高的精度。
以下为Halcon自带例程:
* This example program shows how to read DXF files and how to * use this CAD description of objects to generate shape models. * The program is a slightly modified copy of the example program * examples/hdevelop/Applications/Object-Recognition-2D/ * pm_multiple_models.hdev. * The following modifications to this program were made: * - The model images are created from the DXF description of * the objects. * - The parameters of the operator find_shape_models were * slightly relaxed because the DXF object description does * not fit exactly to the objects in the search image because * the images were taken with an uncalibrated and slightly * oblique viewing camera. * This program shows how to use HALCON's shape-based * matching to find multiple different models in one call to * find_shape_models. Note that this is one mode of operation * that is frequently useful. However, the number of * applications that can be solved with this mechanism is much * larger. Other applications where finding multiple models * in one call is useful are applications where the same object * can only occur in small angle ranges around a discrete set * of angles, e.g., 0°, 90°, 180°, and 270°. In these cases, * it would be wasteful to train the model for the full 360° * rotation range and to match the model in this range. Instead, * four models using the small angle ranges around the discrete * set of angles should be generated from the same model image * and used in the matching stage using four different angle * ranges. * dev_update_pc ('off') dev_update_window ('off') dev_update_var ('off') dev_close_window () dev_open_window (0, 0, 646, 482, 'black', WindowHandle) dev_set_part (0, 0, 481, 645) dev_set_draw ('margin') set_display_font (WindowHandle, 16, 'mono', 'true', 'false') dev_set_line_width (3) * These colors will be used to graphically discern the different * models in the visualization code below. Colors := ['red','green','cyan'] * The object Models will hold a set of XLD contours that * represent the different models. They are used below to overlay * the found models on the current image. XLD contours are used * because they can be transformed much faster than regions. This * creates a slight problem because in general multiple XLD * contours will represent one model. Therefore, the start and * end indices of the different models will be stored in IndexS * and IndexE, respectively. gen_empty_obj (Models) IndexS := [] IndexE := [] * The variable ModelIDs holds the different models that are * created below. ModelIDs := [] * Likewise, RowsRef and ColumnsRef store the reference points * of the different models. They are necessary to transform the * models to the found instances in the current image. for J := 1 to 3 by 1 dev_clear_window () read_contour_xld_dxf (Contours, 'metal-part-' + J$'02', [], [], DxfStatus)//读取DXF文件,并将其转换为DXF轮廓。 gen_model_image_of_bright_object_with_holes (Contours, Image, 3.38, 646, 482) dev_display (Image) dev_set_color ('green') set_tposition (WindowHandle, 20, 20) write_string (WindowHandle, 'Generating shape model ' + J$'d') get_domain (Image, Domain) area_center (Domain, Area, Row, Column) * Although we will use get_shape_model_contours below to * obtain the representation of the model, we extract a model * representation here using inspect_shape_model because this * enables us to display the representation of the model while * the model is being created. inspect_shape_model (Image, ModelImages, ModelRegions, 1, 30) * Since the shape models contain a few extraneous edges, * they will be removed here to give a slightly nicer * visualization. connection (ModelRegions, ConnectedRegions) select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 20, 100000) union1 (SelectedRegions, ModelRegions) gen_contours_skeleton_xld (ModelRegions, ModelContours, 1, 'filter') dev_set_color ('red') dev_display (ModelContours) create_shape_model (Image, 5, rad(0), rad(360), 'auto', 'pregeneration', 'use_polarity', 30, 10, ModelID) get_shape_model_contours (ModelCont, ModelID, 1) select_shape_xld (ModelCont, ModelContours, 'contlength', 'and', 20, 1000) * Count how many XLD contours there are in the current * model and in the already stored models. This is necessary * to compute IndexS and IndexE. count_obj (ModelContours, NumModel) count_obj (Models, NumModels) concat_obj (Models, ModelContours, Models) IndexS := [IndexS,NumModels + 1] IndexE := [IndexE,NumModels + NumModel] ModelIDs := [ModelIDs,ModelID] endfor disp_message (WindowHandle, ['Press left button to start','and stop the demo'], 'image', 50, 20, 'yellow', 'false') get_mbutton (WindowHandle, Row1, Column1, Button1) wait_seconds (0.5) dev_set_color ('red') Button := 0 ImgNo := 1 while (Button != 1) read_image (Image, 'metal-parts/metal-parts-' + ImgNo$'02d') count_seconds (S1) find_shape_models (Image, ModelIDs, rad(0), rad(360), 0.6, 0, 0.5, 'least_squares', 4, 0.3, Row, Column, Angle, Score, Model) count_seconds (S2) Time := (S2 - S1) * 1000. dev_display (Image) Num := |Score| for J := 0 to Num - 1 by 1 * Select the correct XLD contours from the Models object. copy_obj (Models, ModelSelected, IndexS[Model[J]], IndexE[Model[J]] - IndexS[Model[J]] + 1) * Compute the transformation from the model object to * the current instance. vector_angle_to_rigid (0, 0, 0, Row[J], Column[J], Angle[J], HomMat2D) affine_trans_contour_xld (ModelSelected, ModelTrans, HomMat2D) dev_set_color (Colors[Model[J]]) dev_display (ModelTrans) endfor if (Num == 1) disp_message (WindowHandle, Num$'1d' + ' object found in ' + Time$'4.2f' + 'ms', 'image', 20, 20, 'yellow', 'false') else disp_message (WindowHandle, Num$'1d' + ' objects found in ' + Time$'4.2f' + ' ms', 'image', 20, 20, 'yellow', 'false') endif ImgNo := ImgNo + 1 if (ImgNo > 15) ImgNo := 1 endif dev_error_var (Error, 1) dev_set_check ('~give_error') get_mposition (WindowHandle, R, C, Button) dev_error_var (Error, 0) dev_set_check ('give_error') if (Error != H_MSG_TRUE) Button := 0 endif endwhile for J := 0 to |ModelIDs| - 1 by 1 clear_shape_model (ModelIDs[J]) endfor
程序中read_contour_xld_dxf 是读取DXF格式文件的算子,可以将DXF文件转换为XLD轮廓。如果没有提供文件的绝对路径,则会在当前目录下搜索DXF文件。
read_contour_xld_dxf支持如下DXF实体:多段线,2D线段,点,圆,圆弧,椭圆,块,典线。对应DXF实体的X和Y坐标分别存储在列和行的坐标。Z坐标被忽略。
输出参数DxfStatus包含有关DXF文件的部分数据,并转换为轮廓的形式输出。
我们也可以通过write_contour_xld_dxf来将XLD轮廓转换为DXF格式的CAD文件。write_contour_xld_dxf保存DXF格式时可以通过设置参数来确保数据的完整性,设置这些属性的读取可以通过设置通用参数‘read_attributes’为false来关闭,通用参数GenParamNames参数名和在GenParamValues设置的值。
DXF实体中的圆,弧,椭圆和曲线转换过程中为近似的XLD轮廓,近似精度可以通用参数min_num_points和max_approx_error来控制。参数min_num_point定义了被用于近似采样点的最小数量。需要注意的是,参数min_num_points针对完整的圆或椭圆形对应的采集点数,对应于圆弧或椭圆弧,如果min_num_points设置为50,则表示读取一个半圆,此时半圆为至少25个采样点。参数max_approx_error定义的XLD轮廓的理想圆或椭圆,分别的最大偏差(单位:pixel像素)
Halcon自带例程
* This example program shows how to use the operators * write_contour_xld_dxf and read_contour_xld_dxf as well as * the operators write_polygons_xld_dxf and read_polygon_xld_dxf * * First, edges are extracted from an image. read_image (Image, 'mreut') edges_sub_pix (Image, Edges, 'canny', 2, 20, 40) * * Then, to create global attributes, the regression lines are determined. regress_contours_xld (Edges, RegressContours, 'no', 1) * * Now, we can query what attributes and global attributes * are available for the contours. select_obj (RegressContours, ObjectSelected, 1) query_contour_attribs_xld (ObjectSelected, Attribs) query_contour_global_attribs_xld (ObjectSelected, GlobalAttribs) * * In the next step, the contours are written into a DXF file. This file * contains also the attributes and global attributes. write_contour_xld_dxf (RegressContours, 'contours') * * When the contours are read from the DXF file created with * read_contours_xld_dxf, the (global) attributes are read, too. read_contour_xld_dxf (ContoursRead, 'contours', [], [], DxfStatusCont) * * All (global) attributes that were available for the * original contours (RegressContours) are available also for the * contours (ContoursRead) that have been read from the DXF file. select_obj (ContoursRead, ObjectSelected, 1) query_contour_attribs_xld (ObjectSelected, AttribsTest) query_contour_global_attribs_xld (ObjectSelected, GlobalAttribsTest) * * Now, we show how to write and read polygons gen_polygons_xld (ContoursRead, Polygons, 'ramer', 2) write_polygon_xld_dxf (Polygons, 'polygons') read_polygon_xld_dxf (PolygonsRead, 'polygons', [], [], DxfStatusPoly)