2016-07-26 2 views
0

내가하고 싶은 황금은 이미지 1의 왼쪽에서 오른쪽으로 매트릭스를 변경하는 것입니다. 내가 아는 바로는 기본 변형 방법으로는 바꿀 수 없다는 것입니다.이미지를 불규칙한 사각형에서 사각형으로 변경하는 방법은 무엇입니까?

image1. change matrix from left to right

진짜 문제는 다음과 같은 이미지의 사각형을 가지고 있습니다. 불규칙한 사각형을 정사각형으로 변경해야합니다.

image2.

+0

이 당신을 도울 수있다 : [링크] (http://stackoverflow.com/questions/7838487/executing-cvwarpperspective-for-a-fake-deskewing-on-a-set-of-cvpoint) – s1h

+0

@ s1h 감사합니다. [링크] (http://stackoverflow.com/questions/7838487/executing-cvwarpperspective-for-a-fake-deskewing-on-a-set-of-cvpoint) 바로 내 대답입니다. –

답변

1

그래서, 첫 번째 문제는 코너 순서입니다. 그들은 두 벡터에서 같은 순서로 존재해야합니다. 따라서 첫 번째 벡터에서 (왼쪽 위, 왼쪽 아래, 오른쪽 아래, 오른쪽 위) 순서가 다른 벡터의 순서와 같아야합니다.

두 번째로 결과 이미지에 관심있는 대상 만 포함되도록하려면 너비와 높이를 결과 사각형의 너비와 높이와 같게 설정해야합니다. warpPerspective의 src 및 dst 이미지는 크기가 다를 수 있으므로 걱정하지 마십시오.

셋째, 성능 문제입니다. 귀하의 방법은 절대적으로 정확하지만, 수학적으로 아핀 변환 (회전, 크기 조정, 기울기 보정)만을 수행하고 있기 때문에, 귀하는 귀하의 기능의 아핀 공동 응답자를 사용할 수 있습니다. 그들은 훨씬 더 빠릅니다.

getAffineTransform() warpAffine().

중요 사항 : getAffine는 변환 요구를 단지 3 점을 예상하고, 상기 결과 행렬은 2가 3이며, 대신 3- 의해-3. 그래서 여기 당신이

cv::warpPerspective(src, dst, dst.size(), ...); 
use 

cv::Mat rotated; 
cv::Size size(box.boundingRect().width, box.boundingRect().height); 
cv::warpPerspective(src, dst, size, ...); 

및 프로그래밍 할당이 끝난 : 결과 이미지를 만드는 방법

입력 이외의 다른 크기를 가지고있다. 어쩌면

void main() 
{ 
    cv::Mat src = cv::imread("r8fmh.jpg", 1); 


    // After some magical procedure, these are points detect that represent 
    // the corners of the paper in the picture: 
    // [408, 69] [72, 2186] [1584, 2426] [1912, 291] 

    vector<Point> not_a_rect_shape; 
    not_a_rect_shape.push_back(Point(408, 69)); 
    not_a_rect_shape.push_back(Point(72, 2186)); 
    not_a_rect_shape.push_back(Point(1584, 2426)); 
    not_a_rect_shape.push_back(Point(1912, 291)); 

    // For debugging purposes, draw green lines connecting those points 
    // and save it on disk 
    const Point* point = &not_a_rect_shape[0]; 
    int n = (int)not_a_rect_shape.size(); 
    Mat draw = src.clone(); 
    polylines(draw, &point, &n, 1, true, Scalar(0, 255, 0), 3, CV_AA); 
    imwrite("draw.jpg", draw); 

    // Assemble a rotated rectangle out of that info 
    RotatedRect box = minAreaRect(cv::Mat(not_a_rect_shape)); 
    std::cout << "Rotated box set to (" << box.boundingRect().x << "," << box.boundingRect().y << ") " << box.size.width << "x" << box.size.height << std::endl; 

    Point2f pts[4]; 

    box.points(pts); 

    // Does the order of the points matter? I assume they do NOT. 
    // But if it does, is there an easy way to identify and order 
    // them as topLeft, topRight, bottomRight, bottomLeft? 

    cv::Point2f src_vertices[3]; 
    src_vertices[0] = pts[0]; 
    src_vertices[1] = pts[1]; 
    src_vertices[2] = pts[3]; 
    //src_vertices[3] = not_a_rect_shape[3]; 

    Point2f dst_vertices[3]; 
    dst_vertices[0] = Point(0, 0); 
    dst_vertices[1] = Point(box.boundingRect().width-1, 0); 
    dst_vertices[2] = Point(0, box.boundingRect().height-1); 

    Mat warpAffineMatrix = getAffineTransform(src_vertices, dst_vertices); 

    cv::Mat rotated; 
    cv::Size size(box.boundingRect().width, box.boundingRect().height); 
    warpAffine(src, rotated, warpAffineMatrix, size, INTER_LINEAR, BORDER_CONSTANT); 

    imwrite("rotated.jpg", rotated); 
} 
+0

http://stackoverflow.com/a/37381666/5294258 – sturkmen

관련 문제