OpenCVは輪郭外接多角形を実現します。


本論文の実例はOpenCVの輪郭外接多角形を実現する具体的なコードを共有しています。
輪郭の最大外接矩形をとる

Rect boundingRect( InputArray array );
array:入力された階調画像または2 Dポイントセットのデータタイプは、vectorまたはMatです。
この関数は、入力画像中の物体の輪郭または2 Dドットセットを含む最大の外接矩形を求めることができ、関数は1つのパラメータしかなく、階調画像または2 Dドットセット、階調画像のパラメータタイプはMat、2 DポイントセットのパラメータタイプはvectorまたはMatであることができる。この関数の戻り値は、rectangle()関数で直接に長方形を描くことができるRectタイプの変数です。戻り値は4つのパラメータで、最初の2つのパラメータは最大外接矩形の左上隅の最初のピクセルの座標で、後の2つのパラメータはそれぞれ最大外接矩形の幅と高さを表します。 
輪郭が一番小さい外接の長方形

RotatedRect minAreaRect( InputArray points );
points:入力の2 Dポイントセット
この関数は、入力された2 Dポイントセットに基づいて最小の外接矩形を計算します。関数の戻り値は、長方形の中心位置、矩形の幅、高長方形の回転角度を含みます。RotatedRectクラスは2つの重要な方法と属性を持ち、長方形の4つの頂点と中心座標を出力することができます。4つの頂点座標を出力する方法はpoints()であり、RotatedRect類の変数がrrectであると仮定すると、rrect.pointsコマンドにより読み出しができ、座標格納変数はPoint 2 fタイプの配列である。出力矩形の中心座標の属性はセンターであり、RotatedRect類の変数がrrectであると仮定して、opt=rrect.cnterコマンドによって読み取りを行うことができます。ここで、座標に格納されている変数はPoint 2 fタイプの変数です。
外接多角形 

void approxPolyDP( InputArray curve,
                                OutputArray approxCurve,
                                double epsilon, bool closed );
  • curve:輪郭ピクセルポイントを入力します。
  • approxCurve:多角形近似結果は、多角形頂点座標の形で与えられる。
  • epsilon:近似の精度、すなわち元の曲線と近似曲線の最大距離。
  • closed:近似曲線は閉鎖曲線のフラグであるかどうか、trueは曲線の閉鎖を表し、最後の頂点は最初の頂点に接続されている。
  • この関数は入力された輪郭から最適な近似多角形を得た。
    関数の最初のパラメータは入力の輪郭2 Dピクセルポイントで、データタイプはvectorまたはMatです。
    二つ目のパラメータは多角形の近似結果であり、多角形の頂点座標の形で出力されるCV_である。32 SC 2タイプのN×1のMatクラスマトリックスは、出力結果の頂点数によって輪郭の幾何学的形状を初期的に判断することができる。
    三つ目のパラメータは、多角形近似時の精度、すなわち元の曲線と近似曲線の間の最大距離である。
    4番目のパラメータは、近似曲線が閉じられた曲線であるかどうかを示すフラグであり、trueは曲線の閉じた状態を表し、最後の頂点は最初の頂点に接続されています。
    簡単な例
    
    //
    // Created by smallflyfly on 2021/6/22.
    //
     
    #include "opencv2/opencv.hpp"
    #include <iostream>
     
    using namespace std;
    using namespace cv;
     
    int main() {
        Mat im = imread("rice.jfif");
    //    resize(im, im, Size(0, 0), 0.5, 0.5);
        Mat gray;
        cvtColor(im, gray, CV_BGR2GRAY);
     
        Mat imBin;
        threshold(gray, imBin, 150, 255, THRESH_BINARY);
     
        vector<vector<Point>> contours;
        findContours(imBin, contours, RETR_EXTERNAL, CHAIN_APPROX_NONE);
     
        Mat im1 = im.clone();
        Mat im2 = im.clone();
        for (auto & contour : contours) {
            //       
            Rect rect = boundingRect(contour);
            rectangle(im, rect, Scalar(0, 0, 255), 1);
     
            //       
            RotatedRect rotatedRect = minAreaRect(contour);
            Point2f pts[4];
            rotatedRect.points(pts);
            Point2f pt = rotatedRect.center;
            for (int i = 0; i < 4; ++i) {
                if (i == 3) {
                    line(im1, pts[i], pts[0], Scalar(255, 255, 0), 1);
                } else {
                    line(im1, pts[i], pts[i+1], Scalar(255, 255, 0), 1);
                }
            }
            circle(im1, pt, 1, Scalar(0, 0, 255), -1);
     
            //      
            Mat ploys;
            approxPolyDP(contour, ploys, 5, true);
            // draw ploy
            Vec2i pt1, pt2;
            for (int i = 0; i < ploys.rows; ++i) {
                if (i == ploys.rows - 1) {
                    pt1 = ploys.at<Vec2i>(i);
                    pt2 = ploys.at<Vec2i>(0);
     
                } else {
                    pt1 = ploys.at<Vec2i>(i);
                    pt2 = ploys.at<Vec2i>(i+1);
                }
                line(im2, pt1, pt2, Scalar(0, 0, 255), 2);
            }
        }
     
        imshow("im", im);
        imshow("im1", im1);
        imshow("im2", im2);
     
        waitKey(0);
        destroyAllWindows();
     
        return 0;
     
    }

    以上が本文の全部です。皆さんの勉強に役に立つように、私たちを応援してください。