Chris
Chris

Reputation: 21

Fitting Honeycomb Template to Grid of Detected Honeycomb Points (Different Number of Points in Each)

Here is some setup for my problem. I am dealing with greyscale images from a pinhole camera. The pinholes are in a honeycomb pattern that can have a rotation, scale, and translation but by small amounts. Right now, I am detecting the centers of just the pinholes on the right ~1/3 of the image. I get almost all the centers and while they are not all exactly right in the center of the pinhole, they are all within the pinhole just maybe some are slightly off from the exact center. The next step is I make a pre-defined honeycomb grid template. This template uses the max range in x and y (pinholes) to cover the detected pinhole centers from the previous step. It also uses the actual horizontal and vertical spacing of the pinholes and this is obtained from the camera itself. So, since the actual image plate is a honeycomb grid of pinholes, this pre-defined pinhole template made using the same spacing should fit on top of it. This would allow me to look into each pinhole. My goal is to take this template and find the similarity transform (rotation, scale, translation_x, translation_y) needed to align it with my detected pinhole centers.

def mahalanobis_distance_matrix(template, found):
    cov_matrix = np.cov(found.T)  # Shape (2,2)
    
    # Invert covariance matrix
    inv_cov_matrix = np.linalg.inv(cov_matrix)
    
    # Compute Mahalanobis distances efficiently
    diff = template[:, None, :] - found[None, :, :]  # Shape (N, M, 2)
    cost_matrix = np.einsum('nmk,kk,nmk->nm', diff, inv_cov_matrix, diff)  # Vectorized Mahalanobis distance
    
    return np.sqrt(cost_matrix)  # Take the square root for final distance
    
    # return cost_matrix
    
def hungarian_matching_cost(params, template, found):
    
    transformed_template = transform_points(template, params)
    
    # Compute pairwise distance matrix
    # cost_matrix = np.linalg.norm(transformed_template[:, None, :] - found[None, :, :], axis=2)
    cost_matrix = mahalanobis_distance_matrix(transformed_template, found)
    
    # Solve optimal assignment problem
    row_ind, col_ind = linear_sum_assignment(cost_matrix)
    
    # return np.sum(cost_matrix[row_ind, col_ind] ** 2)  # Sum of squared distances
    return np.median(cost_matrix[row_ind,col_ind]**2)

My MAIN issue right now seems to be the cost function as this guides the fitting. I just cannot find the minimum that will align the points. After the optimizer finishes, the aligned template sort of fits the detected pinhole centers but only in local regions. There are few places where the template lines up perfectly, but as you move outwards from that region the points don't align. If anyone has ideas or info regarding better cost functions, maybe for periodic grid data, that would be greatly appreciated. Thank you!

Upvotes: 2

Views: 17

Answers (0)

Related Questions