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

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

1、极坐标变换(方转圆)

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

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

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

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

圆图上点P在方图上对应行数为r/delta_r;

圆图上点P在方图上对应的列数n = thata/delta_t。

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

实现代码如下:

bool cartesian_to_polar(cv::Mat& mat_c, cv::Mat& mat_p, int img_d)
{mat_p = cv::Mat::zeros(img_d, img_d, CV_8UC1);int line_len = mat_c.rows;int line_num = mat_c.cols;double delta_r = (2.0*line_len) / (img_d - 1); //半径因子double delta_t = 2.0 * PI / line_num; //角度因子double center_x = (img_d - 1) / 2.0;double center_y = (img_d - 1) / 2.0;for (int i = 0; i < img_d; i++){for (int j = 0; j < img_d; j++){double rx = j - center_x; //图像坐标转世界坐标double ry = center_y - i; //图像坐标转世界坐标double r = std::sqrt(rx*rx + ry*ry);if (r <= (img_d - 1) / 2.0){double ri = r * delta_r;int rf = (int)std::floor(ri);int rc = (int)std::ceil(ri);if (rf < 0){rf = 0;}if (rc > (line_len - 1)){rc = line_len - 1;}double t = std::atan2(ry, rx);if (t < 0){t = t + 2.0 * PI;}double ti = t / delta_t;int tf = (int)std::floor(ti);int tc = (int)std::ceil(ti);if (tf < 0){tf = 0;}if (tc > (line_num - 1)){tc = line_num - 1;}mat_p.ptr<uchar>(i)[j] = interpolate_bilinear(mat_c, ri, rf, rc, ti, tf, tc);}}}return true;
}

顺便给一段双线性插值的代码:

uchar interpolate_bilinear(cv::Mat& mat_src, double ri, int rf, int rc, double ti, int tf, int tc)
{double inter_value = 0.0;if (rf == rc && tc == tf){inter_value = mat_src.ptr<uchar>(rc)[tc];}else if (rf == rc){inter_value = (ti - tf) * mat_src.ptr<uchar>(rf)[tc] + (tc - ti) * mat_src.ptr<uchar>(rf)[tf];}else if (tf == tc){inter_value = (ri - rf) * mat_src.ptr<uchar>(rc)[tf] + (rc - ri) * mat_src.ptr<uchar>(rf)[tf];}else{double inter_r1 = (ti - tf) * mat_src.ptr<uchar>(rf)[tc] + (tc - ti) * mat_src.ptr<uchar>(rf)[tf];double inter_r2 = (ti - tf) * mat_src.ptr<uchar>(rc)[tc] + (tc - ti) * mat_src.ptr<uchar>(rc)[tf];inter_value = (ri - rf) * inter_r2 + (rc - ri) * inter_r1;}return (uchar)inter_value;
}

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

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

直接看代码吧:

bool polar_to_cartesian(cv::Mat& mat_p, cv::Mat& mat_c, int rows_c, int cols_c)
{mat_c = cv::Mat::zeros(rows_c, cols_c, CV_8UC1);int polar_d = mat_p.cols;double polar_r = polar_d / 2.0; // 圆图半径double delta_r = polar_r / rows_c; //半径因子double delta_t = 2.0*PI / cols_c;  //角度因子double center_polar_x = (polar_d - 1) / 2.0;double center_polar_y = (polar_d - 1) / 2.0;for (int i = 0; i < cols_c; i++){double theta_p = i * delta_t; //方图第i列在圆图对应线的角度double sin_theta = std::sin(theta_p);double cos_theta = std::cos(theta_p);for (int j = 0; j < rows_c; j++){double temp_r = j * delta_r; //方图第j行在圆图上对应的半径长度int polar_x = (int)(center_polar_x + temp_r * cos_theta);int polar_y = (int)(center_polar_y - temp_r * sin_theta);mat_c.ptr<uchar>(j)[i] = mat_p.ptr<uchar>(polar_y)[polar_x];}}return true;
}

3、结果

为验证算法,下载了一张IVUS(血管超声)图像,先用极坐标反变换得到方图,再用极坐标变换将方图变换回圆图,通过比较,变换前后的图像基本一致,哦了~~~

原始图

反极坐标变换图

极坐标变换结果

2017.03.24完成初稿

