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 }