opencv学习之路(26)、轮廓查找与绘制(五)——最小外接矩形

一、简介

二、轮廓最小外接矩形的绘制

 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 }

时间: 2024-10-01 22:35:51

opencv学习之路(26)、轮廓查找与绘制(五)——最小外接矩形的相关文章

opencv学习之路(25)、轮廓查找与绘制(四)——正外接矩形

一.简介 二.外接矩形的查找绘制 1 #include "opencv2/opencv.hpp" 2 using namespace cv; 3 void main() 4 { 5 //外接矩形的查找绘制 6 Mat srcImg =imread("E://12.jpg"); 7 imshow("src",srcImg); 8 Mat dstImg = srcImg.clone(); //原图备份 9 cvtColor(srcImg, srcIm

26、【opencv入门】轮廓查找与绘制(4)——正外接矩形

一.简介 1.使用特定形状的轮廓包围 在实际应用中, 经常会有将检测到的轮廓用多边形表示出来的需求, 提取包围轮廓的多边形也方便我们做进一步分析, 轮廓包围主要有一下几种: 轮廓外接矩形.轮廓最小外接矩形(旋转).轮廓最小包围圆形.轮廓拟合椭圆.轮廓逼近多边形曲线 2.轮廓外接矩形 --- boundingRect() 1 CV_EXPORTS_W Rect boundingRect(InputArray points); points: 输入的二维点集, 可以填Mat类型或std::vecto

android开发学习之路——连连看之游戏逻辑(五)

GameService组件则是整个游戏逻辑实现的核心,而且GameService是一个可以复用的业务逻辑类. (一)定义GameService组件接口 根据前面程序对GameService组件的依赖,程序需要GameService组件包含如下方法.   ·start():初始化游戏状态,开始游戏的方法.     ·Piece[][] getPieces():返回表示游戏状态的Piece[][]数组.     ·boolean hasPieces():判断Pieces[][]数组中是否还剩Piec

Opencv 最小外接矩形合并拼接

前一篇画出了最小外接矩形,但是有时候画出来的矩形由于中间像素干扰或者是其他原因矩形框并不是真正想要的 如图1是一个信号的雨图,被矩形框分割成了多个小框: 需要合并矩形框达到的效果: 主要思想: 扫描两次最小外接矩形,第一次扫描出的矩形是图一的小矩形,遍历vector指定一个合并最大距离(假设是80),达到指定距离使用画矩形函数将这两个矩形占据的组合区域染成实心矩形. 第二次扫描直接扫描之前画的实心矩形图确定最终边框 过程图 膨胀处理和像素翻转: 代码: #include "core/core.h

30、【opencv入门】轮廓查找与绘制(8)——轮廓特征属性及应用

一.简介 1.HSV颜色空间(hue色调,saturation饱和度,value亮度) HSV颜色空间与人眼所看色彩较接近, 故常用于颜色检测与识别.其中H(色调).S(饱和度).V(亮度) H---不同的颜色(红色/绿色/蓝色)---范围: 0~360 S---颜色深浅(浅红/深红)---范围: 0.0~1.0 V---颜色亮暗(暗红/亮红)---范围: 0.0~1.0 OpenCV默认的HSV范围分别是: H: 0~180,  S: 0~255,  V: 0~255 2.相关知识点 颜色空间

opencv学习之路(24)、轮廓查找与绘制(三)——凸包

一.简介 二.绘制点集的凸包 1 #include<opencv2/opencv.hpp> 2 using namespace cv; 3 4 void main() 5 { 6 //---绘制点集的凸包 7 Mat img(400, 400, CV_8UC3, Scalar::all(0)); //定义绘制图像 8 RNG rng; //定义随机数对象 9 while(1) 10 { 11 char key; 12 int count = (unsigned int)rng % 100; /

opencv学习之路(27)、轮廓查找与绘制(六)——外接圆

一.最小外接圆 1 #include "opencv2/opencv.hpp" 2 #include<iostream> 3 using namespace std; 4 using namespace cv; 5 6 void main() { 7 Mat srcImg = imread("E://10.png"); 8 imshow("src", srcImg); 9 Mat dstImg = srcImg.clone(); 10

25、【opencv入门】轮廓查找与绘制(3)——凸包

一简介 1.凸包 凸包(Convex Hull)是一个计算机几何图形学中的概念, 简单来说, 给定二维平面点集, 凸包就是能够将最外层的点连接起来构成的凸多边形, 它能够包含点集中所有的点.物体的凸包检测场应用在物体识别.手势识别及边界检测等领域. A-H是被标出的凸包缺陷 2.寻找凸包---convexHull() 1 CV_EXPORTS_W void convexHull(InputArray points, OutputArray hull, bool clockwise=false,

OpenCV学习代码记录—— Snake轮廓

很久之前学习过一段时间的OpenCV,当时没有做什么笔记,但是代码都还在,这里把它贴出来做个记录. 代码放在码云上,地址在这里https://gitee.com/solym/OpenCVTest/tree/master/OpenCVTest #include <opencv2/core.hpp> #include <opencv2/highgui.hpp> #include <opencv2/imgproc.hpp> #include <opencv2/legac