zoukankan      html  css  js  c++  java
  • 图像添加径向畸变

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

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

    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 }
    View Code
    --------------------------------- 业精于勤而荒于嬉 行成于思而毁于随 ---------------------------------
  • 相关阅读:
    FastAdmin 提示框 toastr 改变文字
    FastAdmin 将会员模块升级为基础模块的升级指导
    随笔
    随笔
    c++11 lambda(了解)
    c++11 类型推断
    boost::archive::text_oarchive
    std::ostringstream
    随笔
    随笔1
  • 原文地址:https://www.cnblogs.com/riddick/p/7446029.html
Copyright © 2011-2022 走看看