【算法+OpenCV】图像极坐标变换及基于OpenCV的实现相关推荐

  1. 【OpenCV 4开发详解】图像极坐标变换

    本文首发于"小白学视觉"微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社发行所有,禁止转载,侵权必究! 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4 ...

  2. 《OpenCv视觉之眼》Python图像处理十二 :Opencv图像轮廓提取之基于一阶导数的Roberts算法、Prewitt算法及Sobel算法

    本专栏主要介绍如果通过OpenCv-Python进行图像处理,通过原理理解OpenCv-Python的函数处理原型,在具体情况中,针对不同的图像进行不同等级的.不同方法的处理,以达到对图像进行去噪.锐 ...

  3. opencv 梯度幅值_基于OpenCV的图像梯度与边缘检测!

    严格的说,梯度计算需要求导数.但是图像梯度的计算,是通过计算像素值的差得到梯度的近似值.图像梯度表示的是图像变化的速度,反映了图像的边缘信息. 边缘是像素值快速变化的地方.所以对于图像的边缘部分,其灰 ...

  4. 分水岭算法分割图像的原理概述及OpenCV代码实现

    图像处理开发需求.图像处理接私活挣零花钱,请加微信/QQ 2487872782 图像处理开发资料.图像处理技术交流请加QQ群,群号 271891601 前面博文中提到的图像阈值化,图像边缘检测,图像轮 ...

  5. 图像拼接和图像融合技术(基于Opencv)

    图像拼接在实际的应用场景很广,比如无人机航拍,遥感图像等等,图像拼接是进一步做图像理解基础步骤,拼接效果的好坏直接影响接下来的工作,所以一个好的图像拼接算法非常重要. 再举一个身边的例子吧,你用你的手 ...

  6. 图像工程课程设计 基于 OpenCV 、 Qt 库实现的图像处理软件 大学编程作业(TUST 天津科技大学 2023年)

    基于 OpenCV . Qt 库实现的图像处理软件 目录 基于 OpenCV . Qt 库实现的图像处理软件 一.项目简介 二.项目要求 三.项目源码 四.交流学习 图像处理工具说明文档 基于 Ope ...

  7. opencv图像配准_Milvus 实战 | 基于 Milvus 的图像查重系统

    背景介绍 由于巨大的利益,论文造假屡见不鲜,在部分国家或地区甚至形成了论文造假的产业链.目前大部分论文查重系统只能检查论文文字,不能检查图片.因此,论文图片查重已然成为了学术论文原创性检测的重要部分. ...

  8. opencv 图像的变换

    图像的变换 图像的缩放 resize(src, dst, dsize, fx, fy, interpolation) 缩放算法 INTER_NEAREST,邻近插值,速度快,效果差 INTER_LIN ...

  9. 图像极坐标变换的研究

    做图像配准的时候,发现图像进行旋转的情况下的配准有一些特殊.于是想到可以用极坐标进行配准.查了一下资料,发现大家用的更多的是对数极坐标Log Polar. 笛卡尔坐标系和极坐标系 先来说一下我们常用的 ...

最新文章

  1. 人人都是作曲家:基于深度神经网络的音乐风格迁移
  2. python输出命令_Python输出各行命令详解
  3. arm服务器芯片尺寸,华为第四代ARM服务器自研芯片Hi1620规格曝光 全球首款7nm工艺的数据中心用ARM处理器...
  4. jquery --- 监听input框失效
  5. 后端架构高可用可伸缩
  6. wifi两种工作模式
  7. excel导出多重表头utils_Java中注解学习系列教程-4 使用自定义注解实现excel导出...
  8. 【月报】Java知音的一月汇总
  9. Sql Server系列:日期和时间函数
  10. Android加密算法之AES加密和解密实现
  11. 关于maven modules开发时候,eclipse的dubug模式不能找到源代码
  12. 微服务架构实战篇(五):Spring boot2.x + Guava 并使用RateLimiter实现秒杀限流demo
  13. 关于如何查找和利用PCL库学习资源的一些心得
  14. MATLAB 滤波函数的源代码
  15. 运营面试问题和答案(一)
  16. 1224. 简单迷宫问题
  17. 世界上哪个人种智商最高
  18. 2022年二级建造师建设工程法规及相关知识精选试题及答案
  19. python3计算md5_python 计算文件的md5值实例
  20. 单片机硬件电路设计实例分析

热门文章

  1. Java注解库_Java 注解详解
  2. 三角窗 matlab,【matlab】矩形窗/三角窗/hanning窗/hamming窗/blackman窗的頻率響應圖
  3. 25 linux ndk 头文件_正点原子Linux第二十五章RTC实时时钟实验
  4. expdp oracle 并行_关于Expdp/Impdp 并行导入导出详细测试结果和并行参数的正确理解!!...
  5. 苹果截屏快捷键_新手小白用苹果电脑搞科研,学会这些才不至于尴尬!
  6. 2020-12-17 Halcon初学者知识【4】区域和分割
  7. oracle 27140,ORA-27140 ORA-27300 ORA-27301
  8. 电磁悬浮控制系统仿真设计
  9. php获取form传递的变量,PHP-将变量传递给Ninja Form字段
  10. linux 有空格的文件夹,Linux之删除带有空格的文件