2013-07-02 4 views
5

체스 보드에 대한 카메라의 상대 위치 (또는 다른 방향)를 찾으려고합니다. 다른 좌표계간에 변환하면 좋을 것 같습니다. 제안 된대로 here. 나는 findChessboardCorners을 사용하여 imagePoints을 얻을 수 있기 때문에이 단계에서 교정뿐만 아니라 실제 위치 결정도 체스 판을 사용하기로 결정했습니다.OpenCV : solvePnP tvec 단위 및 축 방향

나는이 주제에 대해 많이 읽었으며 과 컴퓨터 비전에 대해 완전히 익숙하지 않더라도 solvePnP 결과를 이해한다고 생각합니다. 불행하게도, solvePnP에서 얻은 결과와 실제 테스트 설정을 측정 한 결과는 다릅니다. z 방향으로의 이동이 약 빗나갑니다. 25 %. xy 방향은 완전히 잘못되었습니다. 카메라 좌표계 (x는 이미지를 가리키고, y는 카메라에서 멀리 떨어져 있음)로 읽은 것보다 몇 배와 다른 방향입니다. tvecrvec을 월드 좌표의 카메라 포즈로 변환하면 차이가 지속됩니다.

내 질문은 :

  • 카메라와 세계 체제 '좌표축의 방향은 무엇인가?
  • solvePnPobjectPoints을 지정했을 때와 동일한 단위로 번역을 출력합니까?
  • 나는 세계 기원을 objectPoints (체스 판 코너 중 하나)의 첫 번째로 지정했습니다. 그게 괜찮습니까 tvec 정확히 좌표에서 카메라 좌표로 번역?

이것은 내 코드입니다 (예외가 발생하지 않으므로 pro forma을 첨부합니다). 그레이 스케일 이미지를 사용하여 카메라 내장 함수 행렬 및 보정 중 왜곡 계수를 얻었으므로 회색 음영으로 현지화를 수행하기로 결정했습니다. chessCoordinates은 원점 (코너 포인트 중 하나)에 대한 체스 판 포인트 위치 목록 (mm 단위)입니다. camMatrixdistCoefficients은 보정 (동일한 체스 보드 및 objectPoints을 사용하여 수행)에서 왔습니다.

camCapture=cv2.VideoCapture(0) # Take a picture of the target to get the imagePoints 
tempImg=camCapture.read() 
imgPts=[] 
tgtPts=[] 

tempImg=cv2.cvtColor(tempImg[1], cv2.COLOR_BGR2GRAY) 
found_all, corners = cv2.findChessboardCorners(tempImg, chessboardDim) 

imgPts.append(corners.reshape(-1, 2)) 
tgtPts.append(np.array(chessCoordinates, dtype=np.float32)) 

retval,myRvec,myTvec=cv2.solvePnP(objectPoints=np.array(tgtPts), imagePoints=np.array(imgPts), cameraMatrix=camMatrix, distCoeffs=distCoefficients) 

답변

9

카메라 좌표는 이미지 좌표와 같습니다. 따라서 카메라에서 오른쪽으로 x 축을 향하고 y 축을 아래로 향하게하고 z 방향으로 카메라를 향하게합니다. 이것은 시계 방향의 도끼 시스템이며 체스 판에도 똑같이 적용됩니다. 따라서 체스 판의 오른쪽 위 모서리에서 원점을 지정하면 x ax는 오른쪽의 긴 쪽을 따라 가고 y의 짧은 쪽을 따라갑니다. 체스 판, z 도끼는 땅을 향하여 아래로 향할 것입니다.

Solve PnP는 체스 판 필드의 길이를 지정한 단위와 동일한 단위로 번역을 출력하지만 카메라 매트릭스를 사용하므로 카메라 보정에서 지정한 단위도 사용할 수 있습니다.

Tvec는 사용자가 캘리브레이션 개체를 배치 한 세계 좌표의 원점을 가리 킵니다. 따라서 첫 번째 객체 점을 (0,0)에 배치하면 tvec가 가리키는 점이 나타납니다.

+0

큰 답변, 고마워. 나는이 물건의 일부를 이전에 어딘가에 보냈지 만 약간의 확신을 얻는 것이 좋다. 또한, 시스템 축의 조정에 대한 설명은 매우 유용합니다. 건배. –

3

카메라 및 세계 좌표계의 축 방향은 무엇입니까?

보드의 0,0,0 모서리는 X & Y 축이 나머지 모서리 점을 향하도록합니다. Z 축은 항상 보드에서 멀리 향하고 있습니다. 이것은 보통 카메라의 방향을 가리키고 있음을 의미합니다.

solvePnP는 objectPoints를 지정하는 것과 동일한 단위로 변환을 출력합니까?

은 내가 objectPoints의 첫 번째로 세계 원점 (체스 판의 모서리 중 하나)를 지정했습니다. 괜찮습니까? 그리고 카메라 좌표에서 정확히 그 점으로의 변환이 있습니까?

예, 꽤 일반적입니다. 대부분의 경우 첫 번째 캠 모서리는 0,0,0으로 설정되고 이후 모서리는 z = 0 평면에 설정됩니다 (예 : (1,0,0), (0,1,0) 등) .

회전과 결합 된 tvec는 보드 좌표계에서 카메라 방향으로 그 지점을 향합니다. 간단히 말해서; tvec & rvec는 역 변환 (세계 -> 카메라)을 제공합니다. 몇 가지 기본 형상을 사용하면 카메라 -> 세계에 적용되는 변형을 계산할 수 있습니다.

+0

빠른 응답을 보내 주셔서 감사합니다. 카메라 좌표계 축은 어떨까요? 그들은 "가리키는"곳이 어디입니까? "회전과 결합 된 tvec는 보드 좌표계 **에서 ** 카메라 방향으로 그 점을 가리 킵니다." [this] (http://stackoverflow.com/questions/14515200/python-opencv-solvepnp-yields-wrong-translation-vector)에 따르면 tvec는 카메라 좌표계에 있습니다 ("카메라 방향"이 아닌). 이게 네가 말하는거야? –

+0

카메라 좌표계 Z가 카메라를 가리키는 방향 ("찾고있는 방향")에 있다고 생각합니다. 나는 세계 좌표계와 카메라 좌표계 사이에 차이가 있음을 의미합니다. rvec & tvec를 사용하여 "보드 프레임"에있는 점을 "카메라 프레임"으로 변환 할 수 있습니다. 카메라 프레임에서 월드 프레임으로 점을 변환하려면 두 점의 역을 사용해야합니다. – Nallath

+0

고마워, 나는 이미 위의 답변과 당신의 도움으로 큰 도움을 얻어 냈다. 모든 것이 이제는 의미가 있습니다. 건배. –