OpenCV 輪廓查找與繪制-最小外接矩形


一、簡介

二、輪廓最小外接矩形的繪制

 1 #include "opencv2/opencv.hpp"
 2 using namespace cv;  3 
 4 void main()  5 {  6     //輪廓最小外接矩形的繪制
 7     Mat srcImg = imread("E://00.png");  8     Mat dstImg = srcImg.clone();  9  cvtColor(srcImg, srcImg, CV_BGR2GRAY); 10     threshold(srcImg, srcImg, 100, 255, CV_THRESH_BINARY); //二值化
11     imshow("threshold", srcImg); 12 
13     vector<vector<Point>> contours; 14     vector<Vec4i> hierarcy; 15  findContours(srcImg, contours, hierarcy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE); 16     vector<Rect> boundRect(contours.size());  //定義外接矩形集合
17     vector<RotatedRect> box(contours.size()); //定義最小外接矩形集合
18     Point2f rect[4]; 19     for(int i=0; i<contours.size(); i++) 20  { 21         box[i] = minAreaRect(Mat(contours[i]));  //計算每個輪廓最小外接矩形
22         boundRect[i] = boundingRect(Mat(contours[i])); 23         circle(dstImg, Point(box[i].center.x, box[i].center.y), 5, Scalar(0, 255, 0), -1, 8);  //繪制最小外接矩形的中心點
24         box[i].points(rect);  //把最小外接矩形四個端點復制給rect數組
25         rectangle(dstImg, Point(boundRect[i].x, boundRect[i].y), Point(boundRect[i].x + boundRect[i].width, boundRect[i].y + boundRect[i].height), Scalar(0, 255, 0), 2, 8); 26         for(int j=0; j<4; j++) 27  { 28             line(dstImg, rect[j], rect[(j+1)%4], Scalar(0, 0, 255), 2, 8);  //繪制最小外接矩形每條邊
29  } 30  } 31     imshow("dst", dstImg); 32     waitKey(0); 33 }

三、粗略計算物體像素長寬

 1 #include "opencv2/opencv.hpp"
 2 #include<iostream>
 3 using namespace std;  4 using namespace cv;  5 
 6 void main()  7 {  8     Mat srcImg = imread("E://cup.jpg");  9     imshow("src", srcImg); 10     Mat dstImg = srcImg.clone(); 11     medianBlur(srcImg, srcImg, 5); 12     GaussianBlur(srcImg, srcImg, Size(3, 3), 0, 0); 13  cvtColor(srcImg, srcImg, CV_BGR2GRAY); 14     threshold(srcImg, srcImg, 100, 255, CV_THRESH_BINARY_INV); //INV是因為背景白色,物體黑色,需要反轉一下
15     imshow("threshold", srcImg); 16 
17     vector<vector<Point>> contours; 18     vector<Vec4i> hierarcy; 19 
20  findContours(srcImg, contours, hierarcy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE); 21     cout<<"num="<<contours.size()<<endl; 22     vector<Rect> boundRect(contours.size()); 23     vector<RotatedRect> box(contours.size()); 24     Point2f rect[4]; 25     for(int i=0; i<contours.size(); i++) 26  { 27         box[i] = minAreaRect(Mat(contours[i])); 28         boundRect[i] = boundingRect(Mat(contours[i])); 29         cout<<box[i].angle<<endl; 30         cout<<box[i].center<<endl; 31         cout<<box[i].size.width<<endl; 32         cout<<box[i].size.height<<endl; 33         circle(dstImg, Point(box[i].center.x, box[i].center.y), 5, Scalar(0, 255, 0), -1, 8); 34 
35         //繪制外接矩形和 最小外接矩形(for循環)
36         rectangle(dstImg, Point(boundRect[i].x, boundRect[i].y), Point(boundRect[i].x + boundRect[i].width, boundRect[i].y + boundRect[i].height), Scalar(0, 255, 0), 2, 8); 37         box[i].points(rect);//把最小外接矩形四個端點復制給rect數組
38         for(int j=0; j<4; j++) 39  { 40             line(dstImg, rect[j], rect[(j+1)%4], Scalar(0, 0, 255), 2, 8); 41  } 42 
43         char width[20], height[20]; 44         sprintf(width, "width=%0.2f", box[i].size.width); 45         sprintf(height, "height=%0.2f", box[i].size.height); 46         putText(dstImg, width, Point(235, 260), CV_FONT_HERSHEY_COMPLEX_SMALL, 0.85, Scalar(0, 255, 0)); 47         putText(dstImg, height, Point(235, 285), CV_FONT_HERSHEY_COMPLEX_SMALL, 0.85, Scalar(0, 255, 0)); 48 
49  } 50     imshow("dst", dstImg); 51     waitKey(0); 52 }

