OpenCV4入门系列教程41:极坐标变换

索引地址:系列教程索引地址

上一篇:OpenCV4入门系列教程40:Gamma变换(矫正)

在医学图像处理,尤其是在处理血管断层扫描类(如OCT、IVUS等)图像的过程中,不可避免的会使用到极坐标变换,也即是我们通常所说的“方转圆”。同样,我们可以使用极坐标变换的反变换实现“圆转方”

极坐标变换及其反变换的关键在于,根据极坐标变换前的图像(我们称为“方图”)确定极坐标变换后的图像(我们称为“圆图”)上每个像素点的像素值。也即是找到“圆图”和“方图”间几何坐标的对应关系。

极坐标变换(方转圆)

原理:如下图所示,实现极坐标变换的关键即在于找到圆图上任一点P(i,j),在方图上对应的点p(m,n),然后通过插值算法实现圆图上所有像素点的赋值。

方图上,其行列数分别为M、N,方图上的每一列对应为圆图上的每条半径,半径方向存在着一个长度缩放因子Δr=M/R\Delta _r = M / R,圆周方向被分为N等分,即角度因子为Δt=2π/N\Delta_t = 2π / N

圆图上,图像坐标(i,j)和世界坐标(x,y)有着如下变换关系:x = j - R, y = R - i;

那么,图中P点半径长度为r = sqrt(x * x + y * y),角度θ=arctan(y/x)\theta = arctan(y/x)

圆图上点P在方图上对应行数为r/Δrr/\Delta_r

圆图上点P在方图上对应的列数n=θ/Δtn = \theta/\Delta_t

以上就是极坐标变换的基本原理,结合相应的插值算法,即可实现图像的极坐标变换。

polar

极坐标变换的反变换(圆转方)

原理:顾名思义,极坐标变换的反变换即极坐标变换的逆变换,原理和极坐标变换类似,只是更为直接和方便,且不需要进行插值,这里就不再赘述了。

函数原型:

1
2
3
4
5
6
7
void cv::warpPolar(InputArray  src,
OutputArray dst,
Size dsize,
Point2f center,
double maxRadius,
int flags
)
  • src:原图像,可以是灰度图像或者彩色图像。
  • dst:极坐标变换后输出图像,与原图像具有相同的数据类型和通道数。
  • dsize:目标图像大小。
  • center:极坐标变换时极坐标的原点坐标。
  • maxRadius:变换时边界圆的半径,它也决定了逆变换时的比例参数。
  • flags: 插值方法与极坐标映射方法标志,插值方法和极坐标映射方法在下表中给出,两个方法之间通过“+”或者“|”号进行连接。
标志映射
WARP_POLAR_LINEAR极坐标变换
WARP_POLAR_LOG半对数极坐标变换
WARP_INVERSE_MAP逆变换

测试图片:

rainbow

测试代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main() {
Mat img = imread("rainbow.png");
if (!img.data) {
cout << "请检查图像文件名称是否正确" << endl;
return -1;
}

Mat img1, img2;
Point center = Point(img.cols / 2, img.rows / 2); //极坐标在图像中的原点
//正极坐标变换->方变圆
warpPolar(img, img1, Size(512, 512), center, center.x, WARP_POLAR_LINEAR);

//逆极坐标变换->圆变方
warpPolar(img1,img2,Size(img.rows,img.cols),center,center.x,WARP_INVERSE_MAP);
imshow("Original", img);
imshow("Anti Polar Result", img2);
imshow("Polar Result", img1);
waitKey(0);
return 0;
}

测试结果:

polar

original是原图,polar result是方转圆之后的,我们想要的效果应该是个同心圆,但是不是。anti是圆转方应该回到原图但是可以看出来有部分数据丢失。

下一篇:OpenCV4入门系列教程42:对数变换