Maison >développement back-end >C++ >Comment simuler le redressement des points à l'aide de « warpAffine » d'OpenCV ?

Comment simuler le redressement des points à l'aide de « warpAffine » d'OpenCV ?

Patricia Arquette
Patricia Arquetteoriginal
2024-11-28 11:49:10135parcourir

How to Simulate Deskewing of Points Using OpenCV's `warpAffine`?

Comment obtenir un faux effet de redressement sur un ensemble de points à l'aide de cv::warpPerspective

Énoncé du problème

Le but est d'appliquer une perspective transformation en un ensemble de points pour obtenir un effet de redressement, similaire à celui présenté dans la vidéo suivante :

[Vidéo Lien](http://nuigroup.com/?ACT=28&fid=27&aid=1892_H6eNAaign4Mrnn30Au8d)

Analyse des résultats

L'exemple d'image et de code fourni démontre l'effet de redressement, mais il n'est pas précis. Plus précisément, l'image transformée ne contient pas l'intégralité du ROI et le rapport hauteur/largeur est incorrect.

Correction des erreurs

Pour résoudre les problèmes, les modifications suivantes ont été apportées au code :

  1. Assurer le même ordre des sommets : Les points des vecteurs source et de destination doivent être dans le même ordre (par exemple, en haut à gauche, en bas à gauche, en bas à droite, en haut à droite).
  2. Personnalisation de la taille de l'image de sortie : Pour contenir correctement le retour sur investissement, la taille de l'image de destination doit être défini sur la taille du rectangle englobant autour des points d'origine.
  3. Optimisation pour la vitesse : Pour améliorer les performances, les fonctions de transformation affine (getAffineTransform() et warpAffine()) ont été utilisés à la place des fonctions générales de transformation de perspective.

Code mis à jour

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

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

    // Debug drawing of the points
    const Point* point = &amp;not_a_rect_shape[0];
    int n = (int)not_a_rect_shape.size();
    Mat draw = src.clone();
    polylines(draw, &amp;point, &amp;n, 1, true, Scalar(0, 255, 0), 3, CV_AA);
    imwrite("draw.jpg", draw);

    // Rotated rectangle around the points
    RotatedRect box = minAreaRect(cv::Mat(not_a_rect_shape));

    // Source and destination vertex points
    Point2f pts[4];
    box.points(pts);

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

    // Affine transform matrix
    Mat warpAffineMatrix = getAffineTransform(src_vertices, dst_vertices);

    // Transformation and output image
    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);
}

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