DiamondLightSource / discorpy

Camera calibration with sub-pixel accuracy: https://discorpy.readthedocs.io/
https://discorpy.readthedocs.io
Apache License 2.0
56 stars 8 forks source link

Find location location of specific points in warped image corresponding in unwarped image. #6

Closed severecoder closed 1 year ago

severecoder commented 1 year ago

Hello dear authors

What is the best method to input a last of coordinates in the input image and obtain the corresponding points in the unwarped image?

nghia-vo commented 1 year ago

I answer this in issue #5 but can summarize here which may be useful for others. We have formulas to transform between the undistorted space and distorted space as shown here . Suppose that we got the coefficients of the backward model after the calibration. To get coordinates of a distorted point given undistorted point, we have to use the forward model. Transformation between two models is easily done in Discorpy using this function.

Put everything into a function:

# Define the function to calculate corresponding points between distorted and undistorted space
def find_point_to_point(points, xcenter, ycenter, list_fact):
    """
    points : (row_index, column_index) of 2D array.
    """
    xi, yi = points[1] - xcenter, points[0] - ycenter
    ri = np.sqrt(xi * xi + yi * yi)
    factor = np.float64(np.sum(list_fact * np.power(ri, np.arange(len(list_fact)))))
    xo = xcenter + factor * xi
    yo = ycenter + factor * yi
    return xo, yo

To use it:

(height, width) = img.shape
ref_points = [[i - ycenter, j - xcenter] for i in np.linspace(0, height, 40) for j in
              np.linspace(0, height, 40)]
list_ffact = proc.transform_coef_backward_and_forward(list_bfact, ref_points=ref_points)

# Find top-left point in the undistorted space given top-left point in the distorted space.
xu_top_left, yu_top_left = find_point_to_point((0, 0), xcenter, ycenter, list_ffact)
# Find bottom-right point in the undistorted space given bottom-right point in the distorted space.
xu_bot_right, yu_bot_right = find_point_to_point((height - 1, width - 1), xcenter, ycenter, list_ffact)

Thanks for asking these questions. I'll put them into a section of Discorpy's documentation for who wants to look it up later.

nghia-vo commented 1 year ago

I've add the answer to documentation https://discorpy.readthedocs.io/en/latest/usage/tips.html