I’ve got this geometric shape that I simply want to rotate to be aligned vertically.
I can’t find information online on how to do this, how would you proceed ?
I’ve got this geometric shape that I simply want to rotate to be aligned vertically.
I can’t find information online on how to do this, how would you proceed ?
see
change the line
as
thresh = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)[1]
result
Given an image processing problem like that, I think of two approaches to try. I’m rusty on OpenCV, so I’ll describe what I’d do in more general terms.
Blur the image with a small radius, about 2 to 4 pixels. Then compute gradient vectors everywhere in the image. With broad black or white areas, they’re zero. Ignore any gradients smaller than some threshold. The bigger ones - make a histogram of directions. Magnitudes don’t matter (aside from the thresholding). There will be strong peaks in that histogram. Those correspond to angles of sides of the shapes in the mask. From the exact locations of the peaks, create a rotation matrix.
Fourier transform the image. Power spectrum, just the magnitudes (squared) of the amplitudes. There may be features, blobs, dark lines, or something that can be identified and measured. Rotation of the image equals rotation of the Fourier power spectrum.
Thanks everyone for the answers, I’ve found an iterative approach that kind of works for this exemple:
def align_vertically(src, mask):
# img must be grayscale 2D numpy array
img = cv2.cvtColor(mask, cv2.COLOR_BGR2GRAY)
degree = []
to_max = []
step = 1
init_black_col = img.shape[1] - np.count_nonzero(img.sum(axis = 0))
# rotating positive or negative ?
rot_pos_black_col = img.shape[1] - np.count_nonzero(imutils.rotate(img, 1).sum(axis = 0))
if rot_pos_black_col > init_black_col:
# positive rotation
for deg in range(0,91,step):
black_col = img.shape[1] - np.count_nonzero(imutils.rotate(img, deg).sum(axis = 0))
degree.append(deg)
to_max.append(black_col)
else:
# negative rotation
for deg in range(0,-91,-step):
black_col = img.shape[1] - np.count_nonzero(imutils.rotate(img, deg).sum(axis = 0))
degree.append(deg)
to_max.append(black_col)
max_value = max(to_max)
max_index = to_max.index(max_value)
rot_degree = degree[max_index]
mask = imutils.rotate(mask, rot_degree)
src = imutils.rotate(src, rot_degree)
return src, mask
Where src is the source file and mask the black and white binary mask.