Reputation: 53
First of all, I'm sorry I can not speak English well.
I ask for your understanding even if there are some awkward parts of my words.
I am a beginner to get into Opencv.
I want to translate a picture of a horizontal line into a picture of a circle.
I tried to recommend linearPolar, logPolar, and warpPolar in several articles, but I did not get the desired result.
Result Image:
Here is the image I want to put and the desired result.
Input Image:
Output Image:
What function should I use to get this result?
If you have any examples or explanations for reference, please let me know.
If you let me know just the keywords, I will search Google and this site hard.
Thank you for reading my question.
Upvotes: 5
Views: 1678
Reputation: 51867
Peter's answer is great (+1).
I had a play with it and just wanted to post a Python version of his approach with some sliders:
#!/usr/bin/env python
import numpy as np
import cv2
# main window
WINDOW_NAME = "carToPol"
cv2.namedWindow(WINDOW_NAME)
# read input
src = cv2.imread("iPpzR.png")
# get dimenions and compute half (for center/radius)
dims = src.shape[:-1]
cols,rows = dims
half = cols // 2
def carToPol(src,center,maxRadius,interpolation,rotate90=True):
# rotate 90 degrees (cv2.warpAffine seems to mess up a column)
if(rotate90):
src = np.rot90(src)
# cartesian to polar (WARP_INVERSE_MAP)
return cv2.linearPolar(src,(centerX,centerY),maxRadius,interpolation + cv2.WARP_FILL_OUTLIERS + cv2.WARP_INVERSE_MAP)
# interpolation names: just for debugging
interpolations = ["NEAREST","LINEAR","CUBIC","AREA","LANCZOS4"]
# slider callbacks: just for debugging
def printCenterX(x):
print("center",x)
def printCenterY(x):
print("centerY",x)
def printMaxRadius(x):
print("maxRadius",x)
def printInterpolation(x):
global interpolations
print("interpolation",interpolations[x])
# create sliders
cv2.createTrackbar("centerX" ,WINDOW_NAME,half,cols,printCenterX)
cv2.createTrackbar("centerY" ,WINDOW_NAME,half,cols,printCenterY)
cv2.createTrackbar("maxRadius",WINDOW_NAME,half,cols * 4,printMaxRadius)
cv2.createTrackbar("interpolation",WINDOW_NAME,cv2.INTER_CUBIC,cv2.INTER_LANCZOS4,printInterpolation)
# continously process for quick feedback
while 1:
# exit on ESC key
k = cv2.waitKey(1) & 0xFF
if k == 27:
break
# read slider values
centerX = cv2.getTrackbarPos("centerX",WINDOW_NAME)
centerY = cv2.getTrackbarPos("centerY",WINDOW_NAME)
maxRadius = cv2.getTrackbarPos("maxRadius",WINDOW_NAME)
interpolation = cv2.getTrackbarPos("interpolation",WINDOW_NAME)
dst = carToPol(src,(centerX,centerY),maxRadius,interpolation,True)
# show result
cv2.imshow(WINDOW_NAME,dst)
# save image with 's' key
if k == ord('s'):
cv2.imwrite("output.png",dst)
# exit
cv2.destroyAllWindows()
Upvotes: 3
Reputation: 8284
linearPolar
or warpPolar
are exactly what you are looking for
You just need to pass it the WARP_INVERSE_MAP
flag to make it transform the direction you're looking for.
modified example from samples/cpp/polar_transforms.cpp
Would be something like this:
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
int main(int argc, const char** argv)
{
using namespace cv;
using namespace std;
int flags = INTER_LINEAR + WARP_FILL_OUTLIERS;
Mat src = imread(R"(C:\temp\IPpzR.png)");
Mat lin_polar_img;
rotate(src, lin_polar_img, cv::ROTATE_90_COUNTERCLOCKWISE);
imshow("Loaded",src);
Mat recovered_lin_polar_img;
Point2f center( (float)src.cols / 2, (float)src.rows / 2 );
double maxRadius = min(center.y, center.x);
cv::linearPolar(lin_polar_img, recovered_lin_polar_img, center, maxRadius, flags + WARP_INVERSE_MAP);
cv::imshow("Modified",recovered_lin_polar_img);
cv::waitKey();
return 0;
}
which gives the following result:
Upvotes: 6