One-Dimensional Edge Measurement Using HALCON
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
rowcorresponds to the vertical (y) axis andcolumnto 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.