opencv:轮廓逼近与拟合
轮廓逼近,本质上是减少编码点
拟合圆,生成最相似的圆或椭圆
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
RNG rng(12345);
void fit_circle_demo(Mat &image);
int main(int argc, char** argv)
{
//Mat src = imread("f:/images/qq/jihe.png");
Mat src = imread("f:/images/qq/stuff.png");
if (src.empty())
{
printf("Could not find the image!\n");
return -1;
}
namedWindow("input", WINDOW_AUTOSIZE);
imshow("input", src);
// 做一个高斯模糊,消除一些细微的东西
GaussianBlur(src, src, Size(3, 3), 0);
Mat gray, binary;
cvtColor(src, gray, COLOR_BGR2GRAY);
imshow("gray", gray);
// 二值化
threshold(gray, binary, 0, 255, THRESH_BINARY | THRESH_OTSU);
imshow("binary", binary);
vector<vector<Point>> contours;
vector<Vec4i> hierarchy;
//findContours(binary, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point());
// 只绘制最外层的轮廓
findContours(binary, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point());
fit_circle_demo(src);
src = imread("f:/images/qq/stuff.png");
//多边形逼近演示
for (size_t t = 0; t < contours.size(); t++) {
Moments mm = moments(contours[t]);
// 计算每个轮廓的中心位置
double cx = mm.m10 / mm.m00;
double cy = mm.m01 / mm.m00;
circle(src, Point(cx, cy), 3, Scalar(0, 255, 0), 2, 8, 0);
double area = contourArea(contours[t]);
double clen = arcLength(contours[t], true);
Mat result;
approxPolyDP(contours[t], result, 4, true);
printf("corners: %d, colums: %d, contour area: %.2f, contour length: %.2f\n", result.rows, result.cols, area, clen);
if (result.rows == 6) {
putText(src, "poly", Point(cx, cy-10), FONT_HERSHEY_PLAIN, 1.0, Scalar(0, 255, 0), 1, 8);
}
if (result.rows == 4) {
putText(src, "rectangle", Point(cx, cy - 10), FONT_HERSHEY_PLAIN, 1.0, Scalar(0, 255, 0), 1, 8);
}
if (result.rows == 3) {
putText(src, "trangle", Point(cx, cy - 10), FONT_HERSHEY_PLAIN, 1.0, Scalar(0, 255, 0), 1, 8);
}
if (result.rows > 10) {
putText(src, "circle", Point(cx, cy - 10), FONT_HERSHEY_PLAIN, 1.0, Scalar(0, 255, 0), 1, 8);
}
}
imshow("result", src);
waitKey(0);
destroyAllWindows();
return 0;
}
void fit_circle_demo(Mat& image) {
Mat gray, binary;
cvtColor(image, gray, COLOR_BGR2GRAY);
// 二值化
threshold(gray, binary, 0, 255, THRESH_BINARY | THRESH_OTSU);
imshow("binary", binary);
vector<vector<Point>> contours;
vector<Vec4i> hierarchy;
//findContours(binary, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point());
// 只绘制最外层的轮廓
findContours(binary, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point());
//拟合圆或者椭圆
for (size_t t = 0; t < contours.size(); t++) {
//drawContours(image, contours, t, Scalar(0, 0, 255), 2, 8);
RotatedRect rrt = fitEllipse(contours[t]);
float w = rrt.size.width;
float h = rrt.size.height;
Point center = rrt.center;
circle(image, center, 3, Scalar(255, 0, 0), 2, 8, 0);
ellipse(image, rrt, Scalar(0, 255, 0), 2, 8);
}
imshow("fit demo", image);
}
opencv:轮廓逼近与拟合的更多相关文章
- OpenCV 轮廓基本特征
http://blog.csdn.net/tiemaxiaosu/article/details/51360499 OpenCV 轮廓基本特征 2016-05-10 10:26 556人阅读 评论( ...
- opencv——轮廓发现与轮廓(二值图像)分析
引言 二值图像分析最常见的一个主要方式就是轮廓发现与轮廓分析,其中轮廓发现的目的是为轮廓分析做准备,经过轮廓分析我们可以得到轮廓各种有用的属性信息. 这里顺带提下边缘检测,和轮廓提取的区别: 边缘检测 ...
- OpenCV轮廓vectorvector
OpenCV轮廓vectorvector,vector,vector,vector https://blog.csdn.net/Ahuuua/article/details/80593388 轮廓 ...
- OpenCV —— 轮廓
把检测出的边缘像素组装成轮廓 —— cvFindContours OpenCV 使用内存存储器来统一管理各种动态对象的内存.内存存储器在底层被实现为一个有许多相同大小的内存块组成的双向链表 内存储 ...
- opencv轮廓处理函数详细
ApproxChains 用多边形曲线逼近 Freeman 链 CvSeq* cvApproxChains( CvSeq* src_seq, CvMemStorage* storage, int me ...
- 【转载】openCV轮廓操作
声明:非原创,转载自互联网,有问题联系博主 1.轮廓的提取 从图片中将目标提取出来,常常用到的是提取目标的轮廓. OpenCV里提取目标轮廓的函数是findContours(), 它的输入图像是一幅二 ...
- OpenCV 轮廓检测
使用OpenCV可以对图像的轮廓进行检测.这是之前用过的代码,挺简单的,回顾一下.主要要进行以下2步操作: 1.cvThreshold():对图像进行二值化处理 2.cvFindContours(): ...
- OpenCV轮廓检测,计算物体旋转角度
效果还是有点问题的,希望大家共同探讨一下 // FindRotation-angle.cpp : 定义控制台应用程序的入口点. // // findContours.cpp : 定义控制台应用程序的入 ...
- Opencv轮廓计数(学习)
#include <iostream>#include <opencv2/opencv.hpp>#include <opencv2/xfeatures2d.hpp> ...
随机推荐
- P5048 [[Ynoi2019模拟赛]Yuno loves sqrt technology III]
为什么我感觉这题难度虚高啊-- 区间众数的出现次数- 计算器算一下 \(\sqrt 500000 = 708\) 然后我们发现这题的突破口? 考虑分块出来[L,R]块的众数出现个数 用 \(\text ...
- rp算法 随机化 刷题记录
刷随机化是真的会上瘾quq 洛谷P3973 [TJOI2015]线性代数 看oiwiki上说可以随机化...于是... 就随机在a[i]上选一位取反,然后更新答案,最后输出答案. ...无话可说 代码 ...
- Python-Django学习笔记(二)-创建一个Django项目与应用
1.创建一个Django项目 打开cmd命令行,设置好工作目录(cd 目录路径),然后输入 django-admin startproject projectname #必须安装好Django才可以执 ...
- 占位 SC
占位 SC include: SC404 SC405
- SpringBoot学习- 4、整合JWT
SpringBoot学习足迹 1.Json web token(JWT)是为了网络应用环境间传递声明而执行的一种基于JSON的开发标准(RFC 7519),该token被设计为紧凑且安全的,特别适用于 ...
- C#简单鼠标键盘钩子KMHook
简介:由三个文件构成Pinvo.cs.KeyboardHook.cs.MouseHook.cs Pinvo.cs 是KeyboardHook与MouseHook需要的一些常量消息的定义 Keyboar ...
- 常用UrlEncode编码结果
空格 ! # $ % + @ : = ? %20 %21 %23 %24 %25 %2B %40 %3A %3D %3F
- python笔记20(面向对象课程二)
今日内容 类成员 成员修饰符 内容回顾 & 补充 三大特性 封装 函数封装到类 数据封装到对象 * class Foo: def __init__(self,name,age): self.n ...
- VJ数论专题AC代码临时保存
//A #include<bits/stdc++.h> using namespace std; bool vis[1000010]; void Get_Prime() { int n = ...
- AST抽象语法树——最基础的javascript重点知识,99%的人根本不了解
AST抽象语法树——最基础的javascript重点知识,99%的人根本不了解 javascriptvue-clicommonjswebpackast 阅读约 27 分钟 抽象语法树(AST),是一 ...