opencv学习之路(27)、轮廓查找与绘制(六)——外接圆、椭圆拟合、逼近多边形曲线、计算轮廓面积及长度、提取不规则轮廓
一、最小外接圆

#include "opencv2/opencv.hpp"
#include<iostream>
using namespace std;
using namespace cv; void main() {
Mat srcImg = imread("E://10.png");
imshow("src", srcImg);
Mat dstImg = srcImg.clone();
GaussianBlur(srcImg, srcImg, Size(, ), , );
cvtColor(srcImg, srcImg, CV_BGR2GRAY);
Canny(srcImg, srcImg, , );
imshow("Canny", srcImg); //查找轮廓
vector<vector<Point>> contours;
vector<Vec4i> hierarcy;
findContours(srcImg, contours, hierarcy, CV_RETR_TREE, CV_CHAIN_APPROX_NONE);
cout << "num=" << contours.size() << endl; Point2f center; //定义圆中心坐标
float radius; //定义圆半径
for (int i = ; i<contours.size(); i++) //依次遍历每个轮廓
{
minEnclosingCircle(Mat(contours[i]), center, radius);
drawContours(dstImg, contours, i, Scalar(, , ), , );
circle(dstImg, center, radius, Scalar(, , ), , ); //绘制第i个轮廓的最小外接圆
}
imshow("dst", dstImg); waitKey();
}

二、椭圆拟合

#include "opencv2/opencv.hpp"
using namespace cv; void main() {
Mat srcImg = imread("E://10.png");
imshow("src", srcImg);
Mat dstImg = srcImg.clone();
GaussianBlur(srcImg, srcImg, Size(, ), , );
cvtColor(srcImg, srcImg, CV_BGR2GRAY);
Canny(srcImg, srcImg, , );
imshow("Canny", srcImg); //查找轮廓
vector<vector<Point>> contours;
vector<Vec4i> hierarcy;
findContours(srcImg, contours, hierarcy, CV_RETR_TREE, CV_CHAIN_APPROX_NONE); vector<RotatedRect> box(contours.size());
Point2f rect[];
for (int i = ; i<contours.size(); i++)
{
box[i] = fitEllipse(Mat(contours[i]));
//ellipse(dstImg, box[i].center, Size(box[i].size.width/2, box[i].size.height/2), box[i].angle, 0, 360, Scalar(0, 255, 0), 2, 8);
ellipse(dstImg, box[i], Scalar(, , ), , );
}
imshow("dst", dstImg); waitKey();
}

三、逼近多边形曲线

#include "opencv2/opencv.hpp"
using namespace cv; void main() {
Mat srcImg = imread("E://02.jpg");
imshow("src", srcImg);
Mat dstImg = srcImg.clone();
Mat dstImg2(srcImg.size(), CV_8UC3, Scalar::all());//全黑图像 GaussianBlur(srcImg, srcImg, Size(, ), , );
cvtColor(srcImg, srcImg, CV_BGR2GRAY);
//Canny(srcImg, srcImg, 100, 200);
threshold(srcImg, srcImg, , , CV_THRESH_BINARY_INV);
imshow("threshold", srcImg); vector<vector<Point>> contours;
vector<Vec4i> hierarcy;
findContours(srcImg, contours, hierarcy, CV_RETR_TREE, CV_CHAIN_APPROX_NONE);
vector<vector<Point>> contours_poly(contours.size()); for (int i = ; i<contours.size(); i++)
{
approxPolyDP(Mat(contours[i]), contours_poly[i],, true);//true曲线封闭,反之不封闭
drawContours(dstImg, contours, i, Scalar(, , ), , );//绘制轮廓
drawContours(dstImg2, contours_poly, i, Scalar(, , ), , ); //绘制多边形逼近
}
imshow("dst", dstImg);
imshow("approx", dstImg2); waitKey();
}

四、计算轮廓面积及长度(可用于轮廓筛选)

#include "opencv2/opencv.hpp"
#include<iostream>
using namespace std;
using namespace cv; void main() {
Mat srcImg = imread("E://33.jpg");
imshow("src", srcImg);
Mat dstImg = srcImg.clone();
Mat dstImg2(srcImg.size(), CV_8UC3, Scalar::all()); GaussianBlur(srcImg, srcImg, Size(, ), , );
cvtColor(srcImg, srcImg, CV_BGR2GRAY);
//Canny(srcImg, srcImg, 100, 200);
threshold(srcImg, srcImg, , , CV_THRESH_BINARY);
imshow("threshold", srcImg); vector<vector<Point>> contours;
vector<Vec4i> hierarcy;
findContours(srcImg, contours, hierarcy, CV_RETR_TREE, CV_CHAIN_APPROX_NONE);
cout << "num=" << contours.size() << endl; for (int i = ; i<contours.size(); i++)
{
double area = contourArea(contours[i]);//计算第i个轮廓的面积
cout<<"area--"<<i<<"---"<<area<<endl; double length = arcLength(contours[i], true);
cout << "length--" << i << "---" << length << endl;
//if(area>10000) //面积大约1W
//if(area> 100 && area<300) if (length< && area>)
drawContours(dstImg, contours, i, Scalar(, , ), , );
}
imshow("dst", dstImg);
waitKey();
}

