OpenCV (C++) 幾何形狀識別(面積過濾、橫縱比過濾等等)


 1 #include <opencv2/opencv.hpp>
 2 #include <iostream>
 3 #include <math.h>
 4 
 5 using namespace cv;
 6 using namespace std;
 7 
 8 
 9 int main(int argc, char** argv)
10 {
11     Mat src = imread("3 input.bmp", IMREAD_GRAYSCALE);
12     Mat binary, dst = Mat::zeros(src.size(), CV_8UC3);
13     Mat Triangle = dst.clone(), Rect1 = dst.clone(), BigCircle = dst.clone(), SmallCircle = dst.clone();
14 
15     if (src.empty()) {
16         printf("Could not load image...");
17         return -1;
18     }
19     src = ~src;//取反
20     imshow("原圖", src);
21     //二值化
22     threshold(src, binary, 0, 255, THRESH_BINARY | THRESH_OTSU);
23 
24     //發現輪廓
25     vector<vector<Point>> contours;
26     vector<Vec4i> hireachy;
27     findContours(binary, contours, hireachy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point());
28 
29     //面積刪選
30     for (size_t t = 0; t < contours.size(); t++)
31     {
32         double area = contourArea(contours[t]);
33         if (area < 40000) continue;//將面積小於40000的去掉
34         drawContours(Triangle, contours, t, Scalar(0, 0, 255), 2, 8, Mat(), 0, Point());
35     }
36 
37     for (size_t t = 0; t < contours.size(); t++)
38     {
39         double area = contourArea(contours[t]);
40         if (area > 40000 || area<20000) continue;//將面積小於40000的去掉
41         drawContours(BigCircle, contours, t, Scalar(0, 0, 255), 2, 8, Mat(), 0, Point());
42     }
43 
44     for (size_t t = 0; t < contours.size(); t++)
45     {
46         double area = contourArea(contours[t]);
47         if (area > 20000 || area<15000) continue;//將面積小於40000的去掉
48         drawContours(Rect, contours, t, Scalar(0, 0, 255), 2, 8, Mat(), 0, Point());
49     }
50 
51     for (size_t t = 0; t < contours.size(); t++)
52     {
53         double area = contourArea(contours[t]);
54         if (area > 15000) continue;//將面積小於40000的去掉
55         //其他過濾方法
56 
57         /*//橫縱比過濾
58         Rect rect= boundingRect(contours[t]);//返回最小外接矩形
59         float ratio = float(rect.width) / float(rect.height);//計算橫縱比
60         if (ratio<1.1&&ratio>0.9) {}
61         
62         //周長過濾
63         float length = arcLength(contours[t], true);//計算輪廓長度
64         
65         */
66 
67         
68         drawContours(SmallCircle, contours, t, Scalar(0, 0, 255), 2, 8, Mat(), 0, Point());
69     }
70     imshow("Triangle", Triangle);
71     imshow("BigCircle", BigCircle);
72     imshow("Rect", Rect1);
73     imshow("SmallCircle", SmallCircle);
74 
75     waitKey(0);
76     return 0;
77 }

 方法二:多邊形逼近:

void approxPolyDP(InputArray curve, OutputArray approxCurve, double epsilon, bool closed);

參數說明:

InputArray curve:輸入的點集
OutputArray approxCurve:輸出的點集,當前點集是能最小包容指定點集的。draw出來即是一個多邊形;
double epsilon:指定的精度,也即是原始曲線與近似曲線之間的最大距離。
bool closed:若為true,則說明近似曲線是閉合的,它的首位都是相連,反之,若為false,則斷開。

 

 1 #include <opencv2/opencv.hpp>
 2 #include <iostream>
 3 
 4 #define MATCHMETHOD TM_SQDIFF_NORMED//宏定義匹配模式
 5 using namespace cv;
 6 using namespace std;
 7 
 8 
 9 int main(int argc, char** argv)
10 { 
11     Mat src = imread("F:/2019視覺培訓內容/2019視覺培訓內容/3 input.bmp");
12     Mat src_gray,binary ;
13     Mat Triangle = src.clone(), Rect = src.clone(), BigCircle = src.clone(), SmallCircle = src.clone();
14     if (src.empty()) {
15         printf("Could not load image...");
16         return -1;
17     }
18     imshow("Input Image",src);
19       
20     //二值化
21     cvtColor(src, src_gray, COLOR_BGR2GRAY);
22     threshold(src_gray, binary, 0, 255, THRESH_BINARY | THRESH_OTSU);
23     binary = ~binary;
24     imshow("binary", binary);
25 
26     //發現輪廓
27     vector<vector<Point>> contours;
28     vector<Point> point;
29     vector<Vec4i> hireachy;
30     findContours(binary, contours, hireachy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point());
31     
32     //繪制出所有輪廓
33     for (size_t t = 0; t < contours.size(); t++)
34     {
35                 
36         int epsilon = 0.01*arcLength(contours[t], true);
37         approxPolyDP(contours[t], point, epsilon, true);
38         if(point.size()==3)
39         {
40             drawContours(Triangle, contours, t, Scalar(0, 0, 255), 2, 8, Mat(), 0, Point());//dst必須先初始化 
41         }
42         else if (point.size() == 4)
43         {
44             drawContours(Rect, contours, t, Scalar(0, 0, 255), 2, 8, Mat(), 0, Point());//dst必須先初始化
45         }
46 
47         else 
48         {
49             double area = contourArea(contours[t]);
50             if (area < 15000)
51             {
52                 drawContours(SmallCircle, contours, t, Scalar(0, 0, 255), 2, 8, Mat(), 0, Point());//dst必須先初始化
53             }
54             else
55             {
56                 drawContours(BigCircle, contours, t, Scalar(0, 0, 255), 2, 8, Mat(), 0, Point());//dst必須先初始化
57             }
58         }
59         
60         cout << "邊的數目:" << point.size() << endl;
61     }
62 
63     imshow("Triangle", Triangle);
64     imshow("BigCircle", BigCircle);
65     imshow("Rect", Rect);
66     imshow("SmallCircle", SmallCircle);
67 
68     waitKey(0);
69 
70     return 0;
71 }

 


免責聲明!

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



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