2013-10-19 38 views
1

我目前在Python中使用OpenCV來校正航拍圖像中的圖像失真。我有滾動,俯仰和偏航的數據。我知道我需要創建一個扭曲矩陣,並將該矩陣應用到我的原始座標點以創建圖像的輸出點。我能夠影響圖像的移動方式,但是我覺得有一個錯誤,因爲唯一的值似乎適用於非常小的值。使用滾動,俯仰和偏航來翹曲圖像

這裏是我當前的代碼:

warp_mat = np.array([[math.cos(theta)*math.cos(psy), math.cos(phi)*math.sin(psy)+math.sin(phi)*math.sin(theta)*math.cos(psy), math.sin(phi)*math.sin(psy)-math.cos(phi)*math.sin(theta)*math.cos(psy)],\ 
        [-1*math.cos(theta)*math.sin(psy), math.cos(phi)*math.cos(psy)-math.sin(phi)*math.sin(theta)*math.sin(psy), math.sin(phi)*math.cos(psy)+math.cos(phi)*math.sin(theta)*math.sin(psy)],\ 
        [math.sin(theta), -1*math.sin(phi)*math.cos(theta), math.cos(phi)*math.cos(theta)]], dtype='float32') 


srcPts = np.array([[-2064, 1161, 1],\ 
        [2064, 1161, 1],\ 
        [2064, -1161, 1],\ 
        [-2064, -1161, 1]], dtype='float32') 

dstPts = np.empty(shape = (4,3), dtype='float32') 


dstPts[0][0] = srcPts[0][0] * warp_mat[0][0] + srcPts[0][1] * warp_mat[1][0] + srcPts[0][2] * warp_mat[2][0]; 
dstPts[0][1] = srcPts[0][0] * warp_mat[0][1] + srcPts[0][1] * warp_mat[1][1] + srcPts[0][2] * warp_mat[2][1]; 
dstPts[0][2] = srcPts[0][0] * warp_mat[0][2] + srcPts[0][1] * warp_mat[1][2] + srcPts[0][2] * warp_mat[2][2]; 

dstPts[1][0] = srcPts[1][0] * warp_mat[0][0] + srcPts[1][1] * warp_mat[1][0] + srcPts[1][2] * warp_mat[2][0]; 
dstPts[1][1] = srcPts[1][0] * warp_mat[0][1] + srcPts[1][1] * warp_mat[1][1] +  srcPts[1][2] * warp_mat[2][1]; 
dstPts[1][2] = srcPts[1][0] * warp_mat[0][2] + srcPts[1][1] * warp_mat[1][2] + srcPts[1][2] * warp_mat[2][2]; 

dstPts[2][0] = srcPts[2][0] * warp_mat[0][0] + srcPts[2][1] * warp_mat[1][0] + srcPts[2][2] * warp_mat[2][0]; 
dstPts[2][1] = srcPts[2][0] * warp_mat[0][1] + srcPts[2][1] * warp_mat[1][1] + srcPts[2][2] * warp_mat[2][1]; 
dstPts[2][2] = srcPts[2][0] * warp_mat[0][2] + srcPts[2][1] * warp_mat[1][2] + srcPts[2][2] * warp_mat[2][2]; 

dstPts[3][0] = srcPts[3][0] * warp_mat[0][0] + srcPts[3][1] * warp_mat[1][0] + srcPts[3][2] * warp_mat[2][0]; 
dstPts[3][1] = srcPts[3][0] * warp_mat[0][1] + srcPts[3][1] * warp_mat[1][1] + srcPts[3][2] * warp_mat[2][1]; 
dstPts[3][2] = srcPts[3][0] * warp_mat[0][2] + srcPts[3][1] * warp_mat[1][2] + srcPts[3][2] * warp_mat[2][2]; 


dstPts[0][0] = dstPts[0][0]/dstPts[0][2]; 
dstPts[0][1] = dstPts[0][1]/dstPts[0][2]; 
dstPts[0][2] = dstPts[0][2]/dstPts[0][2]; 

dstPts[1][0] = dstPts[1][0]/dstPts[1][2]; 
dstPts[1][1] = dstPts[1][1]/dstPts[1][2]; 
dstPts[1][2] = dstPts[1][2]/dstPts[1][2]; 

dstPts[2][0] = dstPts[2][0]/dstPts[2][2]; 
dstPts[2][1] = dstPts[2][1]/dstPts[2][2]; 
dstPts[2][2] = dstPts[2][2]/dstPts[2][2]; 

dstPts[3][0] = dstPts[3][0]/dstPts[3][2]; 
dstPts[3][1] = dstPts[3][1]/dstPts[3][2]; 
dstPts[3][2] = dstPts[3][2]/dstPts[3][2]; 



srcPts2 = np.array([[srcPts[0][0],srcPts[0][1]],\ 
        [srcPts[1][0],srcPts[1][1]],\ 
        [srcPts[2][0],srcPts[2][1]],\ 
        [srcPts[3][0],srcPts[3][1]]], dtype='float32') 

dstPts2 = np.array([[dstPts[0][0],dstPts[0][1]],\ 
        [dstPts[1][0],dstPts[1][1]],\ 
        [dstPts[2][0],dstPts[2][1]],\ 
        [dstPts[3][0],dstPts[3][1]]], dtype='float32') 


transMatrix = cv.getPerspectiveTransform(srcPts2, dstPts2) 


dst = cv.warpPerspective(imgFile,transMatrix,(4128,2322) ,borderMode = cv.BORDER_CONSTANT,borderValue = 0) 

回答

0

在你的代碼的開頭你被投射四點計算經矩陣,然後使用getPerspectiveTransform()來找出轉換矩陣。這應該起作用,但它比必要更復雜。如果您知道橫搖角,俯仰角和偏航角,則可以直接計算變換矩陣。看看http://image2measure.net/files/calib3Dto2D.cpp中的函數BirdsEyeView()。它確實如此。
我不得不
Mat R = RX * RY * RZ; 行更改爲
Mat R = RZ * RX * RY; 爲了得到它的改造權。

f是以像素爲單位的焦距。
如果RH是圖像的水平分辨率和照相機的水平開口角度
F =(RH/2)/黃褐色(OH/2)
選擇相同爲值距離如果你不想縮放圖像,比f要大一些,或者縮小一個,縮小它。

0

代碼BirdsEyeView()適用於我,但我不知道爲什麼Roll和Pitch角度交換。當我改變「alpha」時,圖像會在音調中變形,而當我改變「beta」時,圖像會在滾動中扭曲。所以,我改變了我的旋轉矩陣,如下所示。

另外,RY有信號錯誤。你可以檢查Ry:http://en.wikipedia.org/wiki/Rotation_matrix 我想這就是爲什麼Adrian將乘法順序從R = RX * RY * RZ改爲R = RZ * RX * RY的原因。

旋轉Metrix的使用:

Mat RX = (Mat_<double>(4, 4) << 
     1,   0,   0, 0, 
     0, cos(beta), -sin(beta), 0, 
     0, sin(beta), cos(beta), 0, 
     0,   0,   0, 1); 

    Mat RY = (Mat_<double>(4, 4) << 
     cos(alpha), 0, sin(alpha), 0, 
        0, 1,   0, 0, 
     -sin(alpha), 0, cos(alpha), 0, 
        0, 0,   0, 1); 

    Mat RZ = (Mat_<double>(4, 4) << 
     cos(gamma), -sin(gamma), 0, 0, 
     sin(gamma), cos(gamma), 0, 0, 
     0,   0,   1, 0, 
     0,   0,   0, 1); 

問候

相關問題