圖像添加徑向畸變


通常攝像機的鏡頭都會有鏡頭畸變,尤其是廣角鏡頭,在做圖像處理中往往會通過攝像機標定獲取鏡頭的畸變系數,然后進行畸變校正。而在某些特殊的情況下,你可能會需要往圖像中加入畸變,下面簡單實現了一個向無畸變圖像中人為加入徑向畸變。

仍然以這幅風景圖為例,我用手機拍攝的,畸變程度可以忽略:

 

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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM