轮廓逼近,本质上是减少编码点

拟合圆,生成最相似的圆或椭圆

#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:轮廓逼近与拟合的更多相关文章

  1. OpenCV 轮廓基本特征

     http://blog.csdn.net/tiemaxiaosu/article/details/51360499 OpenCV 轮廓基本特征 2016-05-10 10:26 556人阅读 评论( ...

  2. opencv——轮廓发现与轮廓(二值图像)分析

    引言 二值图像分析最常见的一个主要方式就是轮廓发现与轮廓分析,其中轮廓发现的目的是为轮廓分析做准备,经过轮廓分析我们可以得到轮廓各种有用的属性信息. 这里顺带提下边缘检测,和轮廓提取的区别: 边缘检测 ...

  3. OpenCV轮廓vectorvector

    OpenCV轮廓vectorvector,vector,vector,vector https://blog.csdn.net/Ahuuua/article/details/80593388   轮廓 ...

  4. OpenCV —— 轮廓

    把检测出的边缘像素组装成轮廓  ——  cvFindContours OpenCV 使用内存存储器来统一管理各种动态对象的内存.内存存储器在底层被实现为一个有许多相同大小的内存块组成的双向链表 内存储 ...

  5. opencv轮廓处理函数详细

    ApproxChains 用多边形曲线逼近 Freeman 链 CvSeq* cvApproxChains( CvSeq* src_seq, CvMemStorage* storage, int me ...

  6. 【转载】openCV轮廓操作

    声明:非原创,转载自互联网,有问题联系博主 1.轮廓的提取 从图片中将目标提取出来,常常用到的是提取目标的轮廓. OpenCV里提取目标轮廓的函数是findContours(), 它的输入图像是一幅二 ...

  7. OpenCV 轮廓检测

    使用OpenCV可以对图像的轮廓进行检测.这是之前用过的代码,挺简单的,回顾一下.主要要进行以下2步操作: 1.cvThreshold():对图像进行二值化处理 2.cvFindContours(): ...

  8. OpenCV轮廓检测,计算物体旋转角度

    效果还是有点问题的,希望大家共同探讨一下 // FindRotation-angle.cpp : 定义控制台应用程序的入口点. // // findContours.cpp : 定义控制台应用程序的入 ...

  9. Opencv轮廓计数(学习)

    #include <iostream>#include <opencv2/opencv.hpp>#include <opencv2/xfeatures2d.hpp> ...

随机推荐

  1. VsCode开发Java SpringBoot遇到的问题

    报错截图 报错一:Build failed, Do you want to continue? 编译失败,你想继续吗? 报错二:ConfigError:The Project "Demo&q ...

  2. MySQL的联表查询

    MySQL的联表查询 首选:分析查询的字段来自哪些表 进而:确定交集 然后:确定判断的条件 比如:从student表 和 result表 查学号.考试名称.学时.考试日期.考试成绩 表1: 学号 考试 ...

  3. Tram POJ - 1847 spfa

    #include<iostream> #include<algorithm> #include<queue> #include<cstdio> #inc ...

  4. 《深入理解java虚拟机》读书笔记十一——第十二章

    第十二章  Java内存模型与线程 1.硬件效率与一致性 由于计算机的存储设备与处理器的运算速度有几个数量级的差距,所以现代计算机系统都不得不加入一层读写速度尽可能接近处理器运算速度的高速缓存(Cac ...

  5. jQuery里ready方法用原生js实现原理

    function ready(fn){ if(document.addEventListener){ //标准浏览器 document.addEventListener('DOMContentLoad ...

  6. 重载(Overload)和重写(Override)的区别是什么?

    首先java程序的运行分为编译和运行两部分. 所以重载和重写在这一点就有很明显的区别,因为重写方法的方法名和参数个数类型都一样,所以在java虚拟机的编译阶段是识别不出重写的方法的不同,在运行期间才可 ...

  7. Mysql备份参数

    --all-databases , -A 导出全部数据库. mysqldump -uroot -p --all-databases --all-tablespaces , -Y 导出全部表空间. my ...

  8. echarts 设置默认选中,单选

    默认选中 和 不选中 传送门

  9. socket 简单实现HTTP服务器

    # -*- coding: utf-8 -*- # @Time : 2019-07-17 1:39 # @File : 网络socket实现http服务器.py # @Software: PyChar ...

  10. JS定义类的六种方式详解

    转载自: http://www.jb51.net/article/84089.htm 在前端开发中,经常需要定义JS类.那么在JavaScript中,定义类的方式有几种,分别是什么呢?本文就JS定义类 ...