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
프레임 단위.
픽셀 거리 (하단)와 실제 거리 (상단)는 매우 유사해야합니다.
각도:
또한, 둘 다해야 undistortPoints()
하고 undistort()
동일한 결과 (여기에 비디오의 또 다른 세트)을 얻었다?
cv :: undistort 함수는 한 번에 왜곡 제거와 재 투영을 수행합니다. 다음 작업 목록을 수행합니다.
- 카메라 투영 실행 취소 (카메라 매트릭스의 역으로 곱하기)
- 왜곡을 취소하려면 왜곡 모델을 적용하십시오.
- 제공된 회전 행렬 R1 / R2로 회전
- 제공된 투영 행렬 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.
'developer tip' 카테고리의 다른 글
Safari 7 응용 프로그램 캐시가 작동하지 않습니다. (0) | 2020.11.22 |
---|---|
Google App Engine을 사용할 때 유효하지 않거나 누락 된 SSL 인증서 (0) | 2020.11.22 |
xperf WinDBG C # .NET 4.5.2 응용 프로그램-프로세스 덤프 이해 (0) | 2020.11.22 |
XE3에서 자동 업데이트로 라이브 바인딩 (XE2 에서처럼 Notify ()를 호출 할 필요 없음) (0) | 2020.11.22 |
WebRTC AGC (자동 이득 제어) (0) | 2020.11.22 |