Trouble/Vision

Python OpenCV solvePnP 이유 모를 type error

침닦는수건 2024. 2. 22. 11:58
반응형

OpenCV solvePnP 함수는 자세 초기화할 때 자주 쓰는 함수로 매우 익숙하다.

 

주요 주의사항으로는 입력값 3d point (object point), 2d point (image point), mtx(intrinsic matrix), distortion coefficient 들이 float이나 double 형을 유지해야 한다는 점이다. (float, double 섞여도 되지만 권장하진 않음.)

 

python이라면 np.float32이나 np.float64로 통일해서 사용해야 한다. 

 

그렇지 않으면 다음 에러를 만날 수 있다. 

cv2.error: OpenCV(4.7.0) /io/opencv/modules/calib3d/src/solvepnp.cpp:838: error: (-215:Assertion failed) ( (npoints >= 4) || (npoints == 3 && flags == SOLVEPNP_ITERATIVE && useExtrinsicGuess) || (npoints >= 3 && flags == SOLVEPNP_SQPNP) ) && npoints == std::max(ipoints.checkVector(2, CV_32F), ipoints.checkVector(2, CV_64F)) in function 'solvePnPGeneric'

 

문제는! type이 맞을 때도 위 오류가 나는 희귀한 경우가 가끔 있다는 것이다.

  # pt3ds, pt2ds, mtx, dist are all np.float64 in debugger
  ret, rvec, tvec = cv2.solvePnP(pt3ds, pt2ds, mtx, dist) # fail
  ret, rvec, tvec = cv2.solvePnP(pt3ds, pt2ds.astype(np.float64), mtx, dist) # success

 

원인은 모르겠다. debugger가 보기엔 각각이 np.float32 혹은 np.float64가 맞지만, (pt3ds, pt2ds, mtx, dist)의 값을 채우는 과정에서 사용한 값들이 내부적으로 어떻게 얽혀있나보다.

 

해결법은 어쩔 수 없이 value 하나마다 .astype(np.float64)를 선언해주면서 테스트해보는 수 밖에 없다. 

 

원인 아시는 분 설명 좀...

 

반응형