OpenCVSharp4で多角形凸包してみた

はじめに

多角形凸包とは、ある領域を「ヘコみのない多角形」で囲むことである。

方法

  1. 画像を読み込む
  2. 輪郭を求める
  3. 輪郭の点の集合を集める
  4. 集めた点で凸包する
  5. 表示

プログラム

ほとんどmotchy様のプログラムを参考にしたが、現バージョンに合わせて書き換えた。

using System.Collections.Generic;  
using OpenCvSharp;  

namespace convexHull {  
    class Program {  
        static void Main(string[] args) {  

            //1.画像をグレースケールで読み込む  
            Mat img = Cv2.ImRead(@"D:\tamanegi_onion (1).png", ImreadModes.Grayscale);  

            //2.輪郭を求める  
            Point[][] contours;  
            HierarchyIndex[] hierarchyIndexes;  
            img.FindContours(out contours, out hierarchyIndexes, RetrievalModes.CComp, ContourApproximationModes.ApproxSimple);  

            //3.親輪郭を構成する点を全て集める  
            var points = new List<Point>();  
            for(int idx_cnt = 0; idx_cnt < contours.GetLength(0); ++idx_cnt) {  
                if(hierarchyIndexes[idx_cnt].Parent != -1) { continue; }  
                points.AddRange(contours[idx_cnt]);  
            }  

            //4.凸包を求めて描画する  
            Cv2.CvtColor(img, img, ColorConversionCodes.GRAY2BGR);  
            img.Polylines(new Point[1][] { Cv2.ConvexHull(points.ToArray()) }, true,  Scalar.Red);  

            //5.表示  
            Cv2.ImShow("img", img);  
            Cv2.ImWrite(@"D:\totuho.png", img);  
            Cv2.WaitKey();  
        }  
    }  
}  

結果

f:id:negizoku:20200920232359p:plain



参考

https://motchy99.blog.fc2.com/blog-entry-153.html
https://teratail.com/questions/222754
https://docs.opencv.org/4.0.0/d7/d1d/tutorial_hull.html
https://ja.wikipedia.org/wiki/%E5%87%B8%E5%8C%85
https://white-rabbit.jp/quickhull/