좋아, 나는 OpenCV의 초심자이며 MATLAB/lin이라는 것을 인정해야한다. 대수 지식은 편향을 도입 할 수 있습니다. 그러나 내가하고 싶은 일은 정말 간단합니다. 그래도 나는 대답을 찾을 수 없었습니다.OpenCV warpPerspective - 대상 이미지 크기를 아는 방법?
- 가 변형 찾기 : 투시 변환 하에서 화상 (또는 화상의 일부) 정류하려고하면
하면 기본적 (는 왜곡 된 객체를 정의하는 4 점을 가정 함)의 두 단계를 수행 일부 완벽한 직사각형과 왜곡 된 모양 사이 (OpenCV에서
findHomography()
또는getPerspectiveTransform()
을 통해 - 왜이 두 점이 같은 점에서 다르게 작동하는지는 또 다른 이야기이며 실망 스럽습니다). 이것은 행렬 T를 제공합니다. (OpenCV에서는warpPerspective()
으로 끝납니다.) 처음 변형 된 모양에 T의 역함수를 적용하여 직사각형으로 변환합니다.
이제이 마지막 기능()은 대상 이미지의 크기를 지정하도록 사용자에게 요청합니다.
제 질문은 사용자가 미리 알고 있어야하는 크기입니다. 저레벨의 방법은 객체가있는 이미지의 모서리 점에 변형 T를 적용하는 것입니다. 따라서 새로 변형 된 모양으로 경계를 벗어나지 않도록 보장 할 수 있습니다. 그러나 매트릭스를 T에서 꺼내어 수동으로 그 점에 적용하더라도 결과가 이상하게 보입니다.
OpenCV에서이 작업을 수행 할 수있는 방법이 있습니까? 감사!
P.
float leftX, lowerY, rightX, higherY;
float minX = std::numeric_limits<float>::max(), maxX = std::numeric_limits<float>::min(), minY = std::numeric_limits<float>::max(), maxY = std::numeric_limits<float>::min();
Mat value, pt;
for(int i=0; i<4; i++)
{
switch(i)
{
case 0:
pt = (Mat_<float>(3, 1) << 1.00,1.00,1.00);
break;
case 1:
pt = (Mat_<float>(3, 1) << srcIm.cols,1.00,1.00);
break;
case 2:
pt = (Mat_<float>(3, 1) << 1.00,srcIm.rows,1.00);
break;
case 3:
pt = (Mat_<float>(3, 1) << srcIm.cols,srcIm.rows,1.00);
break;
default:
cerr << "Wrong switch." << endl;
break;
}
value = invH*pt;
value /= value.at<float>(2);
minX = min(minX,value.at<float>(0));
maxX = max(maxX,value.at<float>(0));
minY = min(minY,value.at<float>(1));
maxY = max(maxY,value.at<float>(1));
}
leftX = std::min<float>(1.00,-minX);
lowerY = std::min<float>(1.00,-minY);
rightX = max(srcIm.cols-minX,maxX-minX);
higherY = max(srcIm.rows-minY,maxY-minY);
warpPerspective(srcIm, dstIm, H, Size(rightX-leftX,higherY-lowerY), cv::INTER_CUBIC);
UPDATE : 아래의 일부 코드이다 내가 사용 행렬이 잘못 때문에 아마도 내 결과가 좋아 보이지 않습니다. getPerspectiveTransform()
내부에서 일어나는 일을 관찰 할 수 없기 때문에이 행렬이 어떻게 계산되는지는 알 수 없지만 매우 작고 매우 큰 값을 가지기 때문에 쓰레기라고 생각합니다. 이 I는 T에서 데이터를 획득하는 방법이다
for(int row=0;row<3;row++)
for(int col=0;col<3;col++)
T.at<float>(row,col) = ((float*)(H.data + (size_t)H.step*row))[col];
이인가 (getPerspectiveTransform()
의 출력 행렬은 3 × 3은 분할 폴트 T.at<float>(row,col)
리드를 통해 직접 값을 액세스하려고하지만). 그것을 할 올바른 방법? 아마도 올바른 행렬을 얻지 못했기 때문에 원래의 문제가 발생했을 것입니다 ...
저수준 방식이 나에게 맞는 것 같습니다. "결과가 이상하게 보인다"는 것은 무엇을 의미합니까? 문제를 보여주기 위해 최소한의 예제 코드를 만들 수 있습니까? –
나는 내가 얻은 좌표가 원본 이미지의 내부에 있다는 것을 의미한다. (이미지를 표시하기 때문에 그 결과가 이상하게 보일 뿐이고, 그 부분 일 뿐이다.) 이는 아마도 행렬 T가 내가 기대 한 것과 다르다는 것을 의미한다. 정상화되었거나 그와 비슷한 것이지, 포인트를 직접 조작하지 않아도 되는가? ...? – bloodymir
@Dobi 먼저 행렬 값을 얻는 방법에 대한 코드를 추가했습니다. 아마도 이것은 오류가 발생하는 곳입니다 ... – bloodymir