I'm trying to detect angle difference between two circular objects, which be shown as 2 image below.
I'm thinking about rotate one of image with some small angle. Every time one image rotated, SSIM between rotated image and the another image will be calculated. The angle with maximum SSIM will be the angle difference.
But, finding the extremes is never an easy problem. So my question is: Are there another algorithms (opencv) can be used is this case?
EDIT:
Thanks @Micka, I just do the same way he suggest and remove black region like @Yves Daoust said to improve processing time. Here is my final result:
ORIGINAL IMAGE
ROTATED + SHIFTED IMAGE

Here's the same idea but the correlation is done with a convolution (FFT) instead of matchTemplate. FFTs can be faster if there's much data.
Load inputs:
im1 = cv.imread("circle1.jpg", cv.IMREAD_GRAYSCALE)
im2 = cv.imread("circle2.jpg", cv.IMREAD_GRAYSCALE)
height, width = im1.shape
Polar transform (log polar as an exercise to the reader) with some arbitrary parameters that affect "resolution":
maxradius = width // 2
stripwidth = maxradius
stripheight = int(maxradius * 2 * pi) # approximately square at the radius
#stripheight = 360
def polar(im):
return cv.warpPolar(im, center=(width/2, height/2),
dsize=(stripwidth, stripheight), maxRadius=maxradius,
flags=cv.WARP_POLAR_LOG*0 + cv.INTER_LINEAR)
strip1 = polar(im1)
strip2 = polar(im2)
Convolution:
f1 = np.fft.fft2(strip1[::-1, ::-1])
f2 = np.fft.fft2(strip2)
conv = np.fft.ifft2(f1 * f2)
minmaxloc:
conv = np.real(conv) # or np.abs, can't decide
(i,j) = np.unravel_index(conv.argmax(), conv.shape)
i,j = (i+1) % stripheight, (j+1) % stripwidth
and what's that as an angle:
print("degrees:", i / stripheight * 360)
# 42.401091405184175
https://gist.github.com/crackwitz/3da91f43324b0c53504d587a394d4c71