My problem is that I have a line (red on the left), and I want to transform it to get something like on the right picture. (This is a binarized image, so everything is black, except the (red) line here which is white on the picture.) The black dot simbolizes the center of the gray circle. So it is obvious, that the points of the red line can not fit to the edge of 1 circle, but exist 2 circles with r1, r2 (radius) which together create a ring and its surface(gray on the picture) can contain all of the points of the red line. For different pictures r1 and r2 can be different, but it is guaranteed that r2>r1>0.
So I need a mapping, which can transform the points(x,y) (numpy matrix) of the red line from the gray ring to a rectangle. "Without formulas" I would imagine this like cutting somewhere the ring, and folding it into a rectangle.
CodePudding user response:
As astutely pointed out by @fmw42, you can use cv2.warpPolar
. Here's an example.
import math
import cv2
ring = cv2.imread("so71416458-crop.png")
size = ring.shape[0] # assumes square image
outer_radius = size // 2
inner_radius_factor = 0.7 # 0.70 measured empirically from image
# Unwarp ring
warped = cv2.warpPolar(ring, (size, int(size * math.pi)), (outer_radius, outer_radius), outer_radius, 0)
# Rotate 90 degrees
straightened = cv2.rotate(warped, cv2.ROTATE_90_COUNTERCLOCKWISE)
# Crop to ring only
cropped = straightened[: int(straightened.shape[0] * (1 - inner_radius_factor)), :]
cv2.imwrite("so71416458-straight.png", cropped)
input: so71416458-crop.png
The "wobble" evident in here is a result of my sloppy cropping – the center point of the ring isn't exactly at the midpoint of the image.