一 攝像機(jī)成像模型成像的過(guò)程實(shí)質(zhì)上是幾個(gè)坐標(biāo)系的轉(zhuǎn)換。首先空間中的一點(diǎn)由世界坐標(biāo)系轉(zhuǎn)換到攝像機(jī)坐標(biāo)系,然后再將其投影到成像平面(攝像機(jī)的CCD),最后再將成像平面上的數(shù)據(jù)轉(zhuǎn)換到圖像平面(最后生成的圖像)。 圖1-1 世界空間內(nèi)的一個(gè)點(diǎn)在圖像上成像的過(guò)程稱為投影成像過(guò)程,這中間轉(zhuǎn)換過(guò)程構(gòu)成的矩陣M稱為投影矩陣。 攝像機(jī)的畸變參數(shù)與相機(jī)成像時(shí)采用的分辨率無(wú)關(guān),而fx,fy和光心位置cx,cy與分辨率有關(guān),但是成倍數(shù)關(guān)系,例如在分辨率320×240分辨率標(biāo)定得到內(nèi)參數(shù)為fx0,fy0,cx0,cy0,那么在分辨率640×480下對(duì)應(yīng)的參數(shù)則為2fx0,2fy0,2cx0,2cy0。 上面這些參數(shù)中,f,t所采用的量綱都是mm,而dx和dy指的是每個(gè)像素個(gè)數(shù)的大小,即mm/pixel,那么經(jīng)過(guò)換算最后得到的u、v的量綱自然也就是像素。fx和fy是由f/dx,f/dy計(jì)算而來(lái),表示的是長(zhǎng)度值為f時(shí)對(duì)應(yīng)的像素個(gè)數(shù),也即長(zhǎng)度值為f(mm)時(shí),在圖像平面的x方向和y方向的像素個(gè)數(shù),fx、fy、u0、v0構(gòu)成A,A右邊的數(shù)據(jù)為[R|t]M’,看起來(lái)[R|t]M’對(duì)應(yīng)的數(shù)據(jù)的量綱好像是mm,因?yàn)镸’和t的量綱都是mm,這樣A里面的量綱又為像素,這樣乘起來(lái)的量綱就是mm*pixel了,這顯然不對(duì)。但是事實(shí)情況并不是真的這樣,最后[R|t]M’與A相乘的時(shí)候,[R|t]M’的結(jié)果是需要進(jìn)行歸一化的,即[xc yc zc 1] →[xc/zc yc/zc 1],這個(gè)時(shí)候它的量綱其實(shí)就只是倍數(shù)了。整個(gè)過(guò)程如下圖 圖 1-2 opencv標(biāo)定出來(lái)的內(nèi)參數(shù)矩陣一般為(分辨率為640×480) <Camera_Matrix type_id="opencv-matrix"> <rows>3</rows> <cols>3</cols> <dt>d</dt> <data> 5.3193633829444082e+002 0. 3.1950000000000000e+002 0. 5.3193633829444082e+002 2.3950000000000000e+002 0. 0. 1.</data></Camera_Matrix> 這里的fx≈531.9,fy≈531.9,u0=319.5,v0=239.5。u0和v0比較好理解,差不多就是圖像的中心,但是這里的fx和fy為500多還是有點(diǎn)抽象,雖然前面已經(jīng)說(shuō)了表示焦距長(zhǎng)度對(duì)應(yīng)的像素個(gè)數(shù)。根據(jù)上圖中u和v的計(jì)算公式,還有標(biāo)定的內(nèi)參矩陣值,其實(shí)可以反推出x’、y’的大致大小,這里u的最大值是640,v的最大值為480,用這些值可以算出x’和y’的最大值分別為0.6025和0.4521,它們分別代表經(jīng)過(guò)Z值歸一化后的比例值,這個(gè)值實(shí)質(zhì)上反映了相機(jī)的視角。 二 成像畸變在沒(méi)有畸變的情況下,理想的成像的過(guò)程是如圖1-2所示 但是在實(shí)際的情況中,真正的鏡頭通常有一些形變,主要的變形為徑向形變,也會(huì)有輕微的切向形變。所以上面的模型需要擴(kuò)展為: 圖2-1 k1和k2是徑向形變系數(shù),p1和p2是切向形變系數(shù)。OpenCV中沒(méi)有考慮高階系數(shù)。形變系數(shù)跟拍攝的場(chǎng)景無(wú)關(guān),因此它們是內(nèi)參數(shù),而且與拍攝圖像的分辨率無(wú)關(guān)。參見(jiàn)opencv中文wiki opencv計(jì)算得到的畸變參數(shù)形式為: <Distortion_Coefficients type_id="opencv-matrix"> <rows>5</rows> <cols>1</cols> <dt>d</dt> <data> 6.7442695842244271e-002 2.4180872220967919e-001 0. 0. -3.3970575589699975e-001</data></Distortion_Coefficients> 對(duì)應(yīng)存放的畸變參數(shù)為[k1,k2,p1,p2[,k3[,k4,k5,k6]] 三 畸變校正根據(jù)前面的說(shuō)明,可以知道攝像機(jī)拍下來(lái)的圖片是存在畸變的,現(xiàn)在需要根據(jù)內(nèi)參矩陣和畸變參數(shù)對(duì)存在畸變的圖像進(jìn)行校正。校正的過(guò)程就是就是圖2-1描述的過(guò)程。 首先是根據(jù)拍攝得到的存在畸變圖像的坐標(biāo),計(jì)算出根據(jù)畸變模型得到的校正圖像對(duì)應(yīng)的坐標(biāo),這樣就建立了畸變圖像坐標(biāo)和校正圖像坐標(biāo)之間的映射關(guān)系。同時(shí)計(jì)算出來(lái)的校正坐標(biāo)存在小數(shù),所以就需要對(duì)其插值。 例如XYsrc(1,1)<-->XYrect(1.5,1.0),那么假如采用簡(jiǎn)單的線性插值的話,Irect(1.5,1.0)=[Isrc(1,1)+Isrc(2,1)]*0.5 Irect就是算出來(lái)的校正后的像素值。 進(jìn)行畸變的matlab校正代碼(參見(jiàn)stackoverflow)如下:
clear; clc; A =[5.9418398977142772e+002 0 3.1950000000000000e+002; 0 5.941839897714e+002 2.3950000000000000e+002; 0 0 1]; D = [6.7442695842244271e-002 2.4180872220967919e-001 0 0 -3.3970575589699975e-001]; fx = A(1,1); fy = A(2,2); cx = A(1,3); cy = A(2,3); k1 = D(1); k2 = D(2); k3 = D(5); p1 = D(3); p2 = D(4); K = A; Idistorted = imread('logi.jpg'); Idistorted = rgb2gray(Idistorted); Idistorted = im2double(Idistorted); I = zeros(size(Idistorted)); [i j] = find(~isnan(I)); % Xp = the xyz vals of points on the z plane Xp = inv(K)*[j i ones(length(i),1)]'; % Now we calculate how those points distort i.e forward map them through the distortion r2 = Xp(1,:).^2+Xp(2,:).^2; x = Xp(1,:); y = Xp(2,:); x = x.*(1+k1*r2 + k2*r2.^2) + 2*p1.*x.*y + p2*(r2 + 2*x.^2); y = y.*(1+k1*r2 + k2*r2.^2) + 2*p2.*x.*y + p1*(r2 + 2*y.^2); % u and v are now the distorted cooridnates u = reshape(fx*x + cx,size(I)); v = reshape(fy*y + cy,size(I)); % Now we perform a backward mapping in order to undistort the warped image coordinates I = interp2(Idistorted, u, v); subplot(121); imagesc(Idistorted); subplot(122); imagesc(I); 得到的結(jié)果圖為: 摘自:http://blog.csdn.net/kfqcome/article/details/9411711 |
|