Reputation: 3862
I am trying to determine the transformation (rotation + translation + scale) between two images in order to shift them.
The images are taken with two different modalities that produce very different textures. So I can't use techniques based on maintaining the optical flow. I thought it would be nice to threshold the images to extract the geometries (see example below). But then I have trouble seeing what I could do...maybe extract the vertical lines and the central circle to help me extract my transformation.
I work in python, I looked at what Opencv could offer but with few success for the moment.
--- EDIT LATER ---
I detected the circle and lines with the Hough transform (see figure below). Indeed, this will help for a proper registration. However, what tool on Python can I use to register these elements? I often use optical flow conservation, but in this case it's rather complicated...
Upvotes: 5
Views: 880
Reputation: 3414
I had a very similar problem to yours, with trying to center circular objects within both CT and MR images - and went down various routes with registration, hough transforms etc etc. All sort of worked, but slow and complex and not hugely robust.
I ended up using a much simpler, more robust, and much faster approach by stepping back and thinking about it differently.
You have two circles in an an image and you want to find the location and scale.
# r/c 1/0 are variables you can use to set limits on which areas of
# the image you want to limit the search to, or you can use the entire
# image size
r0 = c0 = 0
r1, c1 = image.shape
r_prof = np.mean(image[r0:r1, :], axis=0)
c_prof = np.mean(image[:, c0:c1], axis=1)
# find_peak is a function to find the peak index in a profile
circle_r = find_peak(r_profile)
circle_c = find_peak(c_profile)
# get single pixel width profile across center of circle
r_prof = np.mean(image[circle_r, :], axis=0)
c_prof = np.mean(image[:, circle_c], axis=1)
So from that you end up with the center and diameter of the circle.
I use this approach to do what you're doing - location and size of circular profile - in both CT and MR. It's ended up being at least order magnitude faster than anything else, and much more robust.
Upvotes: 1
Reputation: 1285
Find at least 4 non-collinear corresponding points:
Then you can use findHomography to calculate the Homography matrix which is the transformation between two images.
sample code is similar to the following one:
# Read the first image.
im_fst = cv2.imread('img1.jpg')
# Four points in the first image (more is better)
pts_fst = np.array([[141, 131], [480, 159], [493, 630],[64, 601]])
# Read the second image.
im_scd = cv2.imread('img2.jpg')
# Four points in the second image
pts_scd = np.array([[318, 256],[534, 372],[316, 670],[73, 473]])
# Calculate Homography
h, status = cv2.findHomography(pts_fst, pts_scd)
# Warp source image to destination based on homography
im_out = cv2.warpPerspective(im_fst, h, (im_scd.shape[1],im_scd.shape[0]))
Upvotes: 4
Reputation:
If the pattern is always a disk inside a lane, with clean binarization, this looks like an easy problem.
You can reliably and accurately obtain the disk center and area, hence radius. From the side blobs you can find the verticals (Hough, or line fitting to the inner section of the contours, or just line through pairs of distant points).
Then you get the scale from the ratio of radii, or ratio of distances between the lines. The rotation angle is given by the direction of the verticals. And the translation by the coordinates of the center.
Actually, you have too much data to solve for the 4 DOF, and there are several possible resolutions. Depending on how exactly those images are produced, you should use the most reliable pieces of information.
Upvotes: 2