diff --git a/modules/imgproc/src/imgwarp.cpp b/modules/imgproc/src/imgwarp.cpp index 5822726eee..a7f8eee449 100644 --- a/modules/imgproc/src/imgwarp.cpp +++ b/modules/imgproc/src/imgwarp.cpp @@ -50,6 +50,8 @@ #include "precomp.hpp" #include "opencl_kernels_imgproc.hpp" +using namespace cv; + namespace cv { #if IPP_VERSION_X100 >= 710 @@ -6475,11 +6477,13 @@ CV_IMPL void cvLogPolar( const CvArr* srcarr, CvArr* dstarr, CvPoint2D32f center, double M, int flags ) { + Mat src_with_border; // don't scope this variable (it holds image data) + cv::Ptr mapx, mapy; CvMat srcstub, *src = cvGetMat(srcarr, &srcstub); CvMat dststub, *dst = cvGetMat(dstarr, &dststub); - CvSize ssize, dsize; + CvSize dsize; if( !CV_ARE_TYPES_EQ( src, dst )) CV_Error( CV_StsUnmatchedFormats, "" ); @@ -6487,7 +6491,6 @@ cvLogPolar( const CvArr* srcarr, CvArr* dstarr, if( M <= 0 ) CV_Error( CV_StsOutOfRange, "M should be >0" ); - ssize = cvGetMatSize(src); dsize = cvGetMatSize(dst); mapx.reset(cvCreateMat( dsize.height, dsize.width, CV_32F )); @@ -6500,7 +6503,7 @@ cvLogPolar( const CvArr* srcarr, CvArr* dstarr, double* exp_tab = _exp_tab; for( rho = 0; rho < dst->width; rho++ ) - exp_tab[rho] = std::exp(rho/M); + exp_tab[rho] = std::exp(rho/M) - 1.0; for( phi = 0; phi < dsize.height; phi++ ) { @@ -6522,6 +6525,13 @@ cvLogPolar( const CvArr* srcarr, CvArr* dstarr, } else { + const int ANGLE_BORDER = 1; + Mat src_ = cv::cvarrToMat(src); + cv::copyMakeBorder(src_, src_with_border, ANGLE_BORDER, ANGLE_BORDER, 0, 0, BORDER_WRAP); + srcstub = src_with_border; src = &srcstub; + CvSize ssize = cvGetMatSize(src); + ssize.height -= 2*ANGLE_BORDER; + int x, y; CvMat bufx, bufy, bufp, bufa; double ascale = ssize.height/(2*CV_PI); @@ -6558,7 +6568,7 @@ cvLogPolar( const CvArr* srcarr, CvArr* dstarr, double phi = bufa.data.fl[x]*ascale; mx[x] = (float)rho; - my[x] = (float)phi; + my[x] = (float)phi + ANGLE_BORDER; } #else for( x = 0; x < dsize.width; x++ ) @@ -6599,11 +6609,13 @@ CV_IMPL void cvLinearPolar( const CvArr* srcarr, CvArr* dstarr, CvPoint2D32f center, double maxRadius, int flags ) { + Mat src_with_border; // don't scope this variable (it holds image data) + cv::Ptr mapx, mapy; CvMat srcstub, *src = (CvMat*)srcarr; CvMat dststub, *dst = (CvMat*)dstarr; - CvSize ssize, dsize; + CvSize dsize; src = cvGetMat( srcarr, &srcstub,0,0 ); dst = cvGetMat( dstarr, &dststub,0,0 ); @@ -6611,10 +6623,7 @@ void cvLinearPolar( const CvArr* srcarr, CvArr* dstarr, if( !CV_ARE_TYPES_EQ( src, dst )) CV_Error( CV_StsUnmatchedFormats, "" ); - ssize.width = src->cols; - ssize.height = src->rows; - dsize.width = dst->cols; - dsize.height = dst->rows; + dsize = cvGetMatSize(dst); mapx.reset(cvCreateMat( dsize.height, dsize.width, CV_32F )); mapy.reset(cvCreateMat( dsize.height, dsize.width, CV_32F )); @@ -6632,7 +6641,7 @@ void cvLinearPolar( const CvArr* srcarr, CvArr* dstarr, for( rho = 0; rho < dsize.width; rho++ ) { - double r = maxRadius*(rho+1)/dsize.width; + double r = maxRadius*rho/dsize.width; double x = r*cp + center.x; double y = r*sp + center.y; @@ -6643,6 +6652,13 @@ void cvLinearPolar( const CvArr* srcarr, CvArr* dstarr, } else { + const int ANGLE_BORDER = 1; + Mat src_ = cv::cvarrToMat(src); + cv::copyMakeBorder(src_, src_with_border, ANGLE_BORDER, ANGLE_BORDER, 0, 0, BORDER_WRAP); + srcstub = src_with_border; src = &srcstub; + CvSize ssize = cvGetMatSize(src); + ssize.height -= 2*ANGLE_BORDER; + int x, y; CvMat bufx, bufy, bufp, bufa; const double ascale = ssize.height/(2*CV_PI); @@ -6669,15 +6685,12 @@ void cvLinearPolar( const CvArr* srcarr, CvArr* dstarr, cvCartToPolar( &bufx, &bufy, &bufp, &bufa, 0 ); - for( x = 0; x < dsize.width; x++ ) - bufp.data.fl[x] += 1.f; - for( x = 0; x < dsize.width; x++ ) { double rho = bufp.data.fl[x]*pscale; double phi = bufa.data.fl[x]*ascale; mx[x] = (float)rho; - my[x] = (float)phi; + my[x] = (float)phi + ANGLE_BORDER; } } } diff --git a/modules/imgproc/test/test_imgwarp.cpp b/modules/imgproc/test/test_imgwarp.cpp index 0568cbce0a..8246754387 100644 --- a/modules/imgproc/test/test_imgwarp.cpp +++ b/modules/imgproc/test/test_imgwarp.cpp @@ -1744,4 +1744,86 @@ TEST(Imgproc_Remap, DISABLED_memleak) } } + +TEST(Imgproc_linearPolar, identity) +{ + const int N = 33; + Mat in(N, N, CV_8UC3, Scalar(255, 0, 0)); + in(cv::Rect(N/3, N/3, N/3, N/3)).setTo(Scalar::all(255)); + cv::blur(in, in, Size(5, 5)); + cv::blur(in, in, Size(5, 5)); + + Mat src = in.clone(); + Mat dst; + + Rect roi = Rect(0, 0, in.cols - ((N+19)/20), in.rows); + + for (int i = 1; i <= 5; i++) + { + linearPolar(src, dst, + Point2f((N-1) * 0.5f, (N-1) * 0.5f), N * 0.5f, + CV_WARP_FILL_OUTLIERS | CV_INTER_LINEAR | CV_WARP_INVERSE_MAP); + + linearPolar(dst, src, + Point2f((N-1) * 0.5f, (N-1) * 0.5f), N * 0.5f, + CV_WARP_FILL_OUTLIERS | CV_INTER_LINEAR); + + double psnr = cvtest::PSNR(in(roi), src(roi)); + EXPECT_LE(25, psnr) << "iteration=" << i; + } + +#if 0 + Mat all(N*2+2,N*2+2, src.type(), Scalar(0,0,255)); + in.copyTo(all(Rect(0,0,N,N))); + src.copyTo(all(Rect(0,N+1,N,N))); + src.copyTo(all(Rect(N+1,0,N,N))); + dst.copyTo(all(Rect(N+1,N+1,N,N))); + imwrite("linearPolar.png", all); + imshow("input", in); imshow("result", dst); imshow("restore", src); imshow("all", all); + cv::waitKey(); +#endif +} + + +TEST(Imgproc_logPolar, identity) +{ + const int N = 33; + Mat in(N, N, CV_8UC3, Scalar(255, 0, 0)); + in(cv::Rect(N/3, N/3, N/3, N/3)).setTo(Scalar::all(255)); + cv::blur(in, in, Size(5, 5)); + cv::blur(in, in, Size(5, 5)); + + Mat src = in.clone(); + Mat dst; + + Rect roi = Rect(0, 0, in.cols - ((N+19)/20), in.rows); + + double M = N/log(N * 0.5f); + for (int i = 1; i <= 5; i++) + { + logPolar(src, dst, + Point2f((N-1) * 0.5f, (N-1) * 0.5f), M, + CV_WARP_FILL_OUTLIERS | CV_INTER_LINEAR | CV_WARP_INVERSE_MAP); + + logPolar(dst, src, + Point2f((N-1) * 0.5f, (N-1) * 0.5f), M, + CV_WARP_FILL_OUTLIERS | CV_INTER_LINEAR); + + double psnr = cvtest::PSNR(in(roi), src(roi)); + EXPECT_LE(25, psnr) << "iteration=" << i; + } + +#if 0 + Mat all(N*2+2,N*2+2, src.type(), Scalar(0,0,255)); + in.copyTo(all(Rect(0,0,N,N))); + src.copyTo(all(Rect(0,N+1,N,N))); + src.copyTo(all(Rect(N+1,0,N,N))); + dst.copyTo(all(Rect(N+1,N+1,N,N))); + imwrite("logPolar.png", all); + imshow("input", in); imshow("result", dst); imshow("restore", src); imshow("all", all); + cv::waitKey(); +#endif +} + + /* End of file. */