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 }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章