Maison >développement back-end >C++ >Comment redresser un ensemble de points à l'aide de cv::warpPerspective ?

Comment redresser un ensemble de points à l'aide de cv::warpPerspective ?

Linda Hamilton
Linda Hamiltonoriginal
2024-12-03 17:40:12791parcourir

How to Deskew a Set of Points Using cv::warpPerspective?

Exécution de cv::warpPerspective pour un faux redressement sur un ensemble de cv::Point

Question : Comment puis-je obtenir un effet de redressement sur un ensemble de points en utilisant cv::warpPerspective ? Les points ne sont pas dans un ordre particulier et sont stockés dans un vecteur.

Comprendre le problème :

  • Ordre des points incorrect : l'ordre des points dans le les vecteurs d'entrée et de sortie doivent correspondre pour obtenir la transformation souhaitée.
  • Taille d'image incorrecte : l'image de sortie doit avoir une largeur et une hauteur correspondant au rectangle englobant du objet redressé.

Étapes pour un faux redressement :

  1. Ordre correct des points : assurez-vous de l'ordre des points dans les deux entrées et les vecteurs de sortie suivent la même séquence (par exemple, en haut à gauche, en bas à gauche, en bas à droite, en haut à droite).
  2. Ajustement du rectangle pivoté : utilisez cv::minAreaRect() pour créer un rectangle pivoté autour des points d'entrée. Cependant, notez que cette méthode peut légèrement modifier les coordonnées du point d'origine.
  3. Affine Transform : utilisez les fonctions de transformation affine, cv::getAffineTransform() et cv::warpAffine(), comme ils sont plus efficaces sur le plan informatique pour cette opération de redressement spécifique.
  4. Taille de sortie différente : Pour faites en sorte que l'image redressée contienne uniquement l'objet d'intérêt, définissez une nouvelle taille d'image (par exemple, cv::Size(width, height)) qui correspond à la taille du rectangle englobant.
  5. Appliquer la transformation affine : Transmettez l'image d'entrée, les points d'entrée, les points de sortie et la taille de sortie définie à cv::warpAffine() pour effectuer le redressement réel transformation.

Exemple de code :

#include <opencv2/opencv.hpp>

int main() {
    // Input image
    Mat src = imread("input.jpg");

    // Input points (not in particular order)
    vector<Point> points = {
        Point(408, 69), // Top-left
        Point(72, 2186), // Bottom-left
        Point(1584, 2426), // Bottom-right
        Point(1912, 291), // Top-right
    };

    // Rotated rectangle (bounding box)
    RotatedRect boundingRect = minAreaRect(Mat(points));

    // Corrected point ordering
    Point2f vertices[3];
    vertices[0] = boundingRect.center + boundingRect.size * 0.5f; // Top-left
    vertices[1] = boundingRect.center + boundingRect.size * 0.5f; // Bottom-left
    vertices[1].y += boundingRect.size.height;
    vertices[2] = boundingRect.center - boundingRect.size * 0.5f; // Bottom-right

    // Output point ordering
    Point2f outputVertices[3];
    outputVertices[0] = Point(0, 0); // Top-left
    outputVertices[1].x = outputVertices[0].x + boundingRect.size.width; // Bottom-left
    outputVertices[1].y = outputVertices[1].x;
    outputVertices[2] = outputVertices[0]; // Bottom-right

    // Affine transformation matrix
    Mat transformationMatrix = getAffineTransform(vertices, outputVertices);

    // Deskewed image with corrected size
    Mat deskewedImage;
    Size outputSize(boundingRect.size.width, boundingRect.size.height);
    warpAffine(src, deskewedImage, transformationMatrix, outputSize, INTER_LINEAR);

    // Save deskewed image
    imwrite("deskewed.jpg", deskewedImage);
}

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