这是一张经过处理后的红灯的图像,我们需要找到其中的红灯,可以看到是两个圆,用霍夫圆之后发现其中调参非常麻烦,于是写了一个根据轮廓来分析圆的算法。

算法思想:findContours()找到图像的轮廓,使用minEnclosingCircle()找到轮廓的最小包围矩形,计算轮廓上的每个点到圆心的距离和半径的差值,进行累加(简单来说就是求轮廓中每个点到圆心距离和半径的方差),当累加和小于某个值时,我们认为它是一个圆。

核心函数:

//对轮廓进行分析
float calculateCircularity(vector<Point> contours)
{Point2f center;float radius = 0;minEnclosingCircle((Mat)contours, center, radius);float fsum = 0;float fcompare = 0;for (int i = 0; i < contours.size(); i++){Point2f ptmp = contours[i];//计算距离float fdistance = sqrt(((float)ptmp.x - center.x)*((float)ptmp.x - center.x) + ((float)ptmp.y - center.y)*((float)ptmp.y - center.y));//累加距离到圆心的差值float fdiff = abs(fdistance - radius);fsum = fsum + fdiff;}fcompare = fsum / (float)contours.size();return fcompare;
}

首先找到轮廓,并且对绘制出轮廓,蓝色为轮廓,其中包含了我们需要的红灯和不需要的数字

vector<vector<Point>>contours;vector<Vec4i>hierarchy;findContours(binary,contours,hierarchy, RETR_LIST,CHAIN_APPROX_SIMPLE);drawContours(src, contours, -1, Scalar(255, 0, 0));

我们对提取的每个轮廓进行圆的特性分析,并且输出得到的差值累加和

可以看到有两个累加和比较小的,不确定是否是两个红灯,暂时设置阈值为0.6,将轮廓分析后累加和小于阈值的用绿色进行绘制

成功找到两个红灯

下面贴上整个工程代码

#include<opencv2\opencv.hpp>
#include<iostream>using namespace std;
using namespace cv;//对轮廓进行分析
float calculateCircularity(vector<Point> contours)
{Point2f center;float radius = 0;minEnclosingCircle((Mat)contours, center, radius);float fsum = 0;float fcompare = 0;for (int i = 0; i < contours.size(); i++){Point2f ptmp = contours[i];//计算距离float fdistance = sqrt(((float)ptmp.x - center.x)*((float)ptmp.x - center.x) + ((float)ptmp.y - center.y)*((float)ptmp.y - center.y));//累加距离到圆心的差值float fdiff = abs(fdistance - radius);fsum = fsum + fdiff;}fcompare = fsum / (float)contours.size();return fcompare;
}
int main()
{Mat src = imread("cc.png");//读入有圆的图片imwrite("src.jpg", src);//红绿灯在图像上方,可以选择只分析上半部分图像Mat src_copy = src(Rect(0, 0, src.cols, src.rows / 2));Mat gray;Mat binary;vector<Mat>matSplit;cvtColor(src_copy, gray, COLOR_BGR2GRAY);//二值化threshold(gray, binary, 100, 255, THRESH_OTSU);//闭操作Mat kernel = getStructuringElement(MORPH_ELLIPSE, Size(5, 5));morphologyEx(binary, binary, MORPH_CLOSE, kernel);//找轮廓vector<vector<Point>>contours;vector<Vec4i>hierarchy;findContours(binary,contours,hierarchy, RETR_LIST,CHAIN_APPROX_SIMPLE);vector<vector<Point>>DrawContour;for (int i = 0; i < contours.size(); i++){//对每个轮廓进行分析float fCircle = calculateCircularity(contours[i]);cout << fCircle << endl;//符合圆的特性,则加入vectorif(fCircle<0.6)DrawContour.push_back(contours[i]);}drawContours(src, DrawContour, -1, Scalar(0, 255, 0), 3);imwrite("circle.jpg", src);waitKey(0);return 0;
}

opencv学习——轮廓分析寻找近似圆相关推荐

  1. OpenCV学习——轮廓检测

    前言 轮廓检测是传统视觉中非常常用的功能,这里简单记录一下opencv中的轮廓检测算法使用方法,至于理论,后续有机会再去细品. 国际惯例: OpenCV官方的轮廓检测教程python版 OpenCV中 ...

  2. opencv 最大内接矩形_OpenCV之二值图像分析 – 寻找最大内接圆

    python代码: from __future__ import print_function from __future__ import division import cv2 as cv imp ...

  3. OpenCV学习笔记(十七):查找并绘制轮廓:findContours(),drawContours(),approxPolyDP()

    OpenCV学习笔记(十七):查找并绘制轮廓:findContours() 1.findContours() 函数 该函数使用Suzuki85算法从二值图像中检索轮廓.轮廓线是一种用于形状分析.目标检 ...

  4. OpenCV学习笔记(九)——图像轮廓(下)

    <OpenCV轻松入门:面向Python>学习笔记(九) 1-3 查找并绘制轮廓.矩特性及Hu矩 4-5 轮廓拟合及凸包 6. 利用形状场景算法比较轮廓 6.1 计算形状场景距离 6.2 ...

  5. python使用opencv查找轮廓_(八)OpenCV-Python学习—轮廓查找,绘制和拟合

    针对物体轮廓,opencv还提供了一些相关的函数,来处理轮廓查找,绘制,拟合,以及计算轮廓周长和面积等,详细介绍如下: 1. 寻找和绘制轮廓 opencv的findContours()能寻找图片中的轮 ...

  6. opencv学习笔记20:图像轮廓

    图像轮廓 Contours:轮廓 轮廓是将没有连着一起的边缘连着一起. 边缘检测检测出边缘,边缘有些未连接在一起. 注意问题 1.对象为二值图像,首先进行阈值分割或者边缘检测. 2.查找轮廓需要更改原 ...

  7. OpenCV为轮廓创建边界框和圆

    OpenCV为轮廓创建边界框和圆 为轮廓创建边界框和圆 目标 代码 解释 结果 为轮廓创建边界框和圆 目标 在本教程中,您将学习如何: 使用OpenCV函数cv :: boundingRect 使用O ...

  8. OpenCV在图像中寻找轮廓

    OpenCV在图像中寻找轮廓 在图像中寻找轮廓 目标 代码 结果 在图像中寻找轮廓 目标 在本教程中,您将学习如何: 使用OpenCV函数cv :: findContours 使用OpenCV函数cv ...

  9. 使用Python,OpenCV沿着轮廓寻找极值点

    使用Python,OpenCV沿着轮廓寻找极值点 这篇博客将介绍如何使用Python,OpenCV沿着轮廓寻找极值点,找到最北.最南.最东和最西(x,y)坐标.虽然这项技能本身并不有用,但它通常被用作 ...

最新文章

  1. ubuntu16 kubernetes1.6安装(六、node节点部署)
  2. asp.net序列化
  3. 皮一皮:现在的年轻人不得了吖...
  4. 你见过的“垃圾”项目是这样子么?
  5. POJ 1944 Fiber Communications (枚举 + 并查集 OR 线段树)
  6. linux目录规范及简单说明
  7. html广告悬浮窗口,JS实现悬浮移动窗口(悬浮广告)的特效
  8. Appium 解决手势密码 (java篇)
  9. 一位做了5年Java开发的读者,跟我说面试题都不会答···
  10. 数组与字符串的相互转换
  11. 大工20秋C语言在线测试,大工20秋《计算机应用基础》在线测试
  12. 基于javaweb房屋租赁系统设计与实现
  13. 四种传真接收模式概述
  14. 数据库的四个文本类型的差异
  15. 浅谈什么是 云原生
  16. 配置mpls vpn基本组网-hub and spoke
  17. 一文读懂基于RC522和S50的RFID开发
  18. mapi java_[Security:090504]Certificate chain received from mapi.alipay.com
  19. 清华大学计算机系录取分数浙江,清华在浙江录取专业志愿满足率100% 录取人数突破160...
  20. 网络报修信息管理代码java_javaweb在线报修维修系统、java+ssh+mysql实现

热门文章

  1. Android所有权限说明
  2. [绍棠] Scrapy+Flask+Mongodb+Swift开发全攻略
  3. 蓝桥杯算法训练合集十七 1.数字反转2.试题39713.矮人采金子4.筛法5.机器指令
  4. eclipse出现繁体字的解决办法
  5. 方波的傅里叶变换_疫情当务之急,苍老师教你如何用傅里叶变换为武汉加油......
  6. 【毕业设计】基于51单片机的智能窗帘设计(原理图+原理图+仿真+论文)
  7. 域名怎么跳转到另外一个网站?常见网页跳转方法和特点对比
  8. 关于Git,你真的学会了吗?
  9. 达芬奇 17.1.1为苹果 M1 Mac 添加 H.264 10bit 硬件加速解码支持
  10. 微服务注册中心-Eureka