【算法+OpenCV】图像极坐标变换及基于OpenCV的实现
在医学图像处理,尤其是在处理血管断层扫描类(如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的实现相关推荐
- 【OpenCV 4开发详解】图像极坐标变换
本文首发于"小白学视觉"微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社发行所有,禁止转载,侵权必究! 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4 ...
- 《OpenCv视觉之眼》Python图像处理十二 :Opencv图像轮廓提取之基于一阶导数的Roberts算法、Prewitt算法及Sobel算法
本专栏主要介绍如果通过OpenCv-Python进行图像处理,通过原理理解OpenCv-Python的函数处理原型,在具体情况中,针对不同的图像进行不同等级的.不同方法的处理,以达到对图像进行去噪.锐 ...
- opencv 梯度幅值_基于OpenCV的图像梯度与边缘检测!
严格的说,梯度计算需要求导数.但是图像梯度的计算,是通过计算像素值的差得到梯度的近似值.图像梯度表示的是图像变化的速度,反映了图像的边缘信息. 边缘是像素值快速变化的地方.所以对于图像的边缘部分,其灰 ...
- 分水岭算法分割图像的原理概述及OpenCV代码实现
图像处理开发需求.图像处理接私活挣零花钱,请加微信/QQ 2487872782 图像处理开发资料.图像处理技术交流请加QQ群,群号 271891601 前面博文中提到的图像阈值化,图像边缘检测,图像轮 ...
- 图像拼接和图像融合技术(基于Opencv)
图像拼接在实际的应用场景很广,比如无人机航拍,遥感图像等等,图像拼接是进一步做图像理解基础步骤,拼接效果的好坏直接影响接下来的工作,所以一个好的图像拼接算法非常重要. 再举一个身边的例子吧,你用你的手 ...
- 图像工程课程设计 基于 OpenCV 、 Qt 库实现的图像处理软件 大学编程作业(TUST 天津科技大学 2023年)
基于 OpenCV . Qt 库实现的图像处理软件 目录 基于 OpenCV . Qt 库实现的图像处理软件 一.项目简介 二.项目要求 三.项目源码 四.交流学习 图像处理工具说明文档 基于 Ope ...
- opencv图像配准_Milvus 实战 | 基于 Milvus 的图像查重系统
背景介绍 由于巨大的利益,论文造假屡见不鲜,在部分国家或地区甚至形成了论文造假的产业链.目前大部分论文查重系统只能检查论文文字,不能检查图片.因此,论文图片查重已然成为了学术论文原创性检测的重要部分. ...
- opencv 图像的变换
图像的变换 图像的缩放 resize(src, dst, dsize, fx, fy, interpolation) 缩放算法 INTER_NEAREST,邻近插值,速度快,效果差 INTER_LIN ...
- 图像极坐标变换的研究
做图像配准的时候,发现图像进行旋转的情况下的配准有一些特殊.于是想到可以用极坐标进行配准.查了一下资料,发现大家用的更多的是对数极坐标Log Polar. 笛卡尔坐标系和极坐标系 先来说一下我们常用的 ...
最新文章
- 人人都是作曲家:基于深度神经网络的音乐风格迁移
- python输出命令_Python输出各行命令详解
- arm服务器芯片尺寸,华为第四代ARM服务器自研芯片Hi1620规格曝光 全球首款7nm工艺的数据中心用ARM处理器...
- jquery --- 监听input框失效
- 后端架构高可用可伸缩
- wifi两种工作模式
- excel导出多重表头utils_Java中注解学习系列教程-4 使用自定义注解实现excel导出...
- 【月报】Java知音的一月汇总
- Sql Server系列:日期和时间函数
- Android加密算法之AES加密和解密实现
- 关于maven modules开发时候,eclipse的dubug模式不能找到源代码
- 微服务架构实战篇(五):Spring boot2.x + Guava 并使用RateLimiter实现秒杀限流demo
- 关于如何查找和利用PCL库学习资源的一些心得
- MATLAB 滤波函数的源代码
- 运营面试问题和答案(一)
- 1224. 简单迷宫问题
- 世界上哪个人种智商最高
- 2022年二级建造师建设工程法规及相关知识精选试题及答案
- python3计算md5_python 计算文件的md5值实例
- 单片机硬件电路设计实例分析
热门文章
- Java注解库_Java 注解详解
- 三角窗 matlab,【matlab】矩形窗/三角窗/hanning窗/hamming窗/blackman窗的頻率響應圖
- 25 linux ndk 头文件_正点原子Linux第二十五章RTC实时时钟实验
- expdp oracle 并行_关于Expdp/Impdp 并行导入导出详细测试结果和并行参数的正确理解!!...
- 苹果截屏快捷键_新手小白用苹果电脑搞科研,学会这些才不至于尴尬!
- 2020-12-17 Halcon初学者知识【4】区域和分割
- oracle 27140,ORA-27140 ORA-27300 ORA-27301
- 电磁悬浮控制系统仿真设计
- php获取form传递的变量,PHP-将变量传递给Ninja Form字段
- linux 有空格的文件夹,Linux之删除带有空格的文件