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 }