ホームページ >バックエンド開発 >C++ >OpenCV の「warpAffine」を使用してポイントのデスキューをシミュレートするにはどうすればよいですか?

OpenCV の「warpAffine」を使用してポイントのデスキューをシミュレートするにはどうすればよいですか?

Patricia Arquette
Patricia Arquetteオリジナル
2024-11-28 11:49:10126ブラウズ

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

cv::warpPerspective を使用して一連の点で偽の傾き補正効果を実現する方法

問題の説明

目的はパースペクティブを適用することです次のようなデスキュー効果を得るために一連の点に変換します。ビデオ:

[ビデオ リンク](http://nuigroup.com/?ACT=28&fid=27&aid=1892_H6eNAaign4Mrnn30Au8d)

結果分析

提供されたサンプル画像とコードデスキュー効果を示していますが、正確ではありません。具体的には、変換された画像には ROI 全体が含まれておらず、アスペクト比が正しくありません。

エラーの修正

問題を修正するために、コードに次の変更が加えられました。

  1. 同じ頂点順序を確保する: ソース ベクトルとデスティネーション ベクトルの両方の点は同じでなければなりません順序 (例: 左上、左下、右下、右上)。
  2. 出力画像サイズのカスタマイズ: ROI を適切に含めるには、出力先の画像サイズを次のように指定する必要があります。元の点を囲む外接する四角形のサイズに設定されます。
  3. 速度の最適化: パフォーマンスを向上するには、一般的な透視変換関数の代わりに、アフィン変換関数 (getAffineTransform() および warpAffine()) が使用されました。

更新されたコード

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

以上がOpenCV の「warpAffine」を使用してポイントのデスキューをシミュレートするにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。