OpenCV的图像直角坐标系转极坐标系的函数warpPolar()详解,并附自己写的实现直角坐标系转极坐标系的MATLAB代码

【草稿】详解OpenCV实现图像直角坐标系转极坐标系的函数warpPolar(),并附自己写的实现直角坐标系转极坐标系的MATLAB代码

有些时候我们需要把图像或矩阵从直角坐标系(笛卡尔坐标系)转换到极坐标,这个过程通常称为图像的极坐标变换。

图像的极坐标变换一个常见的作用是可以将将一圆形图像变换成一个矩形图像,类似于把圆剪开铺平。这样可以方便我们处理钟表、圆盘等图像。图形上的圆形排列文字经过及坐标变换后可以垂直的排列在新图像上,便于对文字的识别和检测。示意图如下:

OpenCV的图像直角坐标系转极坐标系的函数warpPolar()详解,并附自己写的实现直角坐标系转极坐标系的MATLAB代码
OpenCV4中新增加了函数warpPolar()用于将图像或矩阵从直角坐标系(笛卡尔坐标系)转换到极坐标。

其C++原型如下:

void cv::warpPolar(InputArray   src,
                   OutputArray dst,
                   Size     dsize,
                   Point2f  center,
                   double   maxRadius,
                   int  flags )

其Python原型如下:

dst = cv.warpPolar(src, dsize, center, maxRadius, flags[, dst])

参数意义如下:
src—原图像,对通道数无要求,可以是灰度图像或者彩色图像。
dst—输出图像,它和原图像具有相同的数据类型和通道数,注意没有说尺寸相同哈。
dsize—目标图像大小,如图不填这个值或dsize两个值中的某个值,那么按下面的规则计算:

OpenCV的图像直角坐标系转极坐标系的函数warpPolar()详解,并附自己写的实现直角坐标系转极坐标系的MATLAB代码
center—极坐标变换时原点坐标。
maxRadius—极坐标系的极半径最大值,如果想更明确的理解这个参数的意义,请看我在参数意义介绍完毕后补充的示意图。
flags— 插值方法与极坐标映射方法标志。两个方法之间通过”+”或者”|”号进行连接。
插值方式如下表所示:
OpenCV的图像直角坐标系转极坐标系的函数warpPolar()详解,并附自己写的实现直角坐标系转极坐标系的MATLAB代码
有同学要问为什么这里要涉及到插值?
答案请访问本博文的原文获取。
本博文原文链接如下:
https://www.hhai.cc/thread-194-1-1.html

映射方法如下表所示:

OpenCV的图像直角坐标系转极坐标系的函数warpPolar()详解,并附自己写的实现直角坐标系转极坐标系的MATLAB代码
从上面这个映射方法表可以看出,函数warpPolar()不仅可以实现从直角坐标系向极坐标系的转换,也能实现从极坐标系向直角坐标系的转换。

为了大家能更好的理解上面各参数的意义,特别是参数dsize和参数maxRadius的意义,补充两张示意图(建议大家放大观看)。
下边这张图上半部分是变换前的原图,下半部分是变换后的图像。左下部分是线性极坐标变换,右下部分是半对数极坐标变换。

OpenCV的图像直角坐标系转极坐标系的函数warpPolar()详解,并附自己写的实现直角坐标系转极坐标系的MATLAB代码
上图中相关量的计算式和说明请访问本博文的原文查看,
本博文的原文链接如下:
https://www.hhai.cc/thread-194-1-1.html
OpenCV的图像直角坐标系转极坐标系的函数warpPolar()详解,并附自己写的实现直角坐标系转极坐标系的MATLAB代码
也许您会觉得上面的示意图和计算公式看着挺难,但实际上一点也不复杂,只要你静下心来仔细看一看,就能很快理解明白的。

另外,如果已知一个点的极坐标(magnitude, angleRad),
还可以用一段简单的代码计算得到其在直角坐标系中的坐标,
具体的代码请访问本博文的原文获取,
本博文原文链接如下:
https://www.hhai.cc/thread-194-1-1.html

接下来,上两个函数warpPolar()使用的示例代码。

第一个示例代码:
在第一个示例代码中,我们绘制一个半径为100的圆,并且把它映射到极坐标中。


import numpy as np
import cv2 as cv

Src_size = 101
Dst_size = Src_size

A = np.zeros((Src_size, Src_size), dtype='uint8')

