2016-07-26 158 views
0

我想要做的黃金是將矩陣從images1左側改爲右側。從我所知道的是,我們不能用基本的轉化方法來改變。如何將圖像從不規則矩形更改爲矩形?

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