Implementing Geometric Affine Transformations in Halcon
Geometric Transformations
Geometric transformations involve converting digital maps or images between coordinate systems using control points and transformation equations. These operations work with:
- Vectors (digital maps): Reprojection process
- Raster (images): Resampling process
Transformation accuracy is measured using RMS (Root Mean Square Error), which quantifies the offset between actual and estimated control point positions.
Affine Transformation Matrices
# Load image and get dimensions
image = read_image('printer_chip/printer_chip_01')
width, height = get_image_size(image)
# Create identity matrix
identity_matrix = create_hom_mat2d_identity()
# Translation
translation_matrix = hom_mat2d_translate(identity_matrix, height/2, width/2)
# Rotation (90 degrees)
rotation_matrix = hom_mat2d_rotate(identity_matrix, math.radians(90), height/2, width/2)
rotated_image = rotate_image(image, 90, interpolation='constant')
# Mirroring
mirrored_image = mirror_image(rotated_image, axis='horizontal')
# Scaling (50%)
scale_matrix = hom_mat2d_scale(identity_matrix, 0.5, 0.5, 0, 0)
scaled_image = affine_trans_image(image, scale_matrix, interpolation='constant', adapt_size=True)
zoomed_image = zoom_image_factor(image, 0.5, 0.5, interpolation='constant')
# Shearing (45 degrees along X-axis)
shear_matrix = hom_mat2d_slant(identity_matrix, math.radians(45), 'x', height/2, width/2)
Nine-Point Calibration
This addresses discrepancies between camera and robot coordinate systems:
- Difefrent origins (tarnslation)
- Insatllation angles (rotation)
- Coordinate mapping (scaling)
- Non-orthogonal axes (shearing)
| Operator | Input | Output | Common Name |
|---|---|---|---|
vector_to_hom_mat2d |
Image coordinates (Px,Py) and robot coordinates (Qx,Qy) | Transformation matrix including translation, rotation, scaling, shearing | Nine-point calibration (image to world coordinate mapping) |
vector_angle_to_rigid |
Point + angle (before/after) | Transformation matrix with translation and rotation | Rigid transformation (within image coordinates) |
Practical Application Example
# Initialize window and load calibration image
window = create_window(0, 0, 512, 512)
calibration_image = read_image('cali/grid_space.cal.k.003')
# Threshold and find circular regions
thresholded = threshold(calibration_image, 0, 100)
connected = connection(thresholded)
circular_regions = select_shape(connected, 'circularity', 0.5139, 1)
large_regions = select_shape(circular_regions, 'area', 150, 99999)
# Align circular points
combined_region = union1(large_regions)
_, center_row, center_col, angle, _, _ = smallest_rectangle2(combined_region)
# Get transformation matrix
transform_matrix = vector_angle_to_rigid(center_row, center_col, angle,
center_row, center_col, 0)
# Apply transformation to region
transformed_region = affine_trans_region(combined_region, transform_matrix,
interpolation='nearest_neighbor')
# Process transformed regions
connected_regions = connection(transformed_region)
sorted_regions = sort_region(connected_regions, 'character', True, 'row')
# Create and display sequence
numbers = range(1, 50)
display_message(window, numbers, 'image', positions=get_region_centers(sorted_regions))
# Inverse transformation
inverse_matrix = hom_mat2d_invert(transform_matrix)
# Generate grid coordinates
grid_rows = []
grid_cols = []
for r in range(7):
for c in range(7):
grid_rows.append(100 + r * 70)
grid_cols.append(100 + c * 70)
# Calculate full transformation
full_transform = vector_to_hom_mat2d(get_region_centers(sorted_regions)[0],
get_region_centers(sorted_regions)[1],
grid_rows, grid_cols)
# Apply final transformation
final_image = affine_trans_image(calibration_image, full_transform,
interpolation='constant', adapt_size=False)