逆透视变换详解 及 代码实现(二)
根據(jù) 逆透視變換詳解 及 代碼實現(xiàn)(一)的原理
下面我用車上拍攝的車道圖像,采用逆透視變換得到的圖像,給出代碼前我們先看下處理結(jié)果。
?
首先是原始圖像:
下圖為逆透視變換圖像:
?
下面說具體的實現(xiàn)吧!!
一、參數(shù)設(shè)置:
1、需要知道相機(jī)的內(nèi)部參數(shù)(這個具體步驟可以找相關(guān)文檔,這里就不具體展開說)。
我們這里假設(shè)已經(jīng)獲取內(nèi)部參數(shù):
相機(jī)焦距,相機(jī)光學(xué)中心, 相機(jī)高度, 相機(jī)的俯仰角, 相機(jī)的偏航角, 相機(jī)拍攝出的圖像尺寸。
參數(shù)說明: ?其中偏航角 和 俯仰角 就是在(一)中所說的世界坐標(biāo)經(jīng)過旋轉(zhuǎn)矩陣得到相應(yīng)的相機(jī)坐標(biāo)。 ?而偏航角和俯仰角將決定這個旋轉(zhuǎn)矩陣。 ?而相機(jī)焦距 ?和相機(jī)光學(xué)中心 是可以從相機(jī)標(biāo)定后得出 ,相機(jī)高度需要自己測量。
而圖像尺寸,是拍出圖像的尺寸。
2、 設(shè)定逆透視變換的參數(shù):
逆透視圖像的尺寸,需要進(jìn)行逆透視變換的區(qū)域,逆透視變換的差值算法。
逆透視變換的區(qū)域:原始圖像中需要變換的區(qū)域(當(dāng)然這個區(qū)域不能超過消失點區(qū)域,后面會說到)
逆透視圖像的尺寸: 就是需要將逆透視變換區(qū)域映射到這個逆透視圖像上。
差值算法:因為需要映射,所以某些數(shù)值需要估計出,這里用雙線性差值。
?
二、
根據(jù)相機(jī)的內(nèi)部參數(shù)計算消失點:
因為圖像是二維的,所以消失點是是一個二維坐標(biāo)。
code:
?
function [ vp ] = GetVanishingPoint( cameraInfo ) %GetVanishingPoint Summary of this function goes here % Detailed explanation goes herevpp = [ sin(cameraInfo.yaw*pi/180)/cos(cameraInfo.pitch*pi/180);cos(cameraInfo.yaw*pi/180)/cos(cameraInfo.pitch*pi/180);0];tyawp = [cos(cameraInfo.yaw*pi/180), -sin(cameraInfo.yaw*pi/180), 0; sin(cameraInfo.yaw*pi/180), cos(cameraInfo.yaw*pi/180), 0;0, 0, 1];tpitchp = [1, 0, 0;0, -sin(cameraInfo.pitch*pi/180), -cos(cameraInfo.pitch*pi/180);0, cos(cameraInfo.pitch*pi/180), -sin(cameraInfo.pitch*pi/180)];transform = tyawp*tpitchp;t1p = [cameraInfo.focalLengthX, 0, cameraInfo.opticalCenterX;0, cameraInfo.focalLengthY, cameraInfo.opticalCenterY;0, 0, 1]; transform = t1p*transform;vp = transform*vpp;end
三、利用消失點可以得到uv平面中的圖像范圍和對應(yīng)的xy平面的范圍
?
code:
?
uvLimitsp = [ vp.x, ipmInfo.ipmRight, ipmInfo.ipmLeft, vp.x;ipmInfo.ipmTop, ipmInfo.ipmTop, ipmInfo.ipmTop, ipmInfo.ipmBottom];xyLimits = TransformImage2Ground(uvLimitsp,cameraInfo);?
function [ xyLimits ] = TransformImage2Ground( uvLimits,cameraInfo ) %TransformImage2Ground Summary of this function goes here % Detailed explanation goes here [row , col ] = size(uvLimits); inPoints4 = zeros(row+2,col); inPoints4(1:2,:) = uvLimits; inPoints4(3,:) = 1; inPoints3 = inPoints4(1:3,:);c1 = cos(cameraInfo.pitch*pi/180); s1 = sin(cameraInfo.pitch*pi/180); c2 = cos(cameraInfo.yaw*pi/180); s2 = sin(cameraInfo.yaw*pi/180);matp= [-cameraInfo.cameraHeight*c2/cameraInfo.focalLengthX,cameraInfo.cameraHeight*s1*s2/cameraInfo.focalLengthY,(cameraInfo.cameraHeight*c2*cameraInfo.opticalCenterX/cameraInfo.focalLengthX)- (cameraInfo.cameraHeight *s1*s2* cameraInfo.opticalCenterY/ cameraInfo.focalLengthY) - cameraInfo.cameraHeight *c1*s2;cameraInfo.cameraHeight *s2/cameraInfo.focalLengthX, ...cameraInfo.cameraHeight *s1*c2/cameraInfo.focalLengthY, ...(-cameraInfo.cameraHeight *s2* cameraInfo.opticalCenterX ..../cameraInfo.focalLengthX)-(cameraInfo.cameraHeight *s1*c2* ....cameraInfo.opticalCenterY /cameraInfo.focalLengthY) - ...cameraInfo.cameraHeight *c1*c2;0, cameraInfo.cameraHeight *c1/cameraInfo.focalLengthY, (-cameraInfo.cameraHeight *c1* cameraInfo.opticalCenterY/cameraInfo.focalLengthY)+cameraInfo.cameraHeight*s1;0, -c1 /cameraInfo.focalLengthY,(c1* cameraInfo.opticalCenterY /cameraInfo.focalLengthY) - s1];inPoints4 = matp*inPoints3; inPointsr4 = inPoints4(4,:); div = inPointsr4; inPoints4(1,:) = inPoints4(1,:)./div; inPoints4(2,:) = inPoints4(2,:)./div; inPoints2 = inPoints4(1:2,:); xyLimits = inPoints2;end
四、根據(jù)得到的范圍計算xy平面的一一對應(yīng)的映射
?
?
row1 = xyLimits(1,:); row2 = xyLimits(2,:); xfMin = min(row1); xfMax = max(row1); yfMin = min(row2); yfMax = max(row2);[outRow outCol] = size(outImage); stepRow = (yfMax - yfMin)/outRow; stepCol = (xfMax - xfMin)/outCol; xyGrid = zeros(2,outRow*outCol); y = yfMax-0.5*stepRow;for i = 1:outRowx = xfMin+0.5*stepCol;for j = 1:outColxyGrid(1,(i-1)*outCol+j) = x;xyGrid(2,(i-1)*outCol+j) = y;x = x + stepCol;endy = y - stepRow; end
五、將xy平面的映射轉(zhuǎn)換到uv平面,并畫出這個映射
?
?
%TransformGround2Image uvGrid = TransformGround2Image(xyGrid,cameraInfo); % Image mean means = mean(R(:))/255; RR = double(R)/255; for i=1:outRowfor j = 1:outCol;ui = uvGrid(1,(i-1)*outCol+j);vi = uvGrid(2,(i-1)*outCol+j);if (ui<ipmInfo.ipmLeft || ui>ipmInfo.ipmRight || vi<ipmInfo.ipmTop || vi>ipmInfo.ipmBottom) outImage(i,j) = means;elsex1 = int32(ui); x2 = int32(ui+1);y1 = int32(vi); y2 = int32(vi+1);x = ui-double(x1) ; y = vi-double(y1);val = double(RR(y1,x1))*(1-x)*(1-y)+double(RR(y1,x2))*x*(1-y)+double(RR(y2,x1))*(1-x)*y+double(RR(y2,x2))*x*y;outImage(i,j) = val;endend end
最終可以顯示這個圖像:如上面的逆透視變化圖像!
?
具體的code,可以在這里下載。如果問題可以留言交流!!
?
##修改時間2019-01-23##begin##
鑒于目前csdn下載積分需求比較高,我把代碼掛在github上
?https://github.com/yeyang1021/matlab_IPM?
##修改時間2019-01-23##end##
?
另外,如果需要標(biāo)定相機(jī)的可以參考這篇博文:
http://blog.csdn.net/yeyang911/article/details/52382722
?
總結(jié)
以上是生活随笔為你收集整理的逆透视变换详解 及 代码实现(二)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 题解P3942_将军令
- 下一篇: keepalived高可用+nginx负