cv.circle(A, (Src_size//2, Src_size//2), Src_size//2, 255, 1)

cv.imshow('A', A)

C = cv.warpPolar(A, (Dst_size, 360), (Src_size//2, Src_size//2), Src_size//2, cv.INTER_LINEAR + cv.WARP_POLAR_LINEAR)

cv.waitKey()

运行结果如下:
下面这张图是代码中的图像A:

OpenCV的图像直角坐标系转极坐标系的函数warpPolar()详解,并附自己写的实现直角坐标系转极坐标系的MATLAB代码
图像A的部分数据如下:
OpenCV的图像直角坐标系转极坐标系的函数warpPolar()详解,并附自己写的实现直角坐标系转极坐标系的MATLAB代码
图像C为图像A的极坐标变换图像,图像C的部分数据如下:
OpenCV的图像直角坐标系转极坐标系的函数warpPolar()详解,并附自己写的实现直角坐标系转极坐标系的MATLAB代码
OpenCV的图像直角坐标系转极坐标系的函数warpPolar()详解,并附自己写的实现直角坐标系转极坐标系的MATLAB代码
从图像C的数据来看,图A中半径为100的圆被映射到了极坐标中极半径为98,99,100的列中,并且角的度数为从0度到359度。

第二个示例代码:
在第二个示例代码中我们对钟表图进行极坐标变换,大家可以看下变换前后的效果,从而对图像极坐标变换有更形象的认识。
代码中用到的图片下载链接:
https://pan.baidu.com/s/1F-zZoKr-A3JETk5BLaNTFA?pwd=a6r0


import numpy as np
import cv2 as cv
import sys

img_src = cv.imread('F:/material/images/P0048-clock_dial.jpg')
if img_src is None:
    print('Error:Failed to read img')
    sys.exit()
cv.imshow('img_src', img_src)

img_polar = cv.warpPolar(img_src, (338, 360), (338//2, 338//2), 338//2, cv.INTER_LINEAR + cv.WARP_POLAR_LINEAR)
cv.imshow('img_polar', img_polar)

cv.waitKey()

运行结果如下图所示:

OpenCV的图像直角坐标系转极坐标系的函数warpPolar()详解,并附自己写的实现直角坐标系转极坐标系的MATLAB代码
从上面的运行结果可以看出,通过直角坐标到极坐标的变换,实现了把直角坐标系中的圆”剪开并展平”的效果。

有很多同学由于老师或学校的要求,
需要直角坐标到极坐标变换的MATLAB代码,
所以博主昊虹君还用MATLAB写了下面两个函数 :
1、矩阵(图像)从直角坐标系转换到极坐系的函数;
2、将极坐标转换到直角坐标的函数;
第1个函数的原型和说明如下:

function [Rmax,polarv]=topolar(v,x0,y0,np)
% 本函数实现将单通道的图像或矩阵v从直角坐标系转化为极坐标
% (x0,y0)为要指定的极坐标原点
% np为一周等间距相位数
% Rmax为函数自动计算出的极坐标系的最大极半径

第2个函数的原型和说明如下:

function [x,y] = polartorect(angle,magnitude,x0,y0)
% 该函数实现将极坐标转换到直角坐标
% angle是某点极坐标的角度值(以度为单位)
% magnitude是某点极坐标的
% x0是极坐系的原点在直角坐标系中的横坐标值
% y0是极坐系的原点在直角坐标系中的纵坐标值

上面两个函数【函数topolar()和函数polartorect()】的Matlab代码所在文件夹详情如下:

OpenCV的图像直角坐标系转极坐标系的函数warpPolar()详解,并附自己写的实现直角坐标系转极坐标系的MATLAB代码
具体的代码请大家访问本博文的原文获取,
本博文的原文链接如下:
https://www.hhai.cc/thread-194-1-1.html

第1个函数【矩阵(图像)从直角坐标系转换到极坐系的函数】的测试代码如下:

clc
close all
clear all

% 博主微信/QQ 2487872782
% 欢迎技术交流与咨询

%读取图像
ImageData=imread('F:/material/images/P0049-A_101_circle.bmp');

f1=figure(1);
set(f1,'name','原图','Numbertitle','off')
imshow(ImageData);

[rows,columns]=size(ImageData);

x0 = floor(rows/2);
y0 = floor(columns/2);
np = 360;

% Rmax中存储的是变换过程中自动计算出的最大极半值
% Rpolar_img就是经极坐标变换后的图像
[Rmax, Rpolar_img] = topolar(ImageData,x0,y0,np);

f2=figure(2);
set(f2,'name','原图的极坐标图','Numbertitle','off')
imshow(Rpolar_img);

运行结果如下图所示:

OpenCV的图像直角坐标系转极坐标系的函数warpPolar()详解,并附自己写的实现直角坐标系转极坐标系的MATLAB代码
从上面的运行结果可以看出,原图中的圆形经极坐标变换后是一条垂直的直线。

函数topolar()和函数polartorect()的Matlab代码所在文件夹详情如下:

OpenCV的图像直角坐标系转极坐标系的函数warpPolar()详解,并附自己写的实现直角坐标系转极坐标系的MATLAB代码
具体的代码请大家访问本博文的原文获取,
本博文的原文链接如下:
https://www.hhai.cc/thread-194-1-1.html

Original: https://blog.csdn.net/wenhao_ir/article/details/124831090
Author: 昊虹图像算法
Title: OpenCV的图像直角坐标系转极坐标系的函数warpPolar()详解,并附自己写的实现直角坐标系转极坐标系的MATLAB代码

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/519339/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球