简单的实现 相片去畸变,调用opencv读写图像,其他库函数不用
2018-08-01 16:58
477 查看
刚入职,leader给我 一些入门级的事情来做,帮助理解原理,以后的目标是 能够完全读懂现有的图像处理的库,并能够根据实际进行改进和优化。
利用matlab单相机标定获得了 相机的 内参矩阵和畸变函数,然后进行 去畸变。
文字流程如下(注意几次坐标系转换):
(1),将图像的像素坐标系通过内参矩阵转换到相机坐标系:
(2),在相机坐标系下进行去畸变操作。
(3),去畸变操作结束后,将相机坐标系重新转换到图像像素坐标系。
(4),并用源图像的像素值对新图像的像素点进行插值。
[code]// Undistortion.cpp: 定义控制台应用程序的入口点。 // #include "stdafx.h" #include<opencv2\opencv.hpp> #include<math.h> using namespace cv; //matlab 单相机标定结果,相机A double k[3] = { -0.0903,0.7409,0.0 };//径向畸变 k1,k2,k3 double p[2] = { -0.0012,0.0013 }; //切向畸变 p1,p2 double intrinsic[3][3] = { {3449.6,0,0},{6.3538,3449.63,0},{668.4023,472.6526,1} }; void undistortion(Mat input, Mat &output); //去畸变 int main() { Mat picture = imread("D:\\week1\\A_006.bmp"); Mat srcImage; cvtColor(picture, srcImage, CV_BGR2GRAY); imshow("【原图片】", srcImage); //a blank image of the same size Mat dstImage = Mat::zeros(srcImage.rows, srcImage.cols, CV_8UC1); undistortion(srcImage, dstImage); imshow("【去畸变后】", dstImage); Mat diffImage = (srcImage - dstImage)*50; imshow("【变化图-放大50倍的效果】", diffImage); waitKey(); return 0; } void undistortion(Mat input, Mat &output) { double fx = intrinsic[0][0]; double fy = intrinsic[1][1]; //焦距 double cx = intrinsic[2][0]; double cy = intrinsic[2][1]; //光心位置 double k1 = k[0]; double k2 = k[1]; double k3 = k[2]; //径向畸变系数 double p1 = p[0]; double p2 = p[1]; //切向畸变系数 double r; //畸变图 距离中心点的距离 double x1, y1, x2, y2; //中间变量 for (int i = 0; i < input.cols; i++) { for (int j = 0; j < input.rows; j++) { //①像素坐标系到 相机坐标系 x1 = (i - cx) / fx; y1 = (j - cy) / fy; //②在相机坐标系下进行去畸变操作 r = x1 * x1 + y1 * y1; x2 = x1 * (1 + k1 * pow(r, 2) + k2 * pow(r, 4)) + 2 * p1*x1*y1 + p2 * (pow(r, 2) + 2 * pow(x1, 2)); y2 = y1 * (1 + k1 * pow(r, 2) + k2 * pow(r, 4)) + 2 * p2*x1*y1 + p1 * (pow(r, 2) + 2 * pow(y1, 2)); //③在去畸变操作后,重新转换到 像素坐标系 x2 = x2 * fx + cx; y2 = y2 * fy + cy; //④并用源图像的像素值对新图像的像素点进行插值 if (y2 > 0 && y2 < input.rows - 1 && x2>0 && x2 < input.cols - 1) { //防止越界 double h = y2; double w = x2; double result = (floor(w + 1) - w)*(floor(h + 1) - h)*input.at<uchar>(floor(h), floor(w)) + (floor(w + 1) - w)*(h - floor(h))*input.at<uchar>(floor(h + 1), floor(w)) + (w - floor(w))*(floor(h + 1) - h)*input.at<uchar>(floor(h), floor(w + 1)) + (w - floor(w))*(h - floor(h))*input.at<uchar>(floor(h + 1), floor(w + 1)); //双线性内插 output.at<uchar>(j, i) = floor(result); //std::cout << output.at<uchar>(j, i) - input.at<uchar>(j, i) << "\t"; } } } }
原图:
越靠近边上的 越亮。说明变形越大,与实际相符合,总体变形不严重,所以这里放大了50倍,没有考虑太多是否溢出的问题,如果是彩色图片,计算三次即可。
阅读更多相关文章推荐
- 利用Qt与OpenCV简单实现摄像头图像捕捉
- OC多文件开发简单例子实现(重点:self在对象方法中调用其他对象方法的3种方法)
- C#真他妈神奇,一个函数都不用写就能实现一个简单的邮件发送工具
- asp.net调用opencv类库,实现图像处理显示
- Opencv实现图像旋转,非常简单,几行代码
- 【图像识别】 Python+Opencv调用摄像头实现人脸识别并保存视频
- 图像放缩 (matlab实现,不用自带的函数)
- ROS学习笔记(2):在ROS中使用OpenCV进行简单的图像处理---代码实现篇
- Opencv简单编程--Mat图像作为函数参数
- 【实现&调用】实现可被简单调用的python函数
- Cocos2D-x精灵的简单实现和函数调用基本流程
- opencv3中图像灰度化处理(手动编写处理函数实现)
- 调用实现使用popen()函数获取其他Console中的内容
- 用OpenCV的resize函数实现图像的缩放
- python3.4实现调用opencv3.1.0显示图像
- 哈工大深研院数字图像处理第一次大作业:不调用Matlab函数实现图像增强
- DCT简单图像压缩的OpenCV实现
- opencv 旋转图像函数实现 等同于matlab里的rotate() (注:旋转后图像变大,超出部分填为黑色)
- Ribbon+Opencv 2.4--实现一个简单的Opencv图像处理小工具
- opencv3实现简单的数字图像识别(KNN)