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

二、轮廓最小外接矩形的绘制
#include "opencv2/opencv.hpp"
using namespace cv; void main()
{
//轮廓最小外接矩形的绘制
Mat srcImg = imread("E://00.png");
Mat dstImg = srcImg.clone();
cvtColor(srcImg, srcImg, CV_BGR2GRAY);
threshold(srcImg, srcImg, , , CV_THRESH_BINARY); //二值化
imshow("threshold", srcImg); vector<vector<Point>> contours;
vector<Vec4i> hierarcy;
findContours(srcImg, contours, hierarcy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
vector<Rect> boundRect(contours.size()); //定义外接矩形集合
vector<RotatedRect> box(contours.size()); //定义最小外接矩形集合
Point2f rect[];
for(int i=; i<contours.size(); i++)
{
box[i] = minAreaRect(Mat(contours[i])); //计算每个轮廓最小外接矩形
boundRect[i] = boundingRect(Mat(contours[i]));
circle(dstImg, Point(box[i].center.x, box[i].center.y), , Scalar(, , ), -, ); //绘制最小外接矩形的中心点
box[i].points(rect); //把最小外接矩形四个端点复制给rect数组
rectangle(dstImg, Point(boundRect[i].x, boundRect[i].y), Point(boundRect[i].x + boundRect[i].width, boundRect[i].y + boundRect[i].height), Scalar(, , ), , );
for(int j=; j<; j++)
{
line(dstImg, rect[j], rect[(j+)%], Scalar(, , ), , ); //绘制最小外接矩形每条边
}
}
imshow("dst", dstImg);
waitKey();
}

三、粗略计算物体像素长宽
#include "opencv2/opencv.hpp"
#include<iostream>
using namespace std;
using namespace cv; void main()
{
Mat srcImg = imread("E://cup.jpg");
imshow("src", srcImg);
Mat dstImg = srcImg.clone();
medianBlur(srcImg, srcImg, );
GaussianBlur(srcImg, srcImg, Size(, ), , );
cvtColor(srcImg, srcImg, CV_BGR2GRAY);
threshold(srcImg, srcImg, , , CV_THRESH_BINARY_INV); //INV是因为背景白色,物体黑色,需要反转一下
imshow("threshold", srcImg); vector<vector<Point>> contours;
vector<Vec4i> hierarcy; findContours(srcImg, contours, hierarcy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
cout<<"num="<<contours.size()<<endl;
vector<Rect> boundRect(contours.size());
vector<RotatedRect> box(contours.size());
Point2f rect[];
for(int i=; i<contours.size(); i++)
{
box[i] = minAreaRect(Mat(contours[i]));
boundRect[i] = boundingRect(Mat(contours[i]));
cout<<box[i].angle<<endl;
cout<<box[i].center<<endl;
cout<<box[i].size.width<<endl;
cout<<box[i].size.height<<endl;
circle(dstImg, Point(box[i].center.x, box[i].center.y), , Scalar(, , ), -, ); //绘制外接矩形和 最小外接矩形(for循环)
rectangle(dstImg, Point(boundRect[i].x, boundRect[i].y), Point(boundRect[i].x + boundRect[i].width, boundRect[i].y + boundRect[i].height), Scalar(, , ), , );
box[i].points(rect);//把最小外接矩形四个端点复制给rect数组
for(int j=; j<; j++)
{
line(dstImg, rect[j], rect[(j+)%], Scalar(, , ), , );
} char width[], height[];
sprintf(width, "width=%0.2f", box[i].size.width);
sprintf(height, "height=%0.2f", box[i].size.height);
putText(dstImg, width, Point(, ), CV_FONT_HERSHEY_COMPLEX_SMALL, 0.85, Scalar(, , ));
putText(dstImg, height, Point(, ), CV_FONT_HERSHEY_COMPLEX_SMALL, 0.85, Scalar(, , )); }
imshow("dst", dstImg);
waitKey();
}

四、倾斜物体矫正提取
#include "opencv2/opencv.hpp"
#include<iostream>
using namespace std;
using namespace cv; void main()
{
Mat srcImg = imread("E://qrcode.jpg");
imshow("src", srcImg);
Mat dstImg = srcImg.clone();
GaussianBlur(srcImg, srcImg, Size(, ), , );
cvtColor(srcImg, srcImg, CV_BGR2GRAY);
Canny(srcImg, srcImg, , );//因为原图比较复杂,所以需要将canny的值调大,去除不想要的成分
//threshold(srcImg, srcImg, 100, 255, CV_THRESH_BINARY_INV); //二值化也可以实现canny效果,不过在本例中杂絮较多
imshow("canny", srcImg);
Mat element = getStructuringElement(MORPH_RECT, Size(, ), Point(-, -)); //定义结构元素
dilate(srcImg, srcImg, element); //膨胀
imshow("dilate", srcImg);
erode(srcImg, srcImg, element);
imshow("erode", srcImg); vector<vector<Point>> contours;
vector<Vec4i> hierarcy;
findContours(srcImg, contours, hierarcy, CV_RETR_TREE, CV_CHAIN_APPROX_NONE);
vector<Rect> boundRect(contours.size());
vector<RotatedRect> box(contours.size());
Point2f rect[];
for(int i=; i<contours.size(); i++)
{
box[i] = minAreaRect(Mat(contours[i]));
boundRect[i] = boundingRect(Mat(contours[i])); if(box[i].size.width < || box[i].size.height<)//筛选
continue;
rectangle(dstImg, Point(boundRect[i].x, boundRect[i].y), Point(boundRect[i].x + boundRect[i].width, boundRect[i].y + boundRect[i].height), Scalar(, , ), , );
circle(dstImg, Point(box[i].center.x, box[i].center.y), , Scalar(, , ), -, );
box[i].points(rect);
for(int j=; j<; j++)
{
line(dstImg, rect[j], rect[(j+)%], Scalar(, , ), , );
} float angle;
cout<<"angle="<<box[i].angle<<endl;
angle = box[i].angle;
char width[], height[];
sprintf(width, "width=%0.2f", box[i].size.width);
sprintf(height, "height=%0.2f", box[i].size.height);
putText(dstImg, width, Point(, ), CV_FONT_HERSHEY_COMPLEX_SMALL, 0.85, Scalar(, , ));
putText(dstImg, height, Point(, ), CV_FONT_HERSHEY_COMPLEX_SMALL, 0.85, Scalar(, , ));
imshow("temp", dstImg); //利用仿射变换进行旋转 另一种方法,透视变换
if (< abs(angle) && abs(angle)<=)
angle = angle;//负数,顺时针旋转
else if (< abs(angle) && abs(angle)<)
angle = - abs(angle);//正数,逆时针旋转
Point2f center = box[i].center; //定义旋转中心坐标
double angle0 = angle;
double scale = ;
Mat roateM = getRotationMatrix2D(center, angle0, scale); //获得旋转矩阵,顺时针为负,逆时针为正
warpAffine(dstImg, dstImg, roateM, dstImg.size()); //仿射变换 //保存二维码
int x0=, y0=, w0=, h0=;
x0 = boundRect[i].x;
y0 = boundRect[i].y;
w0 = boundRect[i].width;
h0 = boundRect[i].height;
Mat ROI = dstImg(Rect(x0, y0, w0, h0));
imwrite("F://1.jpg", ROI);
}
imshow("dst", dstImg);
waitKey();
}




opencv学习之路(26)、轮廓查找与绘制(五)——最小外接矩形的更多相关文章
- Opencv绘制最小外接矩形、最小外接圆
Opencv中求点集的最小外结矩使用方法minAreaRect,求点集的最小外接圆使用方法minEnclosingCircle. minAreaRect方法原型: RotatedRect minAre ...
- Opencv 最小外接矩形合并拼接
前一篇画出了最小外接矩形,但是有时候画出来的矩形由于中间像素干扰或者是其他原因矩形框并不是真正想要的 如图1是一个信号的雨图,被矩形框分割成了多个小框: 需要合并矩形框达到的效果: 主要思想: 扫描两 ...
- Opencv 图片边缘检测和最小外接矩形
#include "core/core.hpp" #include "highgui/highgui.hpp" #include "imgproc/i ...
- opencv学习之路(25)、轮廓查找与绘制(四)——正外接矩形
一.简介 二.外接矩形的查找绘制 #include "opencv2/opencv.hpp" using namespace cv; void main() { //外接矩形的查找 ...
- opencv学习之路(23)、轮廓查找与绘制(二)——访问轮廓每个点
一.简介 二.画出每个轮廓的每个点 #include "opencv2/opencv.hpp" using namespace cv; void main() { Mat src= ...
- opencv学习之路(22)、轮廓查找与绘制(一)
一.简介 图2 二.代码 #include"opencv2/opencv.hpp" #include<iostream> using namespace std; us ...
- opencv学习之路(29)、轮廓查找与绘制(八)——轮廓特征属性及应用
一.简介 HSV颜色空间(hue色调,saturation饱和度,value亮度) 二.HSV滑动条 #include "opencv2/opencv.hpp" #include ...
- opencv学习之路(37)、运动物体检测(二)
一.运动物体轮廓椭圆拟合及中心 #include "opencv2/opencv.hpp" #include<iostream> using namespace std ...
- opencv学习之路(36)、运动物体检测(一)
一.简介 二.背景减法 图片说明 #include "opencv2/opencv.hpp"using namespace cv; void main() { Mat img1 = ...
随机推荐
- Angel - 模拟Kafka数据流调试FTRL的方法
Angel - 模拟Kafka数据流调试FTRL的方法 Mac或者Linux版本(Win10的Linux子系统同样适用) 创建一个目录用来安装kafka以及zookeeper等相关软件,比如,新建一个 ...
- string find_last_of 用法
int find_first_of(char c, int start = 0): 查找字符串中第1个出现的c,由位置start开始. 如果有匹配, ...
- java开发mis系统所需技术及其作用
MIS(管理信息系统--Management Information System)系统 ,是一个由人.计算机及其他外围设备等组成的能进行信息的收集.传递.存贮.加工.维护和使用的系统. 是一门新兴的 ...
- DEMO大全,超赞【申明:来源于网络】
DEMO大全,超赞[申明:来源于网络] 地址:http://www.verydemo.com/one_c55.html
- java-03-动手动脑
1. 问题:这两种方式定义的变量是一样的吗? 早期我们经常这样定义变量 int value=100;前面的示例中这样定义变量 MyClass obj = new MyClass(); 回答:一般情 ...
- 25个常用PowerShell命令总结
尽管Windows PowerShell已经出现一段时间了,习惯命令行的管理员可能对了解PowerShell功能的基础很感兴趣. 下面我们看看能由Windows PowerShell完成的最常见的25 ...
- 作业二 分布式版本控制系统Git的安装与使用
第一步:Git bash配置 修改用户名和邮箱地址: $ git config --global user.name "zzj" $ git config --global use ...
- iptables 分析(二)
原文:http://blog.chinaunix.net/uid-24207747-id-2622901.html do_command()函数分析 //负责整个用户输入的命令处理 int do_co ...
- 更新Xcode10与iOS12 遇到的bug:library not found for -lstdc++.6.0.9
更新Xcode10与iOS12 遇到的bug:library not found for -lstdc++.6.0.9 解决办法:删除pod里导入的库文件,跑一下pod,再重新导入这些库文件,跑pod ...
- array_merge() 用法
array_merge() 函数把两个或多个数组合并为一个数组. 如果键名有重复,该键的键值为最后一个键名对应的值(后面的覆盖前面的).如果数组是数字索引的,则键名会以连续方式重新索引. 注释:如果仅 ...