developer tip

OpenCV undistortPoints 및 triangulatePoint가 이상한 결과 (스테레오)를 제공합니다.

optionbox 2020. 11. 22. 19:22
반응형

OpenCV undistortPoints 및 triangulatePoint가 이상한 결과 (스테레오)를 제공합니다.


공간에서 여러 지점의 3D 좌표를 얻으려고하는데 undistortPoints()triangulatePoints().

두 카메라 모두 해상도가 다르기 때문에 개별적으로 보정하고 0,34및의 RMS 오류를 얻은 0,43다음 stereoCalibrate()더 많은 행렬을 얻고 RMS를 얻은 0,708다음 stereoRectify()나머지 행렬을 얻는 데 사용 했습니다. 그것을 손에 들고 좌표를 모아 작업을 시작했지만 이상한 결과를 얻었습니다.

예를 들어, 입력은 : (935, 262)이고 undistortPoints()출력은 (1228.709125, 342.79841)한 점에 대한 것이고 다른 점은 각각 (934, 176)(1227.9016, 292.4686)각각입니다. 이 두 점이 왜곡이 가장 작은 프레임 중앙에 매우 가깝기 때문에 이상합니다. 나는 그것이 300 픽셀만큼 움직일 것이라고 기대하지 않았습니다.

에 전달 traingulatePoints()하면 결과가 더 이상해집니다. 실생활에서 세 점 사이의 거리 (자 사용)를 측정하고 각 사진의 픽셀 사이의 거리를 계산했습니다. 이번에는 포인트가 매우 평평한 평면에 있었기 때문에 | AB | / | BC |에서와 같이이 두 길이 (픽셀 및 실제)가 일치했습니다. 두 경우 모두 약 4/9였습니다. 그러나 triangulatePoints()| AB | / | BC | 3/2 또는 4/2입니다.

이것은 내 코드입니다.

double pointsBok[2] = { bokList[j].toFloat()+xBok/2, bokList[j+1].toFloat()+yBok/2 };
cv::Mat imgPointsBokProper = cv::Mat(1,1, CV_64FC2, pointsBok);

double pointsTyl[2] = { tylList[j].toFloat()+xTyl/2, tylList[j+1].toFloat()+yTyl/2 };
//cv::Mat imgPointsTyl = cv::Mat(2,1, CV_64FC1, pointsTyl);
cv::Mat imgPointsTylProper = cv::Mat(1,1, CV_64FC2, pointsTyl);

cv::undistortPoints(imgPointsBokProper, imgPointsBokProper, 
      intrinsicOne, distCoeffsOne, R1, P1);
cv::undistortPoints(imgPointsTylProper, imgPointsTylProper, 
      intrinsicTwo, distCoeffsTwo, R2, P2);

cv::triangulatePoints(P1, P2, imgWutBok, imgWutTyl, point4D);

double wResult = point4D.at<double>(3,0);
double realX = point4D.at<double>(0,0)/wResult;
double realY = point4D.at<double>(1,0)/wResult;
double realZ = point4D.at<double>(2,0)/wResult;

점 사이의 각도는 다소 좋지만 일반적으로 그렇지 않습니다.

`7,16816    168,389 4,44275` vs `5,85232    170,422 3,72561` (degrees)
`8,44743    166,835 4,71715` vs `12,4064    158,132 9,46158`
`9,34182    165,388 5,26994` vs `19,0785    150,883 10,0389`

나는 undistort()전체 프레임에서 사용하려고 시도 했지만 결과가 이상했습니다. B 지점과 C 지점 사이의 거리는 항상 거의 변하지 않아야하지만 이것이 제가 얻는 것입니다.

7502,42     
4876,46 
3230,13 
2740,67 
2239,95 

프레임 단위.

픽셀 거리 (하단)와 실제 거리 (상단)는 매우 유사해야합니다. | BC |  거리

각도:

ABC 각도

또한, 둘 다해야 undistortPoints()하고 undistort()동일한 결과 (여기에 비디오의 또 다른 세트)을 얻었다?
여기에 이미지 설명 입력


cv :: undistort 함수는 한 번에 왜곡 제거와 재 투영을 수행합니다. 다음 작업 목록을 수행합니다.

  1. 카메라 투영 실행 취소 (카메라 매트릭스의 역으로 ​​곱하기)
  2. 왜곡을 취소하려면 왜곡 모델을 적용하십시오.
  3. 제공된 회전 행렬 R1 / R2로 회전
  4. 제공된 투영 행렬 P1 / P2를 사용하여 이미지를 투영합니다.

If you pass the matrices R1, P1 resp. R2, P2 from cv::stereoCalibrate(), the input points will be undistorted and rectified. Rectification means that the images are transformed in a way such that corresponding points have the same y-coordinate. There is no unique solution for image rectification, as you can apply any translation or scaling to both images, without changing the alignement of corresponding points. That being said, cv::stereoCalibrate() can shift the center of projection quite a bit (e.g. 300 pixels). If you want pure undistortion you can pass an Identity Matrix (instead of R1) and the original camera Matrix K (instead of P1). This should lead to pixel coordinates similar to the original ones.

참고URL : https://stackoverflow.com/questions/32227595/opencv-undistortpoints-and-triangulatepoint-give-odd-results-stereo

반응형