Maison >développement back-end >C++ >Pourquoi ma mise en œuvre de redressement cv::warpPerspective produit-elle des résultats incorrects et comment puis-je y remédier ?

Pourquoi ma mise en œuvre de redressement cv::warpPerspective produit-elle des résultats incorrects et comment puis-je y remédier ?

DDD
DDDoriginal
2024-11-23 03:32:11606parcourir

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

Comment exécuter correctement cv::warpPerspective pour redresser un ensemble de points

Problème :

Tentatives d'utilisation de cv ::warpPerspective pour obtenir un effet de redressement sur un ensemble de points a donné des résultats insatisfaisants résultats. Le redressement souhaité est illustré par le rectangle vert dans l'image ci-dessous :

[Image d'un document avec un rectangle vert délimitant la région d'intérêt]

Cause :

Les résultats incorrects peuvent être attribués à plusieurs facteurs :

  1. Point Ordre : Les points dans les vecteurs d'entrée et de sortie doivent être dans le même ordre (par exemple, en haut à gauche, en bas à gauche, en bas à droite, en haut à droite).
  2. Image de sortie Taille : Pour éviter que l'image résultante ne contienne un arrière-plan excessif, sa largeur et sa hauteur doivent être définies pour correspondre à celles du rectangle englobant autour du redressement. région.

Solution :

Pour résoudre ces problèmes, le code ci-dessous a été modifié :

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);
}

Améliorations :

Pour améliorer encore l'efficacité, pensez à utiliser cv::getAffineTransform() et cv::warpAffine() au lieu de cv::getPerspectiveTransform() et cv::warpPerspective(). Ces fonctions sont spécialement conçues pour les transformations affines et sont nettement plus rapides.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn