图像去畸变和添加畸变
背景:最近的项目中用到的图像去畸变的知识,刚开始是直接调用opencv中提供的函数cv::initUndistortRectifyMap()和cv::remap()函数,实现图像的全局去畸变,但是由于图像的分辨率很高,再加上,实际过程中我们只用到了很小一块的图像,所以为了降低电脑的负担,则想选用局部图像去畸变的方法来代替全局图像去畸变。
于是我想到了《SLAM十四讲》书中在相机模型中有相关的去畸变的代码,我就直接使用测试了,效果还不错。
void LocalZoneUndistortion(cv::Mat& localImage, cv::Mat& undistortLocalImage) {undistortLocalImage = cv::Mat(localImage.rows, localImage.cols, CV_8UC1);for (int row = 0; row < localImage.rows; ++row) {for (int col = 0; col < localImage.cols; ++col) {double x = (col - cx_) / fx_;double y = (row - cy_) / fy_;double r = sqrt(x * x + y * y);double xDistorted = x * (1 + k1_ * r * r + k2_ * r * r * r * r) + 2 * p1_* x * y + p2_ * (r * r + 2 * x * x);double yDistorted = y * (1 + k1_ * r * r + k2_ * r * r * r * r) + p1_ * (r * r + 2 * y * y) + 2 * p2_* x * y;double uDistorted = fx_ * xDistorted + cx_;double vDistorted = fy_ * yDistorted + cy_;if (uDistorted >= 0 && vDistorted >= 0 && uDistorted < localImage.cols && vDistorted < localImage.rows) {undistortLocalImage.at<uchar>(row, col) = localImage.at<uchar>((int)vDistorted,(int)uDistorted);}else {undistortLocalImage.at<uchar>(row, col) = 0;} }}}
当然在使用的时候要把相机内参和畸变系数传进去呦,我这里是把它们定义为成员变量,就没有传进去。其实我之前一直对这个去畸变的过程很困惑的,这明明是一个添加畸变的过程,为啥可以达到去畸变的效果呢?时隔多日之后再次使用这个函数,其实我还是没怎么关心她背后的逻辑,直到我同时又需要完成对点添加畸变的任务,这个时候我才重新审视这两个过程背后的逻辑。
添加畸变的函数如下
void Tracking::DistortPoints(cv::Point2f& undistPoint, cv::Point2f& distPoint) {double x = (undistPoint.x - cx_) / fx_;double y = (undistPoint.y - cy_) / fy_;double r2 = x * x + y * y;// Radial distorsiondouble xDistort = x * (1 + k1_ * r2 + k2_ * r2 * r2 + k3_ * r2 * r2 * r2);double yDistort = y * (1 + k1_ * r2 + k2_ * r2 * r2 + k3_ * r2 * r2 * r2);// Tangential distorsionxDistort = xDistort + (2 * p1_ * x * y + p2_ * (r2 + 2 * x * x));yDistort = yDistort + (p1_ * (r2 + 2 * y * y) + 2 * p2_ * x * y);// Back to absolute coordinates.xDistort = xDistort * fx_ + cx_;yDistort = yDistort * fy_ + cy_;distPoint = cv::Point2f((float)xDistort, (float)yDistort);};
我们平时遇到的都是将带有畸变的点转换为不带畸变的点,很少会遇到在不带畸变的点上添加畸变,因为我要在一个带有畸变的图像上标注一个不带畸变的点,那标注出的位置和我们真正的目标之间就有一定的偏差了,这个时候只有在这些不带畸变的点上添加上畸变,这样才能适应带有畸变的图像。
我们可以发现,上面两个过程,去畸变和添加畸变刚开始的部分都是在添加畸变的过程,
首先是将像素位置点,从像平面内转换到归一化平面内,
double x = (col - cx_) / fx_;
double y = (row - cy_) / fy_;
double x = (undistPoint.x - cx_) / fx_;
double y = (undistPoint.y - cy_) / fy_;
然后再分别添加,径向畸变和切向畸变,
// Radial distorsion
double xDistort = x * (1 + k1_ * r2 + k2_ * r2 * r2 + k3_ * r2 * r2 * r2);
double yDistort = y * (1 + k1_ * r2 + k2_ * r2 * r2 + k3_ * r2 * r2 * r2);// Tangential distorsion
xDistort = xDistort + (2 * p1_ * x * y + p2_ * (r2 + 2 * x * x));
yDistort = yDistort + (p1_ * (r2 + 2 * y * y) + 2 * p2_ * x * y);
然后在把点转换到像平面内。
// Back to absolute coordinates.
xDistort = xDistort * fx_ + cx_;
yDistort = yDistort * fy_ + cy_;
以上这些步骤两个过程是一样的,最后一步是不一样的。
在去畸变过程中,我们相当于给不带畸变的坐标PointA添加畸变,得到带有畸变的点PointB,而这正是我们直接获取得到的带有畸变的图像I上的点,这个时候我们可以将带有畸变的图像上的PointB位置处的灰度值映射赋值给PointA的位置处,这样操作图像I上所有有效点,就完成了对带有畸变的图像I的去畸变操作。
if (uDistorted >= 0 && vDistorted >= 0 && uDistorted < localImage.cols && vDistorted < localImage.rows) {undistortLocalImage.at<uchar>(row, col) = localImage.at<uchar>((int)vDistorted,(int)uDistorted);
} else {undistortLocalImage.at<uchar>(row, col) = 0;
}
而添加畸变的过程就比较好理解了,就是给不带有畸变的点添加上径向畸变和切向畸变,直接得到带畸变的点。
图像去畸变和添加畸变相关推荐
- 图像去畸变矫正及双线性内插法
点击上方"3D视觉工坊",选择"星标" 干货第一时间送达 通过采集的图像我们可以得到畸变后的图像,要得到没有畸变的图像要通过畸变模型推导其映射关系. 真实图像 ...
- 超实用!图像去畸变矫正及双线性内插法
点击上方"3D视觉工坊",选择"星标" 干货第一时间送达 通过采集的图像我们可以得到畸变后的图像,要得到没有畸变的图像要通过畸变模型推导其映射关系. 真实图像 ...
- 根据相机内参进行图像去畸变
cv::Mat img; cv::Mat img_undistort; double fx,fy, cx, cy, k1, k2, p1, p2, k3;for(int v = 0; v < i ...
- opencv 图像添加畸变
opencv 图像添加畸变 因为需要对相机标定效果进行评价,首先要制作一张有畸变的标定板图片.可是opencv对图片只能去畸变,没有直接添加畸变的方法. 基于畸变公式可以对求得畸变后的点的坐标.本文的 ...
- OpenCV 【十一】—— 图像去畸变,对极约束之undistort,initUndistortRectifyMap,undistort
目录 0.极限约束,对极校正 1.摄像机成像原理简述 2.成像畸变 2.1. 畸变数学模型 2.2. 公式推导 3.畸变校正 3.1. 理论推导 4. 图像去畸变** 5. 图像尺度缩放与内参的关系* ...
- 计算机视觉:Opencv图像去畸变
计算机视觉:Opencv图像去畸变 针孔相机模型图像去畸变 方法一 方法二 区别与联系 鱼眼相机模型图像去畸变 方法一 方法二 区别与联系 参考文献 针孔相机模型图像去畸变 针对畸变参数,k1,k2, ...
- opencv图像去畸变
图像去畸变的思路 对于目标图像(无畸变图像)上的每个像素点,转换到normalize平面,再进行畸变变换,进行投影,得到这个像素点畸变后的位置,然后将这个位置的源图像(畸变图像)的像素值作为目标图像该 ...
- 基于MATLAB的图像去雾系统
基于MATLAB的图像去雾系统 (一)图像去雾基础原理 1.雾霭的形成机理 雾实际上是由悬浮颗粒在大气中的微小液滴构成的气溶胶,常呈现乳白色,其底部位于地球表面,所以也可以看作是接近地面的云.霭其实跟 ...
- matlab图像去雾实现
目录 一.课题意义 1 (一)研究意义 1 (二)研究现状 1 二.相关知识 4 (一)系统功能及简介: 4 (二)用到的知识 5 三.系统设计与实现 5 (一)实现条件 5 硬件条件:计算机 5 软 ...
最新文章
- Linux复制文件scp
- 关于Silverlight安装问题之二
- 分析师洞察:边缘数据中心的UPS系统
- Axure RP一个专业的快速界面原型设计工具
- 神经网络入门-MLP, RNN, BiRNN
- Centos7 install firefox-china
- java配置文件放置到jar外_java相关:Spring Boot 把配置文件和日志文件放到jar外部...
- Node — 第一天
- windows 系统监视器_使用Windows 7中的可靠性监视器对计算机问题进行故障排除
- Windows 如何用命令终端(CMD)启动和停止 MySQL 数据库服务
- python取文本中间_Python读取两个字符串之间的特定文本行
- 剑指Offer - 面试题9. 用两个栈实现队列
- 迭代器协议、斐波那契数列
- Android Activity(一)Activity间的跳转
- 用Python搭建股票舆情分析系统
- 面试记录五:腾讯后台研发
- 详解哈夫曼树和哈夫曼编码
- python怎么调用外部软件_python调用其他程序
- 情绪管理---第二课:情绪包含四方面的反应
- 使用UE4开发VR项目_性能优化(三)_思路和方法
热门文章
- Inside the C++ Object Model | Outline
- 3DMax插件和它的3DXI接口
- [开发手记] 使用.NET实现你的IP切换器
- 怎样在PHP中通过ADO调用Asscess数据库和COM程序
- Promise 的基本使用 与 Ajax的jQuery封装
- 关于Unity中NGUI的背包实现之Scrollview(基于Camera)
- SDL 库 无法解析的外部符号 __imp__fprintf
- iOS 开发者账号共用发布证书 (Distribution)问题
- Spring的bean实例化过程
- es6 --- 自制迭代器