I try to recreate the image transformation ( log-polar mapping) from OpenCV doc.
An I should have such output ( semilog = flase):
My code ( modified example ):
#include <opencv2/core/core.hpp>
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include <iostream>
using namespace cv;
using namespace std;
int main( int argc, char** argv )
{
//
Mat src;
Mat log_polar_img, lin_polar_img, recovered_log_polar, recovered_lin_polar_img;
Mat dst;
// image file to read
std::string name = "p"; // name of the file to read without extension
std::string path = "./"; // path to the file
std::string ext = ".png"; // extension
std::string file_in = path + name + ext;
std::cout << "file name = " << file_in << std::endl;
// read the file
src = imread(file_in, cv::IMREAD_COLOR); // CV_LOAD_IMAGE_COLOR
if (src.empty()) {// Error Handling
std::cout << "Image File " << file_in << " not found. Press any key to end. " << std::endl;
std::cin.get(); return -1; // wait for any key press
}
std::cout << "Image File " << file_in << " found and opened" << std::endl;
int flags = INTER_LINEAR + WARP_FILL_OUTLIERS;
Point2f center( (float)src.cols / 2, (float)src.rows / 2 );
double maxRadius = 0.7*min(center.y, center.x);
//double M = (float)src.cols / log(maxRadius);
//logPolar(src, log_polar_img, center, M, flags);
//linearPolar(src, lin_polar_img, center, maxRadius, flags);
//logPolar(log_polar_img, recovered_log_polar, center, M, flags + WARP_INVERSE_MAP);
//linearPolar(lin_polar_img, recovered_lin_polar_img, center, maxRadius, flags + WARP_INVERSE_MAP);
// direct transform
warpPolar(src, lin_polar_img, Size(),center, M, flags); // linear Polar
warpPolar(src, log_polar_img, Size(),center, maxRadius, flags + WARP_POLAR_LOG); // semilog Polar
// inverse transform
warpPolar(lin_polar_img, recovered_lin_polar_img, src.size(), center, maxRadius, flags + WARP_INVERSE_MAP);
warpPolar(log_polar_img, recovered_log_polar, src.size(), center, maxRadius, flags + WARP_POLAR_LOG + WARP_INVERSE_MAP);
// Below is the reverse transformation for (rho, phi)->(x, y) :
if (flags & WARP_POLAR_LOG)
dst = log_polar_img;
else
dst = lin_polar_img;
//get a point from the polar image
int rho = cvRound(dst.cols * 0.75);
int phi = cvRound(dst.rows / 2.0);
double angleRad, magnitude;
double Kangle = dst.rows / CV_2PI;
angleRad = phi / Kangle;
if (flags & WARP_POLAR_LOG)
{
double Klog = dst.cols / std::log(maxRadius);
magnitude = std::exp(rho / Klog);
}
else
{
double Klin = dst.cols / maxRadius;
magnitude = rho / Klin;
}
int x = cvRound(center.x + magnitude * cos(angleRad));
int y = cvRound(center.y + magnitude * sin(angleRad));
drawMarker(src, Point(x, y), Scalar(0, 255, 0));
drawMarker(dst, Point(rho, phi), Scalar(0, 255, 0));
// windows
namedWindow( "Src", WINDOW_AUTOSIZE );//
namedWindow( "Linear-Polar", WINDOW_AUTOSIZE );
namedWindow( "Log-Polar", WINDOW_AUTOSIZE);
namedWindow( "Recovered Linear-Polar", WINDOW_AUTOSIZE);
namedWindow( "Recovered Log-Polar", WINDOW_AUTOSIZE);
namedWindow( "Dst", WINDOW_AUTOSIZE );//
//
moveWindow( "Linear-Polar", 20,20 );
moveWindow( "Log-Polar", 700,20 );
moveWindow( "Recovered Linear-Polar", 20, 350 );
moveWindow( "Recovered Log-Polar", 700, 350 );
//
imshow("Src", src);
imshow("Log-Polar", log_polar_img);
imshow("Linear-Polar", lin_polar_img);
imshow("Recovered Linear-Polar", recovered_lin_polar_img );
imshow("Recovered Log-Polar", recovered_log_polar );
imshow("Dst", dst);
//
waitKey(0);
std::cout << "Press any key to end " << std::endl;
return 0;
}
It works, but the result is not as expected (p265.png)
How can I get the same image as in OpenCV documentation ?
Why the official example does not do what documentation says ?
===================== edit 1 ====================================
The question is about OpenCV and geometric transformation. The OpenCV has many language bindings. Below is example in python
# https://stackoverflow.com/questions/2164570/reprojecting-polar-to-cartesian-grid
# HanClinto
# https://docs.opencv.org/3.4/d2/de6/tutorial_py_setup_in_ubuntu.html
import numpy as np
import cv2
from matplotlib import pyplot as plt
# Read in our image from disk
image = cv2.imread('Q.png',0)
plt.imshow(image),plt.show()
margin = 0.9 # Cut off the outer 10% of the image
# Do the polar rotation along 1024 angular steps with a radius of 256 pixels.
polar_img = cv2.warpPolar(image, (256, 1024), (image.shape[0]/2,image.shape[1]/2), image.shape[1]*margin*0.5, cv2.WARP_POLAR_LINEAR) # WARP_POLAR_LINEAR
# Rotate it sideways to be more visually pleasing
polar_img = cv2.rotate(polar_img, cv2.ROTATE_90_COUNTERCLOCKWISE)
plt.imshow(polar_img),plt.show()