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> ...
 
随机推荐
- mysql远程连接失败的两种解决方法
			
---恢复内容开始--- (这是转载别人的,因为我觉得很有用,每次都是参考这个的第二种方法解决的,不管你听不听得到,先说声谢谢!也记下来方便大家看看) mysql解决远程不能访问的二种方法,需要的朋友 ...
 - ElasticSearch安装---Windows环境
			
一.前提条件 已经安装了jdk 1.8 二.下载 中文官网: https://www.elastic.co/cn/ 中文官网下载: https://elasticsearch.cn/download/ ...
 - include=FALSE的作用
			
每次都会加载很多的包,会显示很多没用的信息,特别是那个spdep. 例如: {r include=FALSE} library(plm) library(tseries) library(zoo) l ...
 - 2018ICPC南京站Problem J. Prime Game
			
题意: 对于所有数字分解质因子,如果某个质因子在这个区间出现,则贡献为1,求所有质因子对所有区间做的贡献. 解析: 考虑如果所有全部区间都有这个质因子则这个质因子的贡献是n*(n+1)/2,对于任意因 ...
 - LaTeX技巧012:LaTeX 插图加载宏包
			
LaTeX 插图加载宏包.支持 LaTeX - DVIPDFMx; pdfLaTeX; XeLaTeX 三种编译方式,支持 eps/pdf/jpg/png 等图片格式. % Put this snip ...
 - 微信小程序——自定义菜单切换栏tabbar组件
			
效果图: wxml代码: <view class="top_tabbar" > <block wx:for="{{itemName}}" wx ...
 - BZOJ2190 SDOI2008 仪仗队  gcd,欧拉函数
			
题意:求从左下角能看到的元素个数 引理:对点(x,y),连线(0,0)-(x,y),元素个数为gcd(x,y)-1(中间元素) 即要求gcd(x,y)=1 求gcd(x,y)=1的个数 转化为2 \s ...
 - static静态不是很静
			
在类中定义变量时,不会开辟存储空间,只有类定义一个对象时才会开辟类中成员变量的内存空间,且建立一个对象开辟一次,大小与类中的成员变量及函数有关.而static在静态区开辟内存空间,不占用内存空间. 1 ...
 - django学习,captcha图形验证码的使用
			
很多网站在登录或者注册的时候都有验证码,让你去输入. 刚好有这么一款插件,可以满足这个功能 首先,先pip install django-simple-captcha 然后再setting里添加,如 ...
 - QT安装和vs2015使用
			
下载Qt5.7.0安装包(qt-windows-opensource)与Qt插件(Visual Studio Add-in) QT软件下载地址: http://download.qt.io/archi ...