专栏首页一棹烟波图像添加径向畸变

图像添加径向畸变

通常摄像机的镜头都会有镜头畸变,尤其是广角镜头,在做图像处理中往往会通过摄像机标定获取镜头的畸变系数,然后进行畸变校正。而在某些特殊的情况下,你可能会需要往图像中加入畸变,下面简单实现了一个向无畸变图像中人为加入径向畸变。

仍然以这幅风景图为例,我用手机拍摄的,畸变程度可以忽略:

1.人为加入桶形畸变(边缘放大率小于中心放大率,导致边缘像素点向图像中心移动)

视场缩放

2.人为加入枕形畸变(边缘放大率大于中心放大率,导致边缘像素点远离图像中心移动)

视场缩放

 代码实现如下,使用3D warping和双线性插值。加入桶形畸变disK=0.5,加入枕形畸变disk=-0.5,改变归一化焦距fx,fy实现视场的缩放,如fx=fx*scale和fy=fy*scale。

 1 #include <iostream>
 2 #include <string>
 3 #include <opencv2/opencv.hpp>
 4 
 5 using namespace std;
 6 using namespace cv;
 7 
 8 void distortImg(const Mat &srcImg, Mat &dstImg, const float fx, const float fy, const float cx, const float cy)
 9 {
10     int imgHeight=srcImg.rows;
11     int imgWidth=srcImg.cols;
12 
13     float disK=0.5;
14 
15     uchar* pSrcData=(uchar*)srcImg.data;
16     uchar* pDstData=(uchar*)dstImg.data;
17     for (int j=0; j<imgHeight; j++)
18     {
19         for (int i=0; i<imgWidth; i++)
20         {
21             //转到摄像机坐标系
22             float X=(i-cx)/fx;
23             float Y=(j-cy)/fy;
24             float r2=X*X+Y*Y;
25             //加上畸变
26             float newX=X*(1+disK*r2);
27             float newY=Y*(1+disK*r2);
28             //再转到图像坐标系
29             float u=newX*fx+cx;
30             float v=newY*fy+cy;
31             //双线性插值
32             int u0=floor(u);
33             int v0=floor(v);
34             int u1=u0+1;
35             int v1=v0+1;
36 
37             float dx=u-u0;
38             float dy=v-v0;
39             float weight1=(1-dx)*(1-dy);
40             float weight2=dx*(1-dy);
41             float weight3=(1-dx)*dy;
42             float weight4=dx*dy;
43 
44             int resultIdx=j*imgWidth*3+i*3;
45             if (u0>=0 && u1<imgWidth && v0>=0 && v1<imgHeight)
46             {
47                  pDstData[resultIdx+0]=weight1*pSrcData[v0*imgWidth*3 + u0*3+0]+weight2*pSrcData[v0*imgWidth*3+u1*3+0]
48                     +weight3*pSrcData[v1*imgWidth*3 +u0*3+0]+weight4*pSrcData[v1*imgWidth*3 + u1*3+0];
49                  pDstData[resultIdx+1]=weight1*pSrcData[v0*imgWidth*3 + u0*3+1]+weight2*pSrcData[v0*imgWidth*3+u1*3+1]
50                     +weight3*pSrcData[v1*imgWidth*3 +u0*3+1]+weight4*pSrcData[v1*imgWidth*3 + u1*3+1];
51                  pDstData[resultIdx+2]=weight1*pSrcData[v0*imgWidth*3 + u0*3+2]+weight2*pSrcData[v0*imgWidth*3+u1*3+2]
52                     +weight3*pSrcData[v1*imgWidth*3 +u0*3+2]+weight4*pSrcData[v1*imgWidth*3 + u1*3+2];
53             }
54         }
55     }
56 }
57 
58 void main()
59 {
60     string imgPath="data/source_images/";
61     Mat srcImg = imread(imgPath+"moon.jpg");
62     pyrDown(srcImg, srcImg);
63     pyrDown(srcImg, srcImg);
64 
65     Mat dstImg = srcImg.clone();
66     dstImg.setTo(0);
67 
68     namedWindow("showImg",0);
69     imshow("showImg", srcImg);
70     waitKey(0);
71 
72     float fx=930.965;
73     float fy=930.884;
74     float cx=513.823;
75     float cy=385.656;
76 
77     distortImg(srcImg, dstImg, fx, fy, cx, cy);
78 
79     imshow("showImg", dstImg);
80     waitKey(0);
81 }

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 图像缩放示例

    二维图像的缩放属于仿射变换或者透视变换的范畴,一般可以通过OpenCV的warpAffine()或者warpPerspective()函数实现。 出于兴趣,根据...

    一棹烟波
  • OpenCV鼠标滑轮事件

    鼠标的滑轮事件实现图像的缩放很方便,具体在回调函数中如下写: 其中scale可以在外部定义为全局变量,通过响应CV_EVENT_MOUSEWHEEL滑轮事件获取...

    一棹烟波
  • 利用视差图合成新视点

    利用视差图合成新视点,视差图一般通过图像匹配获取,以middlebury上的一张图为例,左边为原图(左图像),右边为对应视差图(灰度图)。 ? ? 1. 正向...

    一棹烟波
  • tensorflow: 查看 tensor详细数值

      print只能打印输出shape的信息,而要打印输出tensor的值,需要借助 tf.Session,tf.InteractiveSession。

    Petrichor_
  • python winrm模块使用

    用户2398817
  • Security知识阶段汇总

    去年参与了很多公司组织的security活动,并且给自己team,其他team做过一些security相关的分享,今年公司security相关的活动又陆续开始了...

    Bruce Li
  • TensorFlow从1到2 | 第五章 非专家莫入!TensorFlow实现CNN

    当看到本篇时,根据TensorFlow官方标准《Deep MNIST for Experts》(https://tensorflow.google.cn/get...

    用户1332428
  • TensorFlow从1到2 - 5 - 非专家莫入!TensorFlow实现CNN

    当看到本篇时,根据TensorFlow官方标准《Deep MNIST for Experts》,你已经达到Expert Level,要恭喜了。 且不说是否夸大...

    黑猿大叔
  • tensorboard快速上手教程

    tensorboard可对网络和各种参数进行可视化,可以方便的进行网络结构调整和调参,尤其是应对复杂网路,下面用一个例子介绍tensorboard在Linux中...

    于小勇
  • Tensorflow教程: tf.Variable() 和tf.get_variable()

    1、使用tf.Variable时,如果检测到命名冲突,系统会自己处理。使用tf.get_variable()时,系统不会处理冲突,而会报错

    用户1332428

扫码关注云+社区

领取腾讯云代金券

玩转腾讯云 有奖征文活动