OpenCV 提取輪廓的凸包、外包矩形、最小外包矩形、最小外包圓


1、提取輪廓的凸包

CONVEXHULL()函數(點我看OPENCV3.2幫助文檔

這里寫圖片描述

函數調用形式:

void convexhul(InputArray points,OutputArray hull,bool clockwise=false,bool returnPoints=true)

輸入:
第一個參數是要求凸包的點集
第二個參數是輸出的凸包點,可以為vector,此時返回的是凸包點在原輪廓點集中的索引,也可以為vector,此時存放的是凸包點的位置
第三個參數是一個bool變量,表示求得的凸包是順時針方向還是逆時針方向,true是順時針方向。
第四個參數,第二個參數的返回類型是vector還是vector,可以忽略

示例:

 1 #define _CRT_SECURE_NO_WARNINGS
 2 #include<iostream>  
 3 #include<vector>  
 4 #include<opencv2/opencv.hpp>  
 5 
 6 using namespace cv;  7 using namespace std;  8 
 9 int main() 10 { 11     Mat srcImage(Size(500, 500), CV_8UC3, Scalar(0)); 12 
13     // 隨機類RNG,默認的構造函數初始化為固定的值,隨機“種子”也是固定的,還有一個帶參數的構造函數,你可以指定“種子”, 14     // 用系統時間來指定,以確保每次執行都是“不同的種子” 從而得到不同的隨機序列
15  RNG rng((unsigned)time(NULL)); 16 
17     char key; 18     while (1) 19  { 20         //隨機生成一些點 21         //首先就是隨機生成點的總數量
22         int g_nPointCount = rng.uniform(10, 30); 23         //接下來就是隨機生成一些點的坐標 
24         vector<Point> points; 25         for (int i = 0; i < g_nPointCount; i++) 26  { 27  Point midPoint; 28 
29             midPoint.x = rng.uniform(srcImage.cols / 4, srcImage.cols * 3 / 4); 30             midPoint.y = rng.uniform(srcImage.rows / 4, srcImage.rows * 3 / 4); 31 
32  points.push_back(midPoint); 33  } 34 
35         //顯示剛剛隨機生成的那些點 
36         for (int i = 0; i < g_nPointCount; i++) 37  { 38             circle(srcImage, points[i], 0, Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)), 3); 39  } 40 
41         //計算凸包 
42         vector<int> hull; 43         convexHull(Mat(points), hull, true); 44         //繪制凸包
45         int hullcount = (int)hull.size(); 46         Point pt0 = points[hull[hullcount - 1]]; 47         for (int i = 0;i < hullcount;i++) 48  { 49             Point pt = points[hull[i]]; 50             line(srcImage, pt0, pt, Scalar(0, 255, 0), 1, LINE_AA); 51             pt0 = pt; 52  } 53 
54         imshow("效果圖", srcImage); 55 
56         key = waitKey(); 57         if (key == 27) 58             break; 59         else
60             srcImage = Scalar::all(0); 61  } 62 
63     return 0; 64 }

效果:

這里寫圖片描述

2、提取輪廓的外包矩形

BOUNDINGRECT()函數(點我看OPENCV3.2幫助文檔

這里寫圖片描述

函數作用:

計算輪廓的外包矩形,矩形是與圖像上下邊界平行的

函數調用形式:

Rect boundingRect(InputArray points)

輸入:二維點集,點的序列或向量 (Mat)
返回:Rect

示例:

 1 #define _CRT_SECURE_NO_WARNINGS
 2 #include<iostream>  
 3 #include<vector>  
 4 #include<opencv2/opencv.hpp>  
 5 
 6 using namespace cv;  7 using namespace std;  8 
 9 int main() 10 { 11     Mat srcImage(Size(500, 500), CV_8UC3, Scalar(0)); 12 
13     // 隨機類RNG,默認的構造函數初始化為固定的值,隨機“種子”也是固定的,還有一個帶參數的構造函數,你可以指定“種子”, 14     // 用系統時間來指定,以確保每次執行都是“不同的種子” 從而得到不同的隨機序列
15  RNG rng((unsigned)time(NULL)); 16 
17     char key; 18     while (1) 19  { 20         //隨機生成一些點 21         //首先就是隨機生成點的總數量
22         int g_nPointCount = rng.uniform(10, 30); 23         //接下來就是隨機生成一些點的坐標 
24         vector<Point> points; 25         for (int i = 0; i < g_nPointCount; i++) 26  { 27  Point midPoint; 28 
29             midPoint.x = rng.uniform(srcImage.cols / 4, srcImage.cols * 3 / 4); 30             midPoint.y = rng.uniform(srcImage.rows / 4, srcImage.rows * 3 / 4); 31 
32  points.push_back(midPoint); 33  } 34 
35         //顯示剛剛隨機生成的那些點 
36         for (int i = 0; i < g_nPointCount; i++) 37  { 38             circle(srcImage, points[i], 0, Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)), 3); 39  } 40         //尋找外包矩陣
41         Rect maxRect = boundingRect(points); 42         //繪制外包矩陣
43         rectangle(srcImage, maxRect, Scalar(0, 255, 0)); 44 
45         imshow("效果圖", srcImage); 46 
47         key = waitKey(); 48         if (key == 27) 49             break; 50         else
51             srcImage = Scalar::all(0); 52  } 53 
54     return 0; 55 }

效果圖:

這里寫圖片描述

3、提取輪廓的最小外包矩形

