2016-07-26 10 views
0

私がしたいと思っている金は、画像の左側から右側にマトリックスを変えることです。私が知っていることから、基本的な変換方法だけでは変更できません。不規則な長方形から長方形にイメージを変更するにはどうすればいいですか?

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

だから、最初の問題はコーナーオーダーです。両方のベクトルで同じ順序でなければなりません。したがって、最初のベクトルの順序が(左上、左下、右下、右上)である場合、それらは他のベクトルと同じ順序でなければなりません。

第2に、結果の画像に対象のオブジェクトだけが含まれるようにするには、その幅と高さを、結果の長方形の幅と高さと同じにする必要があります。 warpPerspectiveのsrcおよびdst画像は、サイズが異なる可能性がありますのでご安心ください。

第3に、パフォーマンスの問題です。あなたのメソッドは絶対に正確ですが、アファイン変換(回転、サイズ変更、デスキュー)を数学的に行っているだけなので、関数のアフィンコルセントントを使うことができます。彼らははるかに高速です。

getAffineTransform() warpAffine().

注意:getAffineニーズを変換し、わずか3点を期待し、その結果マトリックスではなく3×3の、2×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

関連する問題