1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-29 15:23:05 +04:00

Merge pull request #26914 from shyama7004:log/linearPolar

Removal of deprecated functions in imgproc #26914
 
Fixes : #26410

### Pull Request Readiness Checklist

See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request

- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [x] The PR is proposed to the proper branch
- [x] There is a reference to the original bug report and related work
- [ ] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
      Patch to opencv_extra has the same branch name.
- [ ] The feature is well documented and sample code can be built with the project CMake
This commit is contained in:
Skreg
2025-02-18 16:33:45 +05:30
committed by GitHub
parent b605fc13d8
commit 4d15b2a33f
7 changed files with 6 additions and 532 deletions
+1 -97
View File
@@ -268,12 +268,7 @@ enum InterpolationFlags{
/** flag, fills all of the destination image pixels. If some of them correspond to outliers in the
source image, they are set to zero */
WARP_FILL_OUTLIERS = 8,
/** flag, inverse transformation
For example, #linearPolar or #logPolar transforms:
- flag is __not__ set: \f$dst( \rho , \phi ) = src(x,y)\f$
- flag is set: \f$dst(x,y) = src( \rho , \phi )\f$
*/
/** flag, inverse transformation */
WARP_INVERSE_MAP = 16,
WARP_RELATIVE_MAP = 32
};
@@ -2710,97 +2705,6 @@ source image. The center must be inside the image.
CV_EXPORTS_W void getRectSubPix( InputArray image, Size patchSize,
Point2f center, OutputArray patch, int patchType = -1 );
/** @example samples/cpp/snippets/polar_transforms.cpp
An example using the cv::linearPolar and cv::logPolar operations
*/
/** @example samples/python/snippets/logpolar.py
An example using the linearPolar and logPolar operations in python
*/
/** @brief Remaps an image to semilog-polar coordinates space.
@deprecated This function produces same result as cv::warpPolar(src, dst, src.size(), center, maxRadius, flags+WARP_POLAR_LOG);
@internal
Transform the source image using the following transformation (See @ref polar_remaps_reference_image "Polar remaps reference image d)"):
\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 = M \cdot log_e(\texttt{magnitude} (I)) ,\\
\phi = Kangle \cdot \texttt{angle} (I) \\
\end{array}\f]
and
\f[\begin{array}{l}
M = src.cols / log_e(maxRadius) \\
Kangle = src.rows / 2\Pi \\
\end{array}\f]
The function emulates the human "foveal" vision and can be used for fast scale and
rotation-invariant template matching, for object tracking and so forth.
@param src Source image
@param dst Destination image. It will have same size and type as src.
@param center The transformation center; where the output precision is maximal
@param M Magnitude scale parameter. It determines the radius of the bounding circle to transform too.
@param flags A combination of interpolation methods, see #InterpolationFlags
@note
- The function can not operate in-place.
- To calculate magnitude and angle in degrees #cartToPolar is used internally thus angles are measured from 0 to 360 with accuracy about 0.3 degrees.
@sa cv::linearPolar
@endinternal
*/
CV_EXPORTS_W void logPolar( InputArray src, OutputArray dst,
Point2f center, double M, int flags );
/** @brief Remaps an image to polar coordinates space.
@deprecated This function produces same result as cv::warpPolar(src, dst, src.size(), center, maxRadius, flags)
@internal
Transform the source image using the following transformation (See @ref polar_remaps_reference_image "Polar remaps reference image c)"):
\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 = Kmag \cdot \texttt{magnitude} (I) ,\\
\phi = angle \cdot \texttt{angle} (I)
\end{array}\f]
and
\f[\begin{array}{l}
Kx = src.cols / maxRadius \\
Ky = src.rows / 2\Pi
\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 #InterpolationFlags
@note
- The function can not operate in-place.
- To calculate magnitude and angle in degrees #cartToPolar is used internally thus angles are measured from 0 to 360 with accuracy about 0.3 degrees.
@sa cv::logPolar
@endinternal
*/
CV_EXPORTS_W void linearPolar( InputArray src, OutputArray dst,
Point2f center, double maxRadius, int flags );
/** \brief Remaps an image to polar or semilog-polar coordinates space
@anchor polar_remaps_reference_image
-158
View File
@@ -1432,150 +1432,6 @@ static bool ocl_remap(InputArray _src, OutputArray _dst, InputArray _map1, Input
return k.run(2, globalThreads, NULL, false);
}
#if 0
/**
@deprecated with old version of cv::linearPolar
*/
static bool ocl_linearPolar(InputArray _src, OutputArray _dst,
Point2f center, double maxRadius, int flags)
{
UMat src_with_border; // don't scope this variable (it holds image data)
UMat mapx, mapy, r, cp_sp;
UMat src = _src.getUMat();
_dst.create(src.size(), src.type());
Size dsize = src.size();
r.create(Size(1, dsize.width), CV_32F);
cp_sp.create(Size(1, dsize.height), CV_32FC2);
mapx.create(dsize, CV_32F);
mapy.create(dsize, CV_32F);
size_t w = dsize.width;
size_t h = dsize.height;
String buildOptions;
unsigned mem_size = 32;
if (flags & cv::WARP_INVERSE_MAP)
{
buildOptions = "-D InverseMap";
}
else
{
buildOptions = format("-D ForwardMap -D MEM_SIZE=%d", mem_size);
}
String retval;
ocl::Program p(ocl::imgproc::linearPolar_oclsrc, buildOptions, retval);
ocl::Kernel k("linearPolar", p);
ocl::KernelArg ocl_mapx = ocl::KernelArg::PtrReadWrite(mapx), ocl_mapy = ocl::KernelArg::PtrReadWrite(mapy);
ocl::KernelArg ocl_cp_sp = ocl::KernelArg::PtrReadWrite(cp_sp);
ocl::KernelArg ocl_r = ocl::KernelArg::PtrReadWrite(r);
if (!(flags & cv::WARP_INVERSE_MAP))
{
ocl::Kernel computeAngleRadius_Kernel("computeAngleRadius", p);
float PI2_height = (float) CV_2PI / dsize.height;
float maxRadius_width = (float) maxRadius / dsize.width;
computeAngleRadius_Kernel.args(ocl_cp_sp, ocl_r, maxRadius_width, PI2_height, (unsigned)dsize.width, (unsigned)dsize.height);
size_t max_dim = max(h, w);
computeAngleRadius_Kernel.run(1, &max_dim, NULL, false);
k.args(ocl_mapx, ocl_mapy, ocl_cp_sp, ocl_r, center.x, center.y, (unsigned)dsize.width, (unsigned)dsize.height);
}
else
{
const int ANGLE_BORDER = 1;
cv::copyMakeBorder(src, src_with_border, ANGLE_BORDER, ANGLE_BORDER, 0, 0, BORDER_WRAP);
src = src_with_border;
Size ssize = src_with_border.size();
ssize.height -= 2 * ANGLE_BORDER;
float ascale = ssize.height / ((float)CV_2PI);
float pscale = ssize.width / ((float) maxRadius);
k.args(ocl_mapx, ocl_mapy, ascale, pscale, center.x, center.y, ANGLE_BORDER, (unsigned)dsize.width, (unsigned)dsize.height);
}
size_t globalThreads[2] = { (size_t)dsize.width , (size_t)dsize.height };
size_t localThreads[2] = { mem_size , mem_size };
k.run(2, globalThreads, localThreads, false);
remap(src, _dst, mapx, mapy, flags & cv::INTER_MAX, (flags & cv::WARP_FILL_OUTLIERS) ? cv::BORDER_CONSTANT : cv::BORDER_TRANSPARENT);
return true;
}
static bool ocl_logPolar(InputArray _src, OutputArray _dst,
Point2f center, double M, int flags)
{
if (M <= 0)
CV_Error(cv::Error::StsOutOfRange, "M should be >0");
UMat src_with_border; // don't scope this variable (it holds image data)
UMat mapx, mapy, r, cp_sp;
UMat src = _src.getUMat();
_dst.create(src.size(), src.type());
Size dsize = src.size();
r.create(Size(1, dsize.width), CV_32F);
cp_sp.create(Size(1, dsize.height), CV_32FC2);
mapx.create(dsize, CV_32F);
mapy.create(dsize, CV_32F);
size_t w = dsize.width;
size_t h = dsize.height;
String buildOptions;
unsigned mem_size = 32;
if (flags & cv::WARP_INVERSE_MAP)
{
buildOptions = "-D InverseMap";
}
else
{
buildOptions = format("-D ForwardMap -D MEM_SIZE=%d", mem_size);
}
String retval;
ocl::Program p(ocl::imgproc::logPolar_oclsrc, buildOptions, retval);
//ocl::Program p(ocl::imgproc::my_linearPolar_oclsrc, buildOptions, retval);
//printf("%s\n", retval);
ocl::Kernel k("logPolar", p);
ocl::KernelArg ocl_mapx = ocl::KernelArg::PtrReadWrite(mapx), ocl_mapy = ocl::KernelArg::PtrReadWrite(mapy);
ocl::KernelArg ocl_cp_sp = ocl::KernelArg::PtrReadWrite(cp_sp);
ocl::KernelArg ocl_r = ocl::KernelArg::PtrReadWrite(r);
if (!(flags & cv::WARP_INVERSE_MAP))
{
ocl::Kernel computeAngleRadius_Kernel("computeAngleRadius", p);
float PI2_height = (float) CV_2PI / dsize.height;
computeAngleRadius_Kernel.args(ocl_cp_sp, ocl_r, (float)M, PI2_height, (unsigned)dsize.width, (unsigned)dsize.height);
size_t max_dim = max(h, w);
computeAngleRadius_Kernel.run(1, &max_dim, NULL, false);
k.args(ocl_mapx, ocl_mapy, ocl_cp_sp, ocl_r, center.x, center.y, (unsigned)dsize.width, (unsigned)dsize.height);
}
else
{
const int ANGLE_BORDER = 1;
cv::copyMakeBorder(src, src_with_border, ANGLE_BORDER, ANGLE_BORDER, 0, 0, BORDER_WRAP);
src = src_with_border;
Size ssize = src_with_border.size();
ssize.height -= 2 * ANGLE_BORDER;
float ascale = ssize.height / ((float)CV_2PI);
k.args(ocl_mapx, ocl_mapy, ascale, (float)M, center.x, center.y, ANGLE_BORDER, (unsigned)dsize.width, (unsigned)dsize.height);
}
size_t globalThreads[2] = { (size_t)dsize.width , (size_t)dsize.height };
size_t localThreads[2] = { mem_size , mem_size };
k.run(2, globalThreads, localThreads, false);
remap(src, _dst, mapx, mapy, flags & cv::INTER_MAX, (flags & cv::WARP_FILL_OUTLIERS) ? cv::BORDER_CONSTANT : cv::BORDER_TRANSPARENT);
return true;
}
#endif
#endif
#if defined HAVE_IPP && !IPP_DISABLE_REMAP
@@ -3975,18 +3831,4 @@ void cv::warpPolar(InputArray _src, OutputArray _dst, Size dsize,
}
}
void cv::linearPolar( InputArray _src, OutputArray _dst,
Point2f center, double maxRadius, int flags )
{
warpPolar(_src, _dst, _src.size(), center, maxRadius, flags & ~WARP_POLAR_LOG);
}
void cv::logPolar( InputArray _src, OutputArray _dst,
Point2f center, double maxRadius, int flags )
{
Size ssize = _src.size();
double M = maxRadius > 0 ? std::exp(ssize.width / maxRadius) : 1;
warpPolar(_src, _dst, ssize, center, M, flags | WARP_POLAR_LOG);
}
/* End of file. */
-69
View File
@@ -1,69 +0,0 @@
#define CV_2PI 6.283185307179586476925286766559
#ifdef ForwardMap
__kernel void computeAngleRadius(__global float2* cp_sp, __global float* r, float maxRadius_width, float PI2_height, unsigned width, unsigned height)
{
unsigned gid = get_global_id(0);
if (gid < height)
{
float angle = gid * PI2_height;
float2 angle_tri=(float2)(cos(angle), sin(angle));
cp_sp[gid] = angle_tri;
}
if (gid < width)
{
r[gid] = maxRadius_width*gid;
}
}
__kernel void linearPolar(__global float* mx, __global float* my, __global float2* cp_sp, __global float* r, float cx, float cy, unsigned width, unsigned height)
{
__local float l_r[MEM_SIZE];
__local float2 l_double[MEM_SIZE];
unsigned rho = get_global_id(0);
unsigned phi = get_global_id(1);
unsigned local_0 = get_local_id(0);
unsigned local_1 = get_local_id(1);
if (local_1 == 0)
{
unsigned temp_phi=phi + local_0;
if (temp_phi < height)
{
l_double[local_0] = cp_sp[temp_phi];
}
}
if (local_1 == 1 )
{
if (rho < width)
{
l_r[local_0 ] = r[rho];
}
}
barrier(CLK_LOCAL_MEM_FENCE);
if (rho<width && phi<height)
{
unsigned g_id = rho + phi*width;
float radius = l_r[local_0];
float2 tri= l_double[local_1];
mx[g_id] = fma(radius, tri.x , cx);
my[g_id] = fma(radius, tri.y , cy);
}
}
#elif defined (InverseMap)
__kernel void linearPolar(__global float* mx, __global float* my, float ascale, float pscale, float cx, float cy, int angle_border, unsigned width, unsigned height)
{
const int x = get_global_id(0);
const int y = get_global_id(1);
if (x < width && y < height)
{
unsigned g_id = x + y*width;
float dx = (float)x - cx;
float dy = (float)y - cy;
float mag = sqrt(dx*dx + dy*dy);
float angle = atan2(dy, dx);
if (angle < 0)
angle = angle + CV_2PI;
mx[g_id] = mag*pscale;
my[g_id] = (angle*ascale) + angle_border;
}
}
#endif
-69
View File
@@ -1,69 +0,0 @@
#define CV_2PI 6.283185307179586476925286766559
#ifdef ForwardMap
__kernel void computeAngleRadius(__global float2* cp_sp, __global float* r, float m, float PI2_height, unsigned width, unsigned height)
{
unsigned gid = get_global_id(0);
if (gid < height)
{
float angle = gid * PI2_height;
float2 angle_tri = (float2)(cos(angle), sin(angle));
cp_sp[gid] = angle_tri;
}
if (gid < width)
{
r[gid] = exp(gid/m)-1.0f;
}
}
__kernel void logPolar(__global float* mx, __global float* my, __global float2* cp_sp, __global float* r, float cx, float cy, unsigned width, unsigned height)
{
__local float l_r[MEM_SIZE];
__local float2 l_double[MEM_SIZE];
unsigned rho = get_global_id(0);
unsigned phi = get_global_id(1);
unsigned local_0 = get_local_id(0);
unsigned local_1 = get_local_id(1);
if (local_1 == 0)
{
unsigned temp_phi = phi + local_0;
if (temp_phi < height)
{
l_double[local_0] = cp_sp[temp_phi];
}
}
if (local_1 == 1)
{
if (rho < width)
{
l_r[local_0] = r[rho];
}
}
barrier(CLK_LOCAL_MEM_FENCE);
if (rho<width && phi<height)
{
unsigned g_id = rho + phi*width;
float radius = l_r[local_0];
float2 tri = l_double[local_1];
mx[g_id] = fma(radius, tri.x , cx);
my[g_id] = fma(radius, tri.y, cy);
}
}
#elif defined (InverseMap)
__kernel void logPolar(__global float* mx, __global float* my, float ascale, float m, float cx, float cy, int angle_border, unsigned width, unsigned height)
{
const int x = get_global_id(0);
const int y = get_global_id(1);
if (x < width && y < height)
{
unsigned g_id = x + y*width;
float dx = (float)x - cx;
float dy = (float)y - cy;
float mag = log(sqrt(dx*dx + dy*dy)+1.0f);
float angle = atan2(dy, dx);
if (angle < 0)
angle = angle + CV_2PI;
mx[g_id] = mag*m;
my[g_id] = (angle*ascale) + angle_border;
}
}
#endif
-81
View File
@@ -1034,87 +1034,6 @@ TEST(Imgproc_Remap, DISABLED_memleak)
}
}
//** @deprecated */
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
}
//** @deprecated */
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,
WARP_FILL_OUTLIERS | INTER_LINEAR | WARP_INVERSE_MAP);
logPolar(dst, src,
Point2f((N-1) * 0.5f, (N-1) * 0.5f), M,
WARP_FILL_OUTLIERS | 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
}
TEST(Imgproc_warpPolar, identity)
{
const int N = 33;
+5 -13
View File
@@ -11,7 +11,7 @@ int main( int argc, char** argv )
Mat log_polar_img, lin_polar_img, recovered_log_polar, recovered_lin_polar_img;
CommandLineParser parser(argc, argv, "{@input|0| camera device number or video file path}");
parser.about("\nThis program illustrates usage of Linear-Polar and Log-Polar image transforms\n");
parser.about("\nThis program illustrates usage of warpPolar for both linear and log-polar transforms.\n");
parser.printMessage();
std::string arg = parser.get<std::string>("@input");
@@ -47,18 +47,10 @@ int main( int argc, char** argv )
Point2f center( (float)src.cols / 2, (float)src.rows / 2 );
double maxRadius = 0.7*min(center.y, center.x);
#if 0 //deprecated
double M = frame.cols / log(maxRadius);
logPolar(frame, log_polar_img, center, M, flags);
linearPolar(frame, 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);
#endif
//! [InverseMap]
// direct transform
warpPolar(src, lin_polar_img, Size(),center, maxRadius, flags); // linear Polar
warpPolar(src, log_polar_img, Size(),center, maxRadius, flags + WARP_POLAR_LOG); // semilog Polar
// direct transform using warpPolar (replacing deprecated functions)
warpPolar(src, lin_polar_img, Size(),center, maxRadius, flags); // Linear-polar transform
warpPolar(src, log_polar_img, Size(),center, maxRadius, flags + WARP_POLAR_LOG); // Log-polar transform
// 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);
@@ -70,7 +62,7 @@ int main( int argc, char** argv )
dst = log_polar_img;
else
dst = lin_polar_img;
//get a point from the polar image
// get a point from the polar image
int rho = cvRound(dst.cols * 0.75);
int phi = cvRound(dst.rows / 2.0);
-45
View File
@@ -1,45 +0,0 @@
#!/usr/bin/env python
'''
plots image as logPolar and linearPolar
Usage:
logpolar.py
Keys:
ESC - exit
'''
# Python 2/3 compatibility
from __future__ import print_function
import numpy as np
import cv2 as cv
def main():
import sys
try:
fn = sys.argv[1]
except IndexError:
fn = 'fruits.jpg'
img = cv.imread(cv.samples.findFile(fn))
if img is None:
print('Failed to load image file:', fn)
sys.exit(1)
img2 = cv.logPolar(img, (img.shape[0]/2, img.shape[1]/2), 40, cv.WARP_FILL_OUTLIERS)
img3 = cv.linearPolar(img, (img.shape[0]/2, img.shape[1]/2), 40, cv.WARP_FILL_OUTLIERS)
cv.imshow('before', img)
cv.imshow('logpolar', img2)
cv.imshow('linearpolar', img3)
cv.waitKey(0)
print('Done')
if __name__ == '__main__':
print(__doc__)
main()
cv.destroyAllWindows()