Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

One-Dimensional Edge Measurement Using HALCON

Tech 2

Overview of 1D Measurement

One-dimensional measurement in HALCON refers to geometric analysis along a single direction—such as distance between two parallel edges, point-to-point separation along a line, or width estimation across a narrow region. The technique relies on defining a measurement region (ROI), sampling intensity profiles orthogonally across it, detecting edge transitions in the resulting profile, and computing subpixel-accurate edge positions.

The process begins by constructing an ROI—typically a rotated rectangle (gen_measure_rectangle2) or an annular arc (gen_measure_arc). Within this ROI, HALCON internal generates a set of equally spaced, orthogonal scan lines (profile lines) spanning the full width of the ROI. These lines are oriented perpendicular to the ROI’s primary axis, ensuring maximal sensitivity to edges aligned with that direction.

To improve robustness against noise, each scan line’s pixel intensities are averaged along its length, producing a 1D intensity profile. A Gaussian filter (controlled via the Sigma parameter) is then applied to smooth this profile before derivative-based edge detection.

Edge localization proceeds by computing the first derivative of the smoothed profile. Local extrema (peaks or troughs) exceeding a user-defined amplitude threshold (Threshold) are identified as candidate edge points. When using measure_pairs, only pairs of opposite-polarity edges (e.g., dark-to-light followed by light-to-dark) within a configurable distance range are retained. In contrast, measure_pos reports all qualifying individual edges without enforcing pairing constraints.


Core Operators

gen_measure_rectangle2
Creates a measurement object for a rotated rectangular ROI:

gen_measure_rectangle2(Row, Column, Phi, Length1, Length2, Width, Height, Interpolation, MeasureHandle)
  • Row, Column: Center coordinates of the rectangle.
  • Phi: Rotation angle (radians) of the rectangle’s major axis.
  • Length1: Half-width (perpendicular to Phi).
  • Length2: Half-height (parallel to Phi).
  • Interpolation: Resampling method ('nearest_neighbor', 'bilinear', or 'bicubic').

gen_measure_arc
Constructs an annular measurement region for circular or arc-shaped features:

gen_measure_arc(CenterRow, CenterCol, Radius, AngleStart, AngleExtent, AnnulusRadius, Width, Height, Interpolation, MeasureHandle)
  • AnnulusRadius: Radial thickness of the measurement band.

measure_pairs
Detects complementary edge pairs (e.g., rising + falling edges):

measure_pairs(Image, MeasureHandle, Sigma, Threshold, Transition, Select, 
               RowEdgeFirst, ColumnEdgeFirst, AmplitudeFirst,
               RowEdgeSecond, ColumnEdgeSecond, AmplitudeSecond,
               IntraDistance, InterDistance)
  • Transition: 'positive', 'negative', or 'all' — defines expected polarity sequence.
  • IntraDistance: Distance between the two edges in a pair.
  • InterDistance: Spacing between successive edge pairs.

measure_pos
Finds isolated edge centers without requiring pairing:

measure_pos(Image, MeasureHandle, Sigma, Threshold, Transition, Select,
            RowEdge, ColumnEdge, Amplitude, Distance)
  • Distance: Approximate spacing between adjacent detected edges (used for suppression).

translate_measure (Optional)
Repositions an existing measurement handle without regenerating it:

translate_measure(MeasureHandle, NewRow, NewColumn)

Useful when reusing the same ROI geometry at multiple locations.

Coordinate Note: HALCON uses (row, column) indexing, where row corresponds to the vertical (y) axis and column to horizontal (x). This differs from OpenCV’s (x, y) convention.


Practical Example: IC Pin Inspection

Pin Pitch Measurement

dev_close_window()
read_image(Image, 'ic_pin')
get_image_size(Image, Width, Height)
dev_open_window(0, 0, Width / 2, Height / 2, 'black', WindowHandle)
set_display_font(WindowHandle, 14, 'mono', 'true', 'false')
dev_display(Image)

* Define ROI aligned with pin rows
Row := 47
Column := 485
Phi := 0.0
Length1 := 420  // width along x
Length2 := 10   // height along y

dev_set_color('green')
dev_set_draw('margin')
dev_set_line_width(3)
gen_rectangle2(Rectangle, Row, Column, Phi, Length1, Length2)
gen_measure_rectangle2(Row, Column, Phi, Length1, Length2, Width, Height, 'nearest_neighbor', MeasureHandle)

count_seconds(Start)
measure_pairs(Image, MeasureHandle, 1.5, 30, 'negative', 'all',
              Row1, Col1, Amp1, Row2, Col2, Amp2, Widths, Distances)
count_seconds(End)
Time := End - Start

dev_set_color('red')
disp_line(WindowHandle, Row1, Col1, Row2, Col2)

AvgWidth := sum(Widths) / |Widths|
AvgPitch := sum(Distances) / |Distances|
NumPins := |Widths|

dev_set_color('yellow')
disp_message(WindowHandle, 'Pins: ' + NumPins, 'image', 200, 100, 'yellow', 'false')
disp_message(WindowHandle, 'Avg Width: ' + AvgWidth$'.2f', 'image', 260, 100, 'yellow', 'false')
disp_message(WindowHandle, 'Avg Pitch: ' + AvgPitch$'.2f', 'image', 320, 100, 'yellow', 'false')

Pin Height Estimation

* Rotate ROI 90° to span pin heights
Row := 508
Column := 200
Phi := -1.5708  // ≈ -π/2
Length1 := 482  // vertical extent
Length2 := 35   // horizontal width

gen_rectangle2(Rectangle, Row, Column, Phi, Length1, Length2)
gen_measure_rectangle2(Row, Column, Phi, Length1, Length2, Width, Height, 'nearest_neighbor', MeasureHandle)

measure_pos(Image, MeasureHandle, 1.5, 30, 'all', 'all', RowEdges, ColEdges, Amps, Spacings)

* Compute height from top/bottom edge pairs
Height1 := RowEdges[1] - RowEdges[0]
Height2 := RowEdges[3] - RowEdges[2]

dev_set_color('red')
disp_line(WindowHandle, RowEdges, ColEdges - Length2, RowEdges, ColEdges + Length2)

disp_message(WindowHandle, 'Height 1: ' + Height1$'.2f', 'image', RowEdges[1] + 40, ColEdges[1] + 100, 'yellow', 'false')
disp_message(WindowHandle, 'Height 2: ' + Height2$'.2f', 'image', RowEdges[3] - 120, ColEdges[3] + 100, 'yellow', 'false')

In both cases, RowEdges and ColEdges contain subpixel-accurate coordinates of detected edge centers. For height estimation, vertical distances between paired edges yield physical dimensions—provided calibration parameters are applied.

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.