OpenCV筆記(7) 輪廓
阿新 • • 發佈:2021-09-17
目錄
- 查詢輪廓
- 繪製輪廓
- 連通區域分析
- 多邊形輪廓
- 獲得矩形包圍框
- 獲得輪廓凸包
1.查詢輪廓
public static void FindContours(InputOutputArray image, //輸入8-bit單通道的圖片
out Mat[] contours, //一組陣列,contours[i]是一條輪廓,而contours[i][j]是點
OutputArray hierarchy, //輸出一個數組,表示輪廓的樹結構,每個值都是四元陣列
RetrievalModes mode, //輪廓提取方式
ContourApproximationModes method, //輪廓如何被表達
Point? offset = null); public static void FindContours(InputOutputArray image,
out Point[][] contours,
out HierarchyIndex[] hierarchy,
RetrievalModes mode,
ContourApproximationModes method,
Point? offset = null);
2. 繪製輪廓
public static void DrawContours(InputOutputArray image,
IEnumerable<Mat> contours,
int contourIdx, //需要繪製的輪廓索引,若為負,繪製所有輪廓
Scalar color, //顏色
int thickness = 1, //線粗
LineTypes lineType = LineTypes.Link8, //四聯通、八聯通、AA線
Mat hierarchy = null,
int maxLevel = int.MaxValue,
Point? offset = null); public static void DrawContours(InputOutputArray image,
IEnumerable<IEnumerable<Point>> contours,
int contourIdx,
Scalar color,
int thickness = 1,
LineTypes lineType = LineTypes.Link8,
IEnumerable<HierarchyIndex> hierarchy = null,
int maxLevel = int.MaxValue, Point? offset = null);
示例:滑動條和找輪廓
程式碼:
using System; using OpenCvSharp; namespace ConsoleApp2 { class Program { static void Main(string[] args) { Mat g_gray = new Mat(); Mat g_binary = new Mat(); int g_thresh = 100; void on_trackbar(int pos, object userdata) { Cv2.Threshold((Mat)userdata, g_binary, pos, 255, ThresholdTypes.BinaryInv); Point[][] contours; HierarchyIndex[] hierarchy; Cv2.FindContours(g_binary, out contours, out hierarchy, RetrievalModes.List, ContourApproximationModes.ApproxSimple); Mat mask = new Mat(g_binary.Rows, g_binary.Cols, MatType.CV_8UC1, new Scalar(0)); Cv2.DrawContours(mask, contours, -1, new Scalar(255)); Cv2.ImShow("Contours", mask); } g_gray = Cv2.ImRead("C:\\Users\\ATWER\\Desktop\\b.png",ImreadModes.Grayscale); Cv2.ImShow("gray", g_gray); CvTrackbar cvTrackbar = new CvTrackbar("Threshold", "gray", g_thresh, 255, on_trackbar,g_gray); Cv2.ImShow("gray", g_gray); Cv2.WaitKey(0); } } }
3. 查詢連通區域
示例:
using System; using OpenCvSharp; namespace ConsoleApp2 { class Program { static void Main(string[] args) { Mat img = Cv2.ImRead("C:\\Users\\ATWER\\Desktop\\c.png"); Mat labelMat = new Mat(); Mat stats = new Mat(); Mat centroids = new Mat(); Cv2.CvtColor(img, img, ColorConversionCodes.BGR2GRAY);
Cv2.NamedWindow("img",WindowMode.Normal); Cv2.ImShow("img", img); int num = Cv2.ConnectedComponentsWithStats(img, labelMat, stats, centroids, PixelConnectivity.Connectivity4); Console.WriteLine(num.ToString()); for (int i = 0; i < num; i++) { double a = centroids.At<double>(i, 0); double b = centroids.At<double>(i, 1); Point point = new OpenCvSharp.Point(a, b); Cv2.Circle(img, point, 2, new Scalar(0, 0, 255)); int x = stats.At<int>(i, 0); int y = stats.At<int>(i, 1); int width = stats.At<int>(i, 2); int height = stats.At<int>(i, 3); Rect rect = new Rect(x, y, width, height); Cv2.Rectangle(img, rect, new Scalar(255)); } Cv2.NamedWindow("繪製質心", WindowMode.Normal); Cv2.ImShow("繪製質心", img); Cv2.WaitKey(0); } } }
4. 多邊形逼近輪廓ApproxPolyDP()
public static void ApproxPolyDP(InputArray curve,
OutputArray approxCurve,
double epsilon,
bool closed);
示例:多邊形逼近一個圓的外輪廓
程式碼:
using System; using System.Numerics; using OpenCvSharp; namespace ConsoleApp10 { class Program { static void Main(string[] args) { Mat img = new Mat(); Mat src = Cv2.ImRead("D:\\Backup\\桌面\\c.png");
//預處理 Cv2.CvtColor(src, img, ColorConversionCodes.BGR2GRAY); Cv2.BitwiseNot(img, img); Cv2.Threshold(img, img, 128, 255, ThresholdTypes.Binary); Cv2.ImShow("img", img);
//查詢輪廓 Mat[] contours; Mat hierarchy = new Mat(); Cv2.FindContours(img,out contours, hierarchy, RetrievalModes.External, ContourApproximationModes.ApproxSimple); Mat[] contours_poly = (Mat[])contours.Clone(); //Cv2.DrawContours(img, contours, -1, new Scalar(255),5); for (int i = 0; i < contours.Length; i++) { Cv2.ApproxPolyDP(contours[i], contours_poly[i], 10, true);//多邊形逼近 }
//繪製輪廓 Cv2.DrawContours(src, contours_poly, -1, new Scalar(0,255, 0),2); Cv2.ImShow("a", src); Cv2.WaitKey(0); } } }
5.獲得矩形包圍框
public static Rect BoundingRect(InputArray curve); public static RotatedRect MinAreaRect(InputArray points);
示例:
程式碼:
using System; using System.Numerics; using OpenCvSharp; namespace ConsoleApp10 { class Program { static void Main(string[] args) { Mat img = new Mat(); Mat src = Cv2.ImRead("D:\\Backup\\桌面\\c.png"); Cv2.ImShow("src", src); Cv2.CvtColor(src, img, ColorConversionCodes.BGR2GRAY); Cv2.BitwiseNot(img, img); Cv2.Threshold(img, img, 128, 255, ThresholdTypes.Binary); Cv2.ImShow("img", img); //查詢輪廓
Mat[] contours; Mat hierarchy = new Mat(); Cv2.FindContours(img,out contours, hierarchy, RetrievalModes.List, ContourApproximationModes.ApproxSimple); Mat[] contours_poly = (Mat[])contours.Clone(); for (int i = 0; i < contours.Length; i++) { Cv2.ApproxPolyDP(contours[i], contours_poly[i], 10, true); //獲得輪廓長度 double len = Cv2.ArcLength(contours_poly[i], true); Console.WriteLine(len.ToString()); //獲得矩形包圍框 Rect rect = Cv2.BoundingRect(contours_poly[i]); Cv2.Rectangle(src, rect, new Scalar(0),5); //獲得最小矩形框 RotatedRect rect_rotate = Cv2.MinAreaRect(contours_poly[i]); Console.WriteLine(rect_rotate.Angle.ToString()); }
//繪製輪廓 Cv2.DrawContours(src, contours_poly, -1, new Scalar(0,255, 0),2); Cv2.ImShow("a", src); Cv2.WaitKey(0); } } }
6. 獲得輪廓凸包
public static void ConvexHull(InputArray points,
OutputArray hull,
bool clockwise = false,
bool returnPoints = true);
示例:
程式碼:
using System; using System.Numerics; using OpenCvSharp; namespace ConsoleApp10 { class Program { static void Main(string[] args) { Mat img = new Mat(); Mat src = Cv2.ImRead("D:\\Backup\\桌面\\d.png"); Cv2.ImShow("src", src); Cv2.CvtColor(src, img, ColorConversionCodes.BGR2GRAY); Cv2.BitwiseNot(img, img); Cv2.Threshold(img, img, 128, 255, ThresholdTypes.Binary); Cv2.ImShow("img", img);
//查詢輪廓 Mat[] contours; Mat hierarchy = new Mat(); Cv2.FindContours(img,out contours, hierarchy, RetrievalModes.List, ContourApproximationModes.ApproxSimple);
//凸包 居然想不到第二個方法把hulls畫出來 Mat hulls = new Mat(); Cv2.ConvexHull(contours[0],hulls,false); Mat[] r = new Mat[] { hulls }; //繪製輪廓 Cv2.DrawContours(src, r, -1, new Scalar(0, 255, 0), 2); Cv2.ImShow("a", src); Cv2.WaitKey(0); } } }
源自:蝴蝶書第十四章輪廓