2013-10-19 3 views
1

현재 공중 이미지에서 이미지 왜곡을 보정하기 위해 Python에서 OpenCV를 사용하고 있습니다. 롤, 피치 및 요에 대한 데이터가 있습니다. 워프 매트릭스를 만들고 원래의 좌표 포인트에 매트릭스를 적용하여 이미지 출력 지점을 만들어야한다는 것을 알고 있습니다. 나는 이미지가 움직이는 방식에 영향을 미칠 수 있지만, 아주 작은 값에 대해서만 작용하는 유일한 값이기 때문에 에러가 있다고 생각한다. 당신은() 변환 행렬을 찾기 위해 getPerspectiveTransform를 사용하여 다음 네 개의 점을 투영하여 경사 행렬을 계산하는 코드의 시작 부분에서롤, 피치 및 요를 사용하여 이미지 뒤틀림

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

:

여기에 내 현재 코드입니다. 이것은 효과가 있지만 필요 이상으로 복잡합니다. 롤, 피치 및 요우 각을 알고있는 경우 변환 행렬을 직접 계산할 수 있습니다. http://image2measure.net/files/calib3Dto2D.cpp에서 BirdsEyeView() 함수를 살펴보십시오. 그것은 정확하게 그것을합니다.
나는 그것을 변환 권리를 얻기 위해
Mat R = RZ * RX * RY; 에 라인을
Mat R = RX * RY * RZ; 을 변경했다.

f은 픽셀 단위의 초점 거리입니다. RH 수평 이미지의 해상도 카메라의 수평 개방 각도
경우
위한 F = (RH/2)/탄 (OH/2)
선택 동일한 값 거리
이미지의 크기를 조절하지 않으려면 f보다 큰 이미지를 확대하거나 축소하려면 더 큰 이미지를 사용하십시오.

0

BirdsEyeView() 코드는 저에게는 효과적이지만 롤 및 피치 각이 교환되는 이유를 알지 못합니다. "알파"를 바꿀 때 이미지가 피치에 뒤틀려서 "베타"를 바꿀 때 이미지가 휜 상태로 뒤틀려 있습니다. 그래서 아래에서 볼 수 있듯이 회전 행렬을 변경했습니다.

또한 RY에는 신호 오류가 있습니다. 당신은 Ry를 확인할 수 있습니다 : http://en.wikipedia.org/wiki/Rotation_matrix 이것이 Adrian이 R = RX * RY * RZ에서 R = RZ * RX * RY로 곱셈 순서를 변경 한 이유라고 생각합니다.

회전 메트릭스 내가 사용

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); 

감사