四、傾斜物體矯正提取

 1 #include "opencv2/opencv.hpp"
 2 #include<iostream>
 3 using namespace std;  4 using namespace cv;  5 
 6 void main()  7 {  8     Mat srcImg = imread("E://qrcode.jpg");  9     imshow("src", srcImg); 10     Mat dstImg = srcImg.clone(); 11     GaussianBlur(srcImg, srcImg, Size(3, 3), 0, 0); 12  cvtColor(srcImg, srcImg, CV_BGR2GRAY); 13     Canny(srcImg, srcImg, 100, 200);//因為原圖比較復雜,所以需要將canny的值調大,去除不想要的成分 14     //threshold(srcImg, srcImg, 100, 255, CV_THRESH_BINARY_INV); //二值化也可以實現canny效果,不過在本例中雜絮較多
15     imshow("canny", srcImg); 16     Mat element = getStructuringElement(MORPH_RECT, Size(11, 11), Point(-1, -1)); //定義結構元素
17     dilate(srcImg, srcImg, element); //膨脹
18     imshow("dilate", srcImg); 19  erode(srcImg, srcImg, element); 20     imshow("erode", srcImg); 21 
22     vector<vector<Point>> contours; 23     vector<Vec4i> hierarcy; 24  findContours(srcImg, contours, hierarcy, CV_RETR_TREE, CV_CHAIN_APPROX_NONE); 25     vector<Rect> boundRect(contours.size()); 26     vector<RotatedRect> box(contours.size()); 27     Point2f rect[4]; 28     for(int i=0; i<contours.size(); i++) 29  { 30         box[i] = minAreaRect(Mat(contours[i])); 31         boundRect[i] = boundingRect(Mat(contours[i])); 32 
33         if(box[i].size.width < 100 || box[i].size.height<100)//篩選
34             continue; 35         rectangle(dstImg, Point(boundRect[i].x, boundRect[i].y), Point(boundRect[i].x + boundRect[i].width, boundRect[i].y + boundRect[i].height), Scalar(0, 255, 0), 2, 8); 36         circle(dstImg, Point(box[i].center.x, box[i].center.y), 5, Scalar(0, 255, 0), -1, 8); 37  box[i].points(rect); 38         for(int j=0; j<4; j++) 39  { 40             line(dstImg, rect[j], rect[(j+1)%4], Scalar(0, 0, 255), 2, 8); 41  } 42 
43         float angle; 44         cout<<"angle="<<box[i].angle<<endl; 45         angle = box[i].angle; 46         char width[20], height[20]; 47         sprintf(width, "width=%0.2f", box[i].size.width); 48         sprintf(height, "height=%0.2f", box[i].size.height); 49         putText(dstImg, width, Point(195, 260), CV_FONT_HERSHEY_COMPLEX_SMALL, 0.85, Scalar(0, 255, 0)); 50         putText(dstImg, height, Point(190, 285), CV_FONT_HERSHEY_COMPLEX_SMALL, 0.85, Scalar(0, 255, 0)); 51         imshow("temp", dstImg); 52 
53         //利用仿射變換進行旋轉 另一種方法,透視變換
54         if (0< abs(angle) && abs(angle)<=45) 55             angle = angle;//負數,順時針旋轉
56         else if (45< abs(angle) && abs(angle)<90) 57             angle = 90 -  abs(angle);//正數,逆時針旋轉
58         Point2f center = box[i].center;  //定義旋轉中心坐標
59         double angle0 = angle; 60         double scale = 1; 61         Mat roateM = getRotationMatrix2D(center, angle0, scale);  //獲得旋轉矩陣,順時針為負,逆時針為正
62         warpAffine(dstImg, dstImg, roateM, dstImg.size()); //仿射變換 63 
64         //保存二維碼
65         int x0=0, y0=0, w0=0, h0=0; 66         x0 = boundRect[i].x; 67         y0 = boundRect[i].y; 68         w0 = boundRect[i].width; 69         h0 = boundRect[i].height; 70         Mat ROI = dstImg(Rect(x0, y0, w0, h0)); 71         imwrite("F://1.jpg", ROI); 72  } 73     imshow("dst", dstImg); 74     waitKey(0); 75 }

 


免責聲明!

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



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