五、提取不规则轮廓
#include "opencv2/opencv.hpp"
using namespace cv; void main() {
Mat srcImg = imread("E://220.jpg");
imshow("src", srcImg);
Mat dstImg = srcImg.clone(); //原图备份
Mat tempImg = srcImg.clone(); //原图备份
Mat tempImg2(srcImg.size(), CV_8UC3, Scalar::all()); //定义全黑的和原图一样大小的图像
Mat draw(srcImg.size(), CV_8UC3, Scalar::all());
Mat tempImg3(srcImg.size(), CV_8UC3, Scalar::all()); GaussianBlur(srcImg, srcImg, Size(, ), , );
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_TREE, CV_CHAIN_APPROX_NONE);
while ()
{
for (int i = ; i<contours.size(); i++)
{
tempImg2.copyTo(draw); //每次进入将draw清空为全黑
tempImg2.copyTo(tempImg3);
//drawContours(dstImg, contours, i, Scalar(0, 255, 0), 5, 8);
drawContours(draw, contours, i, Scalar(, , ), -, );
Mat mask; //定义掩码
cvtColor(draw, mask, CV_BGR2GRAY);
tempImg.copyTo(tempImg3, mask); //将tempImg 复制到tempImg3(只有mask部分被复制)
imshow("draw", draw);
imshow("result", tempImg3);
char key = waitKey();
if (key == ) //按下Esc键跳出for循环
break;
}
break;
}
}

opencv学习之路(27)、轮廓查找与绘制(六)——外接圆、椭圆拟合、逼近多边形曲线、计算轮廓面积及长度、提取不规则轮廓的更多相关文章
- OpenCV学习笔记(27)KAZE 算法原理与源码分析(一)非线性扩散滤波
http://blog.csdn.net/chenyusiyuan/article/details/8710462 OpenCV学习笔记(27)KAZE 算法原理与源码分析(一)非线性扩散滤波 201 ...
- opencv学习之路(28)、轮廓查找与绘制(七)——位置关系及轮廓匹配
一.点与轮廓的距离及位置关系 #include "opencv2/opencv.hpp" #include <iostream> using namespace std ...
- 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学习之路(37)、运动物体检测(二)
一.运动物体轮廓椭圆拟合及中心 #include "opencv2/opencv.hpp" #include<iostream> using namespace std ...
- opencv学习之路(25)、轮廓查找与绘制(四)——正外接矩形
一.简介 二.外接矩形的查找绘制 #include "opencv2/opencv.hpp" using namespace cv; void main() { //外接矩形的查找 ...
- opencv学习之路(24)、轮廓查找与绘制(三)——凸包
一.简介 二.绘制点集的凸包 #include<opencv2/opencv.hpp> using namespace cv; void main() { //---绘制点集的凸包 Mat ...
- opencv学习之路(29)、轮廓查找与绘制(八)——轮廓特征属性及应用
一.简介 HSV颜色空间(hue色调,saturation饱和度,value亮度) 二.HSV滑动条 #include "opencv2/opencv.hpp" #include ...
- opencv学习之路(26)、轮廓查找与绘制(五)——最小外接矩形
一.简介 二.轮廓最小外接矩形的绘制 #include "opencv2/opencv.hpp" using namespace cv; void main() { //轮廓最小外 ...
随机推荐
- 完美:利用旧版iCloud更改Apple ID地区
朋友们,你们有没有尝试过从大陆地区以外的App Store上下载APP呢?或许听起来蛮有趣的,其实并不难,只需要更改Apple ID的地区就可以了,许多用户就是卡在下一步,需要输入付款信息,不过下面苹 ...
- dubbo+zookeeper+spring实例
互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构以及流动计算架构势在必行,Dubbo是一个分布式服务框架,在这种情况下诞生的.现在核心业务抽取出来,作为独立的服务,使 ...
- vue动态组件切换(选项卡)
vue的动态组件 <template :is='变量'></template> 可以通过改变变量,来改变template的替换内容.达到选项卡的功能 如果想要切换保持不重新创建 ...
- 教师信息管理系统(方式一:数据库为oracle数据库;方式二:存储在文件中)
方式一: 运行截图 数据库的sql语句: /*Navicat Oracle Data TransferOracle Client Version : 12.1.0.2.0 Source Server ...
- allegro画元件封装
LP Wizard 10.5 根据标准,输入datasheet的尺寸,可以计算出推荐的焊盘和封装. 封装必须画的层: 1.引脚 2.pakage-> 2.1.assembly_top,add线( ...
- 运行opatch lsinventory
http://blog.itpub.net/4227/viewspace-704451/ 运行opatch lsinventory 注意执行opatch lsinventory的路径: > $O ...
- LeetCode 993 Cousins in Binary Tree 解题报告
题目要求 In a binary tree, the root node is at depth 0, and children of each depth k node are at depth k ...
- mysql脚本手动修改成oracle脚本
今天有一个需求,立了一个新项目,新项目初步定了使用了现有的框架,但数据库要求由原来的mysql改成oracle,所以原来的基础版本的数据库脚本就需要修改成符合oracle的脚本,修改完成后,总结了一下 ...
- python练习题-day11
1.编写装饰器,为多个函数加上认证的功能(用户的账号密码来源于文件), 要求:登录成功一次,后续的函数都无需再输入用户名和密码 flag=False def wrapper(fun): def inn ...
- 接口测试工具-Jmeter使用笔记(九:跨线程组传递变量)
使用场景: 请求API需要授权令牌,但是授权令牌只需要获取一次,即可调用服务器上其他业务接口. 所以我想要把授权操作放在单独的一个线程,业务流放在其他线程. 这就需要我把从授权线程获取的令牌传入业务流 ...