1. 程式人生 > >26、【opencv入門】輪廓查找與繪制(4)——正外接矩形

26、【opencv入門】輪廓查找與繪制(4)——正外接矩形

waitkey font 定義 truct 形狀 esp 圖片 namespace open

一、簡介

1、使用特定形狀的輪廓包圍

  在實際應用中, 經常會有將檢測到的輪廓用多邊形表示出來的需求, 提取包圍輪廓的多邊形也方便我們做進一步分析, 輪廓包圍主要有一下幾種: 輪廓外接矩形、輪廓最小外接矩形(旋轉)、輪廓最小包圍圓形、輪廓擬合橢圓、輪廓逼近多邊形曲線

技術分享圖片

2、輪廓外接矩形 --- boundingRect()

1 CV_EXPORTS_W Rect boundingRect(InputArray points);

  points: 輸入的二維點集, 可以填Mat類型或std::vector

  返回值: Rect類矩形對象

示例:

 1 vector<Rect> boundRect(contours.size());//
定義外接矩形集合 2 int x0 = 0, y0 = 0, w0 = 0, h0 = 0; 3 for(int i = 0; i < contours.size(); i++) 4 { 5 drawContours(dstImg, contours, i, Scalar(0, 0, 255), 2, 8); 6 boundRect[i] = boundingRect(Mat(contours[i])); 7 x0 = boundRect[i].x; 8 y0 = boundRect[i].y; 9 w0 = boundRect[i].width; 10 h0 = boundRect[i].height;
11 12 rectangle(dstImg, Point(x0, y0), Point(x0 + w0, y0 + h0), Scalar(0, 255, 0), 2, 8); 13 }

二、外接矩形的查找繪制

 1 //外接矩形的查找繪制
 2 #include "opencv2/opencv.hpp"
 3 
 4 using namespace cv;
 5 
 6 int main()
 7 {
 8     //外接矩形的查找繪制
 9     Mat srcImg =imread("2.jpg");
10     imshow("src",srcImg);
11     Mat dstImg = srcImg.clone();  //
原圖備份 12 cvtColor(srcImg, srcImg, CV_BGR2GRAY); //轉為灰度圖 13 threshold(srcImg, srcImg, 100, 255, CV_THRESH_BINARY); //二值化 14 15 vector<vector<Point>> contours; 16 vector<Vec4i> hierarcy; 17 findContours(srcImg, contours, hierarcy, CV_RETR_EXTERNAL, CHAIN_APPROX_NONE); //查找輪廓 18 vector<Rect> boundRect(contours.size()); //定義外接矩形集合 19 //drawContours(dstImg, contours, -1, Scalar(0, 0, 255), 2, 8); //繪制輪廓 20 int x0=0, y0=0, w0=0, h0=0; 21 for(int i=0; i<contours.size(); i++) 22 { 23 boundRect[i] = boundingRect((Mat)contours[i]); //查找每個輪廓的外接矩形 24 drawContours(dstImg, contours, i, Scalar(0, 0, 255), 2, 8); //繪制輪廓 25 x0 = boundRect[i].x; //獲得第i個外接矩形的左上角的x坐標 26 y0 = boundRect[i].y; //獲得第i個外接矩形的左上角的y坐標 27 w0 = boundRect[i].width; //獲得第i個外接矩形的寬度 28 h0 = boundRect[i].height; //獲得第i個外接矩形的高度 29 rectangle(dstImg, Point(x0, y0), Point(x0+w0, y0+h0), Scalar(0, 255, 0), 2, 8); //繪制第i個外接矩形 30 } 31 imshow("boundRect", dstImg); 32 waitKey(0); 33 return 0; 34 }

三、分割硬幣輪廓並計數

 1 //分割硬幣輪廓並計數
 2 #include "opencv2/opencv.hpp"
 3 #include<iostream>
 4 
 5 using namespace cv;
 6 using namespace std;
 7 
 8 int main()
 9 {
10     //分割硬幣輪廓
11     Mat srcImg =imread("3.png");
12     imshow("src", srcImg);
13     Mat dstImg = srcImg.clone();  //原圖備份
14     cvtColor(srcImg, srcImg, CV_BGR2GRAY); //轉為灰度圖
15     threshold(srcImg, srcImg, 100, 255, CV_THRESH_BINARY); //二值化
16     Mat element = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1)); //獲得結構元素
17     dilate(srcImg, srcImg, element); //膨脹操作
18     imshow("dilate",srcImg);
19 
20     vector<vector<Point>> contours;  
21     vector<Vec4i> hierarcy;
22     findContours(srcImg, contours, hierarcy, CV_RETR_EXTERNAL, CHAIN_APPROX_NONE); //查找輪廓
23     vector<Rect> boundRect(contours.size()); //定義外接矩形集合
24     int x0=0, y0=0, w0=0, h0=0,num=0;
25     for(int i=0; i<contours.size(); i++)
26     {
27         boundRect[i] = boundingRect((Mat)contours[i]); //查找每個輪廓的外接矩形
28         drawContours(dstImg, contours, i, Scalar(0, 0, 255), 2, 8);  //繪制輪廓
29         x0 = boundRect[i].x;  
30         y0 = boundRect[i].y; 
31         w0 = boundRect[i].width; 
32         h0 = boundRect[i].height; 
33         if(w0>30 && h0>30)//篩選
34         {
35             rectangle(dstImg, Point(x0, y0), Point(x0+w0, y0+h0), Scalar(0, 255, 0), 2, 8); //繪制第i個外接矩形
36             num++;
37         }
38     }
39     cout<<"硬幣數量:"<<num;
40     imshow("boundRect", dstImg);
41     waitKey(0); 
42     return 0;
43 }

四、簡單車牌字符分隔

 1 //簡單車牌字符分割
 2 #include "opencv2/opencv.hpp"
 3 
 4 using namespace cv;
 5 
 6 int main()
 7 {
 8     //---簡單車牌字符分隔
 9     Mat srcImg =imread("12.jpg");
10     Mat dstImg = srcImg.clone();  //原圖備份
11     medianBlur(srcImg, srcImg, 5);  //中值濾波
12     cvtColor(srcImg, srcImg, CV_BGR2GRAY); //轉為灰度圖
13     threshold(srcImg, srcImg, 100, 255, CV_THRESH_BINARY); //二值化
14     imshow("threshold", srcImg);
15     imwrite("F://car0.jpg", srcImg);
16 
17     vector<vector<Point>> contours;  
18     vector<Vec4i> hierarcy;
19     findContours(srcImg, contours, hierarcy, CV_RETR_TREE, CHAIN_APPROX_NONE); //查找所有輪廓
20     vector<Rect> boundRect(contours.size()); //定義外接矩形集合
21     int x0=0, y0=0, w0=0, h0=0;
22     for(int i=0; i<contours.size(); i++)
23     {
24         boundRect[i] = boundingRect((Mat)contours[i]); //查找每個輪廓的外接矩形
25         x0 = boundRect[i].x;  
26         y0 = boundRect[i].y; 
27         w0 = boundRect[i].width; 
28         h0 = boundRect[i].height; 
29         if(w0>srcImg.cols/12 && w0<srcImg.cols/5 && h0>srcImg.rows/6 && h0<srcImg.rows*5/6)
30         {
31             char pic_name[10];
32             sprintf(pic_name, "F:\\%d.bmp", i);
33             Mat ROI = dstImg(Rect(x0, y0, w0, h0));
34             imwrite(pic_name, ROI);
35             rectangle(dstImg, Point(x0, y0), Point(x0+w0, y0+h0), Scalar(0, 255, 0), 2, 8); //繪制第i個外接矩形
36         }
37     }
38     imshow("boundRect", dstImg);
39     waitKey(0);
40     return 0;
41 }


26、【opencv入門】輪廓查找與繪制(4)——正外接矩形