MINAREARECT()函數(點我看OPENCV3幫助文檔

這里寫圖片描述

函數作用:

主要求得包含點集最小面積的矩形,這個矩形是可以有偏轉角度的,可以與圖像的邊界不平行

函數調用形式:

RotatedRect minAreaRect(InputArray points)

輸入:二維點集,點的序列或向量 (Mat)
返回:RotatedRect

示例:

 1 #define _CRT_SECURE_NO_WARNINGS
 2 #include<iostream>  
 3 #include<vector>  
 4 #include<opencv2/opencv.hpp>  
 5 
 6 using namespace cv;  7 using namespace std;  8 
 9 int main() 10 { 11     Mat srcImage(Size(500, 500), CV_8UC3, Scalar(0)); 12 
13     // 隨機類RNG,默認的構造函數初始化為固定的值,隨機“種子”也是固定的,還有一個帶參數的構造函數,你可以指定“種子”, 14     // 用系統時間來指定,以確保每次執行都是“不同的種子” 從而得到不同的隨機序列
15  RNG rng((unsigned)time(NULL)); 16 
17     char key; 18     while (1) 19  { 20         //隨機生成一些點 21         //首先就是隨機生成點的總數量
22         int g_nPointCount = rng.uniform(10, 30); 23         //接下來就是隨機生成一些點的坐標 
24         vector<Point> points; 25         for (int i = 0; i < g_nPointCount; i++) 26  { 27  Point midPoint; 28 
29             midPoint.x = rng.uniform(srcImage.cols / 4, srcImage.cols * 3 / 4); 30             midPoint.y = rng.uniform(srcImage.rows / 4, srcImage.rows * 3 / 4); 31 
32  points.push_back(midPoint); 33  } 34 
35         //顯示剛剛隨機生成的那些點 
36         for (int i = 0; i < g_nPointCount; i++) 37  { 38             circle(srcImage, points[i], 0, Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)), 3); 39  } 40 
41         //尋找最小外包矩形
42         RotatedRect minRect = minAreaRect(points); 43 
44         Point2f fourPoint2f[4]; 45         //將minRect的四個頂點坐標值放到fourPoint的數組中 
46  minRect.points(fourPoint2f); 47 
48         //根據得到的四個點的坐標 繪制矩形 
49         for (int i = 0; i < 3; i++) 50  { 51             line(srcImage, fourPoint2f[i], fourPoint2f[i + 1], Scalar(0,0,255), 3); 52  } 53         line(srcImage, fourPoint2f[0], fourPoint2f[3], Scalar(0, 0, 255), 3); 54 
55         imshow("效果圖", srcImage); 56 
57         key = waitKey(); 58         if (key == 27) 59             break; 60         else
61             srcImage = Scalar::all(0); 62  } 63 
64     return 0; 65 }

效果圖:

這里寫圖片描述

ROTATEDRECT類的詳解,參見我另一篇博客:【OPENCV3學習筆記】ROTATEDRECT類 詳解

4、提取輪廓的最小外包圓

minEnclosingcircle()(點我看OpenCV3幫助文檔
這里寫圖片描述

函數調用形式:

void minEnclosingcircle(InputArray points,Point2f& center,float& radius)

輸入:二維點集,點的序列vector< point >或向量 (Mat) ,圓心坐標,半徑

示例:

 1 #define _CRT_SECURE_NO_WARNINGS
 2 #include<iostream>  
 3 #include<vector>  
 4 #include<opencv2/opencv.hpp>  
 5 
 6 using namespace cv;  7 using namespace std;  8 
 9 int main() 10 { 11     Mat srcImage(Size(500, 500), CV_8UC3, Scalar(0)); 12 
13     // 隨機類RNG,默認的構造函數初始化為固定的值,隨機“種子”也是固定的,還有一個帶參數的構造函數,你可以指定“種子”, 14     // 用系統時間來指定,以確保每次執行都是“不同的種子” 從而得到不同的隨機序列
15  RNG rng((unsigned)time(NULL)); 16 
17     char key; 18     while (1) 19  { 20         //隨機生成一些點 21         //首先就是隨機生成點的總數量
22         int g_nPointCount = rng.uniform(10, 30); 23         //接下來就是隨機生成一些點的坐標 
24         vector<Point> points; 25         for (int i = 0; i < g_nPointCount; i++) 26  { 27  Point midPoint; 28 
29             midPoint.x = rng.uniform(srcImage.cols / 4, srcImage.cols * 3 / 4); 30             midPoint.y = rng.uniform(srcImage.rows / 4, srcImage.rows * 3 / 4); 31 
32  points.push_back(midPoint); 33  } 34 
35         //顯示剛剛隨機生成的那些點 
36         for (int i = 0; i < g_nPointCount; i++) 37  { 38             circle(srcImage, points[i], 0, Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)), 3); 39  } 40 
41 
42         //在生成的那些隨機點中尋找最小包圍圓形 
43         Point2f center; //圓心
44         float radius; //半徑
45  minEnclosingCircle(points, center, radius); 46 
47         //根據得到的圓形和半徑 繪制圓形 
48         circle(srcImage, static_cast<Point>(center), (int)radius, Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)), 3); 49 
50         imshow("效果圖", srcImage); 51 
52         key = waitKey(); 53         if (key == 27) 54             break; 55         else
56             srcImage = Scalar::all(0); 57  } 58 
59     return 0; 60 }

效果圖:

這里寫圖片描述


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM