Heim >Backend-Entwicklung >C++ >Warum führt meine cv::warpPerspective-Entzerrungsimplementierung zu falschen Ergebnissen und wie kann ich das beheben?

Warum führt meine cv::warpPerspective-Entzerrungsimplementierung zu falschen Ergebnissen und wie kann ich das beheben?

DDD
DDDOriginal
2024-11-23 03:32:11669Durchsuche

Why Does My cv::warpPerspective Deskewing Implementation Produce Incorrect Results, and How Can I Fix It?

So führen Sie cv::warpPerspective korrekt aus, um eine Reihe von Punkten auszurichten

Problem:

Versuche, cv zu verwenden Die Verwendung von ::warpPerspective zur Erzielung eines Entzerrungseffekts auf eine Reihe von Punkten hat zu unbefriedigenden Ergebnissen geführt. Die gewünschte Schräglagenkorrektur wird durch das grüne Rechteck im Bild unten veranschaulicht:

[Bild eines Dokuments mit einem grünen Rechteck, das den interessierenden Bereich umreißt]

Ursache:

Die falschen Ergebnisse können auf mehrere Faktoren zurückgeführt werden:

  1. Punkt Reihenfolge: Die Punkte in den Eingabe- und Ausgabevektoren müssen in derselben Reihenfolge sein (z. B. oben links, unten links, unten rechts, oben rechts).
  2. Ausgabebild Größe: Um zu verhindern, dass das resultierende Bild zu viel Hintergrund enthält, sollten Breite und Höhe so eingestellt werden, dass sie mit denen des Begrenzungsrechtecks ​​um die Entzerrung übereinstimmen Region.

Lösung:

Um diese Probleme zu beheben, wurde der folgende Code geändert:

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

    // Points representing the corners of the paper in the picture:
    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));

    // Assemble a rotated rectangle from the points
    RotatedRect box = minAreaRect(cv::Mat(not_a_rect_shape));

    // Extract the corner points of the rotated rectangle
    Point2f pts[4];
    box.points(pts);

    // Define the vertices for the warp transformation
    Point2f src_vertices[3];
    src_vertices[0] = pts[0];
    src_vertices[1] = pts[1];
    src_vertices[2] = pts[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);

    // Use the affine transform as it's faster for the given use case
    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);
}

Verbesserungen :

Um die Effizienz weiter zu steigern, sollten Sie die Verwendung von cv::getAffineTransform() und in Betracht ziehen cv::warpAffine() anstelle von cv::getPerspectiveTransform() und cv::warpPerspective(). Diese Funktionen sind speziell für affine Transformationen konzipiert und deutlich schneller.

Das obige ist der detaillierte Inhalt vonWarum führt meine cv::warpPerspective-Entzerrungsimplementierung zu falschen Ergebnissen und wie kann ich das beheben?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn