Tutorial - VC-Z HALCON Image Acquisition Interface  1.0

How to build image processing

How to build image processing

We have a first skeleton script to open the test images. Now we have to implement the image processing task. Reminder, the application is described below.

1. Application description

The camera will see a Box with a circle pattern on the upper face. The aim of the application is to detect the 3D position of the Box.

AppImage.png

2. Implementation of image processing

To achieve this image processing topic, we propose this method:

3. Edges detection

This step is done simply by the operator:

edges_sub_pix(Image, Edges, 'sobel_fast', 1, 10, 20)

The result 'Edges' looks like this image:

ImgProc_Edges.png

4. Circle pattern detection

We have to filter the 'Edges' results in order to keep the biggest elliptic one.

At first we can remove very small edges by filtering with a 'length' > 50 px and concatenate adjacent result edges:

select_shape_xld(Edges, SelectedXLD, 'contlength', 'and', 50, 99999999)
union_adjacent_contours_xld(SelectedXLD, UnionContours, 10, 1, 'attr_keep')

The result 'UnionContours' looks like this image:

ImgProc_UnionContours.png

Then we can filter them with the 'compactness' feature in order to keep the most rounded shapes.

select_shape_xld (UnionContours, SelectedXLD1, 'compactness', 'and', 0, 1.5)

Finally we keep the longest one:

length_xld(SelectedXLD1, Length)
select_obj(SelectedXLD1, CircularPattern, sort_index(Length)[|Length|-1]+1)

The result 'CircularPattern' looks like this image:

ImgProc_CircullarPattern.png

5. Pose estimation

At this step we keep only one edge in 'CircularPattern' that must be the circular pattern. To compute the 3D Pose from the circular shape, we can simply call the operator 'get_circle_pose()':

// Fake calibration
focus := 0.012 // lens 12 mm
pixelsize := 5.3e-6 // 5.3 µm
CamParam := [focus, 0, pixelsize, pixelsize, Width/2, Height/2, Width, Height]
// Get the 3D pose
get_circle_pose(CircularPattern, CamParam, 0.025, 'pose', Pose1, Pose2)

The operator 'get_circle_pose()' need a calibrated camera, we have to compute the internal camera parameters 'CamParam'. In this simple sample, we use theoretical internal camera parameters. So the 3D position will be computed but it will not be accurate like we are using a real CamParam.

In our sample the circular pattern on the box has a diameter of 5 cm. So we specify a radius of 0.025 meter.

We can see there are 2 3D Poses in output. It is due to a ambiguity on the orientation of the circular shape seen as an ellipse.

Pose1 := [0.00312725, -0.015015, 0.383852, 37.1182, 2.27214, 0.0, 0]
Pose2 := [0.00321507, -0.016536, 0.383789, 327.607, 358.505, 0.0, 0]

The first three elements of the output parameters Pose1 and Pose2 contain the position X, Y and Z in meter of the center of the circle. The following three elements contain the 2 possible orientations due to the elliptic ambiguity. The 6th value for the rotation around the z axis is set to zero, because it cannot be determined.

6. Display results

We can show the 3D Pose simply by the call of this procedure:

disp_3d_coord_system(WindowHandle, CamParam, Pose1, 0.07)

It draws the 3 axes XYZ on the top of the Box centered on the circular pattern. And the axes will look like a length of 7 cm.

The result looks like this image:

ImgProc_3dPose.png

At the end we will display the teapot under the box. We have to read the CAD file at the beggining of the sript:

read_object_model_3d('./teapot.ply', 0.02, [], [], Tea, Status)

For each 3D pose detected, we can project the CAD file on the 2D image:

project_object_model_3d (ModelContoursTea, Tea, CamParam, Pose2, [], [])
AppImageResultHDevelop.png

You can get the complete source code here and the teapot CAD file.


Next section: How to run the Vision Application inside the Camera