My objective is to convert a 2D power spectrum (below) from cartesian to polar coordinates.
imshow(np.log10(psd2shift),cmap=cm.jet)
There are several posts on stackoverflow on how to do just that such as this link. And so I believe my code is right.
ro,col=psd2shift.shape
cent=(int(ro/2),int(col/2))
max_radius = int(np.sqrt(ro**2+col**2)/2)
polar=cv.linearPolar(np.log10(psd2shift),cent,max_radius,cv.WARP_FILL_OUTLIERS)
plt.imshow(polar,cmap=cm.jet, interpolation='bicubic')
Nonetheless I am not getting what I want which is this:
Obviously there is a difference in the transformation that I have not been able to uncover despite digging into the help of linearPolar function or the documentation here. It almost seems that the center is not defined right, but I am pretty sure it is.Thoughts?
With help(cv.linearPolar)
Returns:
Help on built-in function linearPolar:
linearPolar(...)
linearPolar(src, center, maxRadius, flags[, dst]) -> dst
. @brief Remaps an image to polar coordinates space.
.
. @anchor polar_remaps_reference_image
. 
.
. Transform the source image using the following transformation:
. \f[\begin{array}{l}
. dst( \rho , \phi ) = src(x,y) \\
. dst.size() \leftarrow src.size()
. \end{array}\f]
.
. where
. \f[\begin{array}{l}
. I = (dx,dy) = (x - center.x,y - center.y) \\
. \rho = Kx \cdot \texttt{magnitude} (I) ,\\
. \phi = Ky \cdot \texttt{angle} (I)_{0..360 deg}
. \end{array}\f]
.
. and
. \f[\begin{array}{l}
. Kx = src.cols / maxRadius \\
. Ky = src.rows / 360
. \end{array}\f]
.
.
. @param src Source image
. @param dst Destination image. It will have same size and type as src.
. @param center The transformation center;
. @param maxRadius The radius of the bounding circle to transform. It determines the inverse magnitude scale parameter too.
. @param flags A combination of interpolation methods, see cv::InterpolationFlags
.
. @note
. - The function can not operate in-place.
. - To calculate magnitude and angle in degrees @ref cv::cartToPolar is used internally thus angles are measured from 0 to 360 with accuracy about 0.3 degrees.
My first impression is that you might have messed up the center's coordinates. Points in OpenCV are refered as (x,y)
which is confusingly translated to (col, row)
. Swapping those in your code
ro,col=img.shape
cent=(int(col/2),int(ro/2))
max_radius = int(np.sqrt(ro**2+col**2)/2)
polar=cv2.linearPolar(img,cent,max_radius,cv2.WARP_FILL_OUTLIERS)
plt.figure(figsize=(16,10))
plt.imshow(polar,cmap='jet', interpolation='bicubic')
plt.show()
I get the image, which I think is close to what you want.