Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Circle and Line Measurement in Halcon: Metrology Model Approach

Tech May 10 3
read_image (Image, 'test.bmp')
get_image_size (Image, Width, Height)
dev_close_window ()
dev_open_window (0, 0, Width/2, Height/2, 'black', WindowHandle)
dev_display (Image)
dev_set_draw ('margin')

draw_line (WindowHandle, Row1, Column1, Row2, Column2)
draw_circle (WindowHandle, Row, Column, Radius)

Line Measurement Using the Metrology Model

The following code demonstrates how to set up and perform a line measurement using the metrology model. Key parameters such as caliper width, height, spacing, threshold, and edge selection are configured.

set_system ('clip_region', 'false')

* Create metrology model
create_metrology_model (MetrologyHandle)
add_metrology_object_line_measure (MetrologyHandle, StartRow, StartCol, EndRow, EndCol, 100, 20, 1, 30, [], [], Index)

* Set measurement parameters
set_metrology_object_param (MetrologyHandle, Index, 'measure_length1', RuleWidth)
set_metrology_object_param (MetrologyHandle, Index, 'measure_length2', RuleHeight)
set_metrology_object_param (MetrologyHandle, Index, 'measure_distance', RuleSpace)
set_metrology_object_param (MetrologyHandle, Index, 'measure_threshold', RuleThd)
set_metrology_object_param (MetrologyHandle, Index, 'measure_select', RuleSeleP)
set_metrology_object_param (MetrologyHandle, Index, 'measure_transition', RuleMode)

* Apply measurement
apply_metrology_model (Image, MetrologyHandle)
get_metrology_object_result (MetrologyHandle, Index, 'all', 'result_type', ['row_begin', 'column_begin', 'row_end', 'column_end'], Parameter)

if (|Parameter| = 4)
    * Retrieve edge point contours
    get_metrology_object_measures (Contours, MetrologyHandle, Index, RuleMode, PointRows, PointCols)
    * Draw crosses at edge points
    gen_cross_contour_xld (Cross, PointRows, PointCols, 5, 0)
    * Generate line contour from result
    gen_contour_polygon_xld (ContLine, [Parameter[0], Parameter[2]], [Parameter[1], Parameter[3]])
    * Compute center and angle of the line
    centerRow := (Parameter[0] + Parameter[2]) / 2
    centerCol := (Parameter[1] + Parameter[3]) / 2
    angle_lx (Parameter[0], Parameter[1], Parameter[2], Parameter[3], Angle)
endif

clear_metrology_model (MetrologyHandle)

Circle Measurement Using the Metrology Model

This example shows how to configure and execute a circle measurement. The approach is similar to line measurement, but the object type is a circle.

set_system ('clip_region', 'false')

* Create metrology model for circle
create_metrology_model (MetrologyHandle)
add_metrology_object_circle_measure (MetrologyHandle, Row, Column, Radius, 20, 5, 1, 30, [], [], Index)

* Set parameters
set_metrology_object_param (MetrologyHandle, Index, 'measure_length1', RuleWidth)
set_metrology_object_param (MetrologyHandle, Index, 'measure_length2', RuleHeight)
set_metrology_object_param (MetrologyHandle, Index, 'measure_distance', RuleSpace)
set_metrology_object_param (MetrologyHandle, Index, 'measure_threshold', RuleThd)
set_metrology_object_param (MetrologyHandle, Index, 'measure_select', RuleSeleP)
set_metrology_object_param (MetrologyHandle, Index, 'measure_transition', RuleMode)

* Execute measurement
apply_metrology_model (Image, MetrologyHandle)
get_metrology_object_result (MetrologyHandle, Index, 'all', 'result_type', ['row', 'column', 'radius'], Parameter)

if (|Parameter| >= 3)
    * Find edge points
    get_metrology_object_measures (Contours, MetrologyHandle, Index, RuleMode, PointRows, PointCols)
    * Draw crosses
    gen_cross_contour_xld (Cross, PointRows, PointCols, 5, 0)
    * Draw cross at center
    gen_cross_contour_xld (CrossCenter, Parameter[0], Parameter[1], 10, rad(45))
    * Generate fitted circle contour
    gen_circle_contour_xld (ContCircle, Parameter[0], Parameter[1], Parameter[2], 0, 6.28318, 'positive', 1)
endif

clear_metrology_model (MetrologyHandle)

Advanced Circle Measuremant with Multiple Objects

When measuring multiple circles in a single image, hendle each object iteratively. The code below also includes a fallback using least-squares fitting when the metrology model fails to return a result.

set_system ('clip_region', 'false')

tuple_length (Row, Length)

* Initialize model
create_metrology_model (MetrologyHandle)
add_metrology_object_circle_measure (MetrologyHandle, Row, Column, Radius, RuleWidth, RuleHeight, 1, RuleThd, ['min_score'], [0.35], Index)

* Set common parameters for all objects
set_metrology_object_param (MetrologyHandle, 'all', 'measure_distance', RuleSpace)
set_metrology_object_param (MetrologyHandle, 'all', 'measure_select', RuleSeleP)
set_metrology_object_param (MetrologyHandle, 'all', 'measure_transition', RuleMode)

apply_metrology_model (Image, MetrologyHandle)

Parameter := []
gen_empty_obj (Contours)
gen_empty_obj (Cross)
gen_empty_obj (CrossCenter)
gen_empty_obj (ContCircle)

get_metrology_object_result (MetrologyHandle, Index, 'all', 'result_type', ['row', 'column', 'radius'], Parameter)

if (|Parameter| >= 3)
    for Index2 := 0 to Length - 1 by 1
        get_metrology_object_measures (tempContours, MetrologyHandle, Index2, 'all', PointRows, PointCols)
        gen_cross_contour_xld (tempCross, PointRows, PointCols, 5, 0)
        gen_cross_contour_xld (tempCrossCenter, Parameter[Index2 * 3 + 0], Parameter[Index2 * 3 + 1], 50, rad(45))
        gen_circle_contour_xld (tempContCircle, Parameter[Index2 * 3 + 0], Parameter[Index2 * 3 + 1], Parameter[Index2 * 3 + 2], 0, 6.28318, 'positive', 1)
        concat_obj (tempContours, Contours, Contours)
        concat_obj (tempCross, Cross, Cross)
        concat_obj (tempCrossCenter, CrossCenter, CrossCenter)
        concat_obj (tempContCircle, ContCircle, ContCircle)
    endfor
else
    for Index1 := 0 to Length - 1 by 1
        get_metrology_object_measures (tempContours, MetrologyHandle, Index1, 'all', PointRows, PointCols)
        gen_cross_contour_xld (tempCross, PointRows, PointCols, 5, 0)
        * Least-squares circle fitting
        fit_circle_analytic (PointRows, PointCols, tempParameter)
        if (|tempParameter| = 3)
            gen_cross_contour_xld (tempCrossCenter, tempParameter[0], tempParameter[1], 50, rad(45))
            gen_circle_contour_xld (tempContCircle, tempParameter[0], tempParameter[1], tempParameter[2], 0, 6.28318, 'positive', 1)
        endif
        concat_obj (tempContours, Contours, Contours)
        concat_obj (tempCross, Cross, Cross)
        concat_obj (tempContCircle, ContCircle, ContCircle)
        tuple_concat (tempParameter, Parameter, Parameter)
    endfor
endif

clear_metrology_model (MetrologyHandle)

Least-Squares Circle Fitting Function

The function fit_circle_analytic computes the best-fit circle from a set of edge points using an algebraic least-squares method.

* Input: RowList, ColList
* Output: Parameter (row_center, col_center, radius)
Parameter[0] := -999.999
Parameter[1] := -999.999

if (|RowList| <= 3 or |ColList| <= 3 or |RowList| != |ColList|)
    return ()
endif

sum_x := 0.0
sum_y := 0.0
sum_x2 := 0.0
sum_y2 := 0.0
sum_x3 := 0.0
sum_y3 := 0.0
sum_xy := 0.0
sum_x1y2 := 0.0
sum_x2y1 := 0.0

tuple_length (ColList, N)

for i := 0 to N - 1 by 1
    x := RowList[i]
    y := ColList[i]
    x2 := x * x
    y2 := y * y
    sum_x := sum_x + x
    sum_y := sum_y + y
    sum_x2 := sum_x2 + x2
    sum_y2 := sum_y2 + y2
    sum_x3 := sum_x3 + x2 * x
    sum_y3 := sum_y3 + y2 * y
    sum_xy := sum_xy + x * y
    sum_x1y2 := sum_x1y2 + x * y2
    sum_x2y1 := sum_x2y1 + x2 * y
endfor

C := N * sum_x2 - sum_x * sum_x
D := N * sum_xy - sum_x * sum_y
E := N * sum_x3 + N * sum_x1y2 - (sum_x2 + sum_y2) * sum_x
G := N * sum_y2 - sum_y * sum_y
H := N * sum_x2y1 + N * sum_y3 - (sum_x2 + sum_y2) * sum_y

a := (H * D - E * G) / (C * G - D * D)
b := (H * C - E * D) / (D * D - G * C)
c := -(a * sum_x + b * sum_y + sum_x2 + sum_y2) / N

Parameter[0] := a / (-2)
Parameter[1] := b / (-2)
Parameter[2] := sqrt(a * a + b * b - 4 * c) / 2

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.