<?xml version="1.0" encoding="UTF-8"?>
<hdevelop file_version="1.2" halcon_version="19.05.0.0">
<procedure name="main">
<interface/>
<body>
<c>************************************************************************************************</c>
<c>* Parameter</c>
<c>************************************************************************************************</c>
<c></c>
<l>PathImg := './'</l>
<l>PathIdRect := '.rect.'</l>
<l>ZoomDisplay := 0.3</l>
<c></c>
<c>* Distortions from OpenCV</c>
<l>Distortions := [-0.161881, 0.092025, 0.000072, -0.000105, 0.000000]</l>
<c>*</c>
<c>* Camera matrices from OpenCV</c>
<l>* CamMatrixOpenCV := [1402.101918, 0.000000, 967.367190,\
0.000000, 1399.751916, 580.546496,\
0.000000, 0.000000, 1.000000]</l>
<c></c>
<c>* CamMatrixOpenCV</c>
<l>Cx := 967.3672</l>
<l>Cy := 580.546496</l>
<l>fxPix := 1402.101918</l>
<l>fyPix := 1399.751916</l>
<l>f := 0.00824144</l>
<c>*</c>
<l>* ProjectionOpenCV := [ fxPix, 0.000000, Cx, 0.000000,\
0.000000, fyPix, Cy, 0.000000,\
0.000000, 0.000000, 1.000000, 0.000000,\
0, 0, 0, 1 ]</l>
<c></c>
<c>************************************************************************************************</c>
<c>* Initialization</c>
<c>************************************************************************************************</c>
<c></c>
<l>dev_update_off ()</l>
<c></c>
<c>* Prepare the image data.</c>
<l>list_image_files (PathImg, 'png', [], ImageFilesAll)</l>
<l>ImageFilesRectified := regexp_select(ImageFilesAll, PathIdRect)</l>
<l>ImageFilesNonRectified := difference(ImageFilesAll, ImageFilesRectified)</l>
<l>if (|ImageFilesNonRectified| != |ImageFilesRectified|)</l>
<l> throw (['Uneven amounts of images found, please check the image pairs'])</l>
<l>endif</l>
<c></c>
<c>* Prepare the display</c>
<l>read_image (Image, ImageFilesNonRectified[0])</l>
<l>get_image_size (Image, Width, Height)</l>
<l>for I := 0 to 2 by 1</l>
<l> dev_open_window (0, I*(Width*ZoomDisplay+12), Width*ZoomDisplay, Height*ZoomDisplay, 'black', WindowHandles.at(I))</l>
<l> set_display_font (WindowHandles.at(I), 16, 'mono', 'true', 'false')</l>
<l>endfor</l>
<c></c>
<c>* Perform the calibration using an arbitrary grid (full image also possible but slow)</c>
<l>gen_grid_region (RegionGrid, 5, 5, 'points', Width, Height)</l>
<l>get_region_points (RegionGrid, Row, Col)</l>
<l>campar_opencv2halcon (Distortions, f, Cx, Cy, fxPix, fyPix, Row, Col, Width, Height, Error, CamParamsOpt)</l>
<l>change_radial_distortion_cam_par ('adaptive', CamParamsOpt, [0,0,0,0,0], CamParamOptRect) </l>
<l>dev_set_window (WindowHandles.at(0))</l>
<l>dev_disp_text ('Error (pxl): ' + Error, 'window', 'top', 'left', 'black', [], [])</l>
<l>dev_disp_text (['HALCON camera params:', CamParamsOpt], 'window', 'bottom', 'left', 'black', [], [])</l>
<l>disp_continue_message (WindowHandles.at(0), 'black', 'true')</l>
<l>stop ()</l>
<c></c>
<c>* Ignore errors at the close image border</c>
<l>Padding := min([Width, Height])/100</l>
<l>gen_rectangle1 (RoiDiff, Padding, Padding, Height-Padding, Width-Padding)</l>
<c></c>
<c></c>
<c>************************************************************************************************</c>
<c>* Initialization</c>
<c>************************************************************************************************</c>
<c></c>
<c>* Apply the calibration</c>
<l>for I := 0 to |ImageFilesNonRectified|-1 by 1</l>
<c> * Select the image pair</c>
<l> FileNameNonRectCurrent := ImageFilesNonRectified[I]</l>
<l> FileNameRectCurrent := regexp_select(ImageFilesRectified, split(FileNameNonRectCurrent, PathImg)[0])</l>
<c> </c>
<l> read_image (ImageNonRect, FileNameNonRectCurrent)</l>
<l> read_image (ImageRectOpenCV, FileNameRectCurrent)</l>
<c> </c>
<c> * Rectify the image using the HALCON calibration and compare it to the </c>
<c> * OpenCV ground truth</c>
<l> change_radial_distortion_image (ImageNonRect, ImageNonRect, ImageRectHALCON, CamParamsOpt, CamParamOptRect)</l>
<c></c>
<l> reduce_domain (ImageRectOpenCV, RoiDiff, ImageRectOpenCVReduced)</l>
<l> abs_diff_image (ImageRectOpenCVReduced, ImageRectHALCON, ImageAbsDiff, 1)</l>
<l> threshold (ImageAbsDiff, RegionDiff, 50, 255)</l>
<l> region_features (RegionDiff, 'area', AreaDiff)</l>
<c> </c>
<l> ImagesDisp := {ImageNonRect, ImageRectOpenCV, ImageRectHALCON}</l>
<l> DispText := ['Original image', 'Rect image (OpenCV)', 'Rect image (HALCON)']</l>
<l> for J := 0 to ImagesDisp.length()-1 by 1</l>
<l> dev_set_window (WindowHandles.at(J))</l>
<l> dev_display (ImagesDisp.at(J))</l>
<l> dev_disp_text (DispText[J], 'window', 'top', 'left', 'black', [], [])</l>
<l> endfor</l>
<l> if (AreaDiff>100)</l>
<l> dev_set_color ('#ff0000c0')</l>
<l> dev_display (RegionDiff)</l>
<l> smallest_rectangle1 (RegionDiff, Row1, Column1, Row2, Column2)</l>
<l> dev_set_color ('#ff000040')</l>
<l> gen_rectangle1 (Rectangle, Row1, Column1, Row2, Column2)</l>
<l> dev_disp_text ('Deviation detected', 'window', 'top', 'right', 'red', 'box', 'false')</l>
<l> stop ()</l>
<l> else</l>
<l> dev_disp_text ('No deviation', 'window', 'top', 'right', 'green', 'box', 'false')</l>
<l> endif</l>
<l>endfor</l>
<l>disp_end_of_program_message (WindowHandles.at(WindowHandles.length()-1), 'black', 'true')</l>
<l>stop ()</l>
<c></c>
<c>************************************************************************************************</c>
<c>* Clean up</c>
<c>************************************************************************************************</c>
<c></c>
<l>for I := 0 to WindowHandles.length()-1 by 1</l>
<l> dev_set_window (WindowHandles.at(I))</l>
<l> dev_close_window ()</l>
<l>endfor</l>
<l>dev_update_on ()</l>
</body>
<docu id="main">
<parameters/>
</docu>
</procedure>
<procedure name="campar_opencv2halcon">
<interface>
<ic>
<par name="OpenCv_Distortions" base_type="ctrl" dimension="0"/>
<par name="OpenCvF" base_type="ctrl" dimension="0"/>
<par name="OpenCv_Cx" base_type="ctrl" dimension="0"/>
<par name="OpenCv_Cy" base_type="ctrl" dimension="0"/>
<par name="OpenCv_fxPix" base_type="ctrl" dimension="0"/>
<par name="OpenCv_fyPix" base_type="ctrl" dimension="0"/>
<par name="RowObservations" base_type="ctrl" dimension="0"/>
<par name="ColObservations" base_type="ctrl" dimension="0"/>
<par name="WidthImage" base_type="ctrl" dimension="0"/>
<par name="HeightImage" base_type="ctrl" dimension="0"/>
</ic>
<oc>
<par name="Error" base_type="ctrl" dimension="0"/>
<par name="CamParamsOpt" base_type="ctrl" dimension="0"/>
</oc>
</interface>
<body>
<c>************************************************************************************************</c>
<c>* Prepare the OpenCV values as input for HALCON calibration</c>
<c>************************************************************************************************</c>
<c></c>
<c>* Extract the distortions</c>
<l>k_1 := OpenCv_Distortions[0]</l>
<l>k_2 := OpenCv_Distortions[1]</l>
<l>p_1 := OpenCv_Distortions[2]</l>
<l>p_2 := OpenCv_Distortions[3]</l>
<l>k_3 := OpenCv_Distortions[4]</l>
<c></c>
<c>* Image plane coord. system -> HALCONs "description plate"</c>
<l>x_ := (ColObservations - OpenCv_Cx)/OpenCv_fxPix</l>
<l>y_ := (RowObservations - OpenCv_Cy)/OpenCv_fyPix</l>
<c></c>
<c>* Calculate the distorted points using the OpenCV Model</c>
<l>r2 := x_*x_+y_*y_</l>
<c></c>
<l>x2_tmp := x_ * (1 + k_1 * r2 + k_2 * r2 * r2 + k_3 * r2 * r2 * r2)</l>
<l>x2_ := x2_tmp + (2.0 * p_1 *x_ * y_ + p_2*(r2+2.0*x_*x_))</l>
<c></c>
<l>y2_tmp := y_ * (1 + k_1*r2+k_2*r2*r2+k_3*r2*r2*r2)</l>
<l>y2_ := y2_tmp + (p_1 * (r2 + 2 * y_ * y_) + 2 * p_2 * x_ * y_)</l>
<c></c>
<c>* Image plane coord. system -> Image coord. system (= Pixel coord)</c>
<l>u := OpenCv_fxPix * x2_ + OpenCv_Cx</l>
<l>v := OpenCv_fyPix * y2_ + OpenCv_Cy</l>
<c></c>
<c>* Compute the sensor size</c>
<l>sx := OpenCvF/OpenCv_fxPix</l>
<l>sy := OpenCvF/OpenCv_fyPix</l>
<c></c>
<c></c>
<c>************************************************************************************************</c>
<c>* Perform a HALCON calibration</c>
<c>************************************************************************************************</c>
<c></c>
<l>create_calib_data ('calibration_object', 1, 1, CalibDataID)</l>
<c>* Define a calibration plate</c>
<l>tuple_gen_const (|x_|, OpenCvF, Zeroes)</l>
<l>set_calib_data_calib_object (CalibDataID, 0, [x_, y_, Zeroes])</l>
<c>* Define the start params</c>
<l>gen_cam_par_area_scan_polynomial (OpenCvF, 0, 0, 0, 0, 0, sx, sy, OpenCv_Cx, OpenCv_Cy, WidthImage, HeightImage, CameraParamStart)</l>
<l>set_calib_data_cam_param (CalibDataID, 0, [], CameraParamStart)</l>
<c>* Exclude all params we can set directly from OpenCV</c>
<l>set_calib_data (CalibDataID, 'camera', 0, 'excluded_settings', ['pose'])</l>
<l>set_calib_data (CalibDataID, 'camera', 0, 'excluded_settings', ['focus','cx','cy'])</l>
<c></c>
<c>* Set the observation points</c>
<l>hom_mat3d_identity (HomMat3DIdentity)</l>
<l>hom_mat3d_to_pose (HomMat3DIdentity, Pose)</l>
<l>set_calib_data_observ_points (CalibDataID, 0, 0, 0, v, u, 'all', Pose)</l>
<c>* Calibrate the camera and deliver the results</c>
<l>calibrate_cameras (CalibDataID, Error)</l>
<l>get_calib_data (CalibDataID, 'camera', 0, 'params', CamParamsOpt)</l>
<l>clear_calib_data (CalibDataID)</l>
<l>return ()</l>
</body>
<docu id="campar_opencv2halcon">
<parameters>
<parameter id="CamParamsOpt">
<sem_type>campar</sem_type>
</parameter>
<parameter id="ColObservations">
<default_type>real</default_type>
<sem_type>number</sem_type>
<type_list>
<item>real</item>
</type_list>
</parameter>
<parameter id="Error">
<default_type>real</default_type>
<multivalue>false</multivalue>
<sem_type>number</sem_type>
<type_list>
<item>real</item>
</type_list>
</parameter>
<parameter id="HeightImage">
<default_type>integer</default_type>
<sem_type>number</sem_type>
<type_list>
<item>integer</item>
</type_list>
<value_max>1</value_max>
<value_min>1</value_min>
</parameter>
<parameter id="OpenCvF">
<default_type>real</default_type>
<multivalue>false</multivalue>
<sem_type>number</sem_type>
<type_list>
<item>real</item>
</type_list>
</parameter>
<parameter id="OpenCv_Cx">
<default_type>real</default_type>
<sem_type>number</sem_type>
<type_list>
<item>real</item>
</type_list>
</parameter>
<parameter id="OpenCv_Cy">
<default_type>real</default_type>
<sem_type>number</sem_type>
<type_list>
<item>real</item>
</type_list>
</parameter>
<parameter id="OpenCv_Distortions">
<default_type>real</default_type>
<mixed_type>optional</mixed_type>
<multivalue>true</multivalue>
<sem_type>number</sem_type>
<type_list>
<item>integer</item>
<item>real</item>
</type_list>
</parameter>
<parameter id="OpenCv_fxPix">
<default_type>real</default_type>
<sem_type>number</sem_type>
<type_list>
<item>real</item>
</type_list>
</parameter>
<parameter id="OpenCv_fyPix">
<default_type>real</default_type>
<sem_type>number</sem_type>
<type_list>
<item>real</item>
</type_list>
</parameter>
<parameter id="RowObservations">
<default_type>real</default_type>
<sem_type>number</sem_type>
<type_list>
<item>real</item>
</type_list>
</parameter>
<parameter id="WidthImage">
<default_type>integer</default_type>
<sem_type>number</sem_type>
<type_list>
<item>integer</item>
</type_list>
<value_max>1</value_max>
<value_min>1</value_min>
</parameter>
</parameters>
</docu>
</procedure>
</hdevelop>