Opencv+ROS实现颜色识别应用
目录
一、工具
二、原理
概念
本质
三、实践
添加发布话题
主要代码
四、成果
五、总结
一、工具
opencv+ros
ubuntu18.04
摄像头
二、原理
概念
彩色图像:RGB(红,绿,蓝)
HSV图像:H(色调)S(饱和度)V(亮度)
色调(H:hue):用角度度量,取值范围为0°~360°,从红色开始按逆时针方向计算,红色为0°,绿色为120°,蓝色为240°。它们的补色是:黄色为60°,青色为180°,品红为300°;
饱和度(S:saturation):取值范围为0.0~1.0,值越大,颜色越饱和。
亮度(V:value):取值范围为0(黑色)~255(白色)。
但是在opencv中引用的范围有所不同,给出下表。
本质
颜色识别本质就是在图像上提取出你想要的颜色阈值,然后通过降噪优化模型,轮廓检测进行框选。
要点:
- RGB转HSV
- 所需颜色阈值(hsv),并二值化
- 腐蚀操作除噪,Canny算法进行边缘检测
- 最后通过findContours()函数找出轮廓坐标
三、实践
读取摄像头
VideoCapture cap(video_device); //dev/video0
RGB转HSV
cvtColor(frame, imghsv, COLOR_BGR2HSV);
直方图均衡化
split(imghsv, hsvSplit);
equalizeHist(hsvSplit[2], hsvSplit[2]);
merge(hsvSplit, imghsv);
直方图均衡化是一种简单有效的图像增强技术,用于增强动态范围偏小的图像的对比度
定义颜色阈值,这里选取红色
Scalar lower_red(156, 43, 46);Scalar upper_red(180, 255, 255); // 定义红色的HSV范围inRange(imghsv, lower_red, upper_red, mask);//二值化红色部分
inRange()函数就是检测imghsv内所有像素是否在lower-upper之间,如果是则设为255,也就是白色。输出的是二值图。
用腐蚀,膨胀操作去噪点
Mat kernel = getStructuringElement(MORPH_RECT, Size(3, 3));morphologyEx(mask, mask, MORPH_OPEN, kernel);//开运算morphologyEx(mask, mask, MORPH_CLOSE, kernel);//闭运算
腐蚀,膨胀操作的对象是二值化图像
- 腐蚀:变精细
- 膨胀:变粗矿
- 开运算:先腐蚀后膨胀 消去一个黑图中的很多小白点
- 闭运算:先膨胀后腐蚀 消去一个白图中的很多小黑点
- 梯度运算:膨胀-腐蚀
高斯滤波,Canny边缘检测
GaussianBlur(mask, mask, Size(3, 3), 0);//高斯滤波Canny(mask, mask, 100, 250);//canny算子边缘检测
Canny()函数参数表明:
第一个:InputArray类型的image,输入图像
第二个:OutputArray类型的edges,输出的边缘图
第三个:double类型的threshold1,第一个滞后性阈值
第四个:double类型的threshold2,第二个滞后性阈值
Canny过程为
- 高斯滤波获得平滑图像
- 计算每个像素点的梯度强度和方向
- 应用非极大值抑制,消除边缘检测带来的杂散响应
- 双阈值确定真实或潜在的边缘
- 抑制弱化边缘完成边缘检测
然后开始找轮廓
findContours()函数
findContours(mask,contours,hierarchy,RETR_EXTERNAL,CHAIN_APPROX_SIMPLE,Point());
第一个参数:输入图像
第二个参数:所有轮廓
第三个参数:表示第i个轮廓的后一个轮廓、前一个轮廓、父轮廓、内嵌轮廓的索引编号
第四个参数:RETR_EXTERNAL只检测最外围轮廓
第五个参数:CHAIN_APPROX_SIMPLE 仅保存轮廓的拐点信息
寻找最大轮廓
vector<double> Area(contours.size());//寻找最大面积的轮廓for (int i = 1; i < contours.size(); i++) {Area[i] = contourArea(contours[i]);if (Area[i] > Area[max]) {max = i;} }Rect boundRect = boundingRect(Mat(contours[max]));circle(frame, Point(boundRect.x + boundRect.width/2, boundRect.y + boundRect.height/2), 5, Scalar(0,0,255), -1);
boundingRect()函数
表示包围轮廓的最大矩形
返回四个参数
第一个:boundRect.x
第二个:boundRect.y
第三个:boundRect.width
第四个:boundRect.hight
左上角顶点的像素坐标值及矩形边界的宽和高
然后将矩形在原画面画出即可
ROS_INFO("x:%d,y:%d",boundRect.x+ boundRect.width/2, boundRect.y + boundRect.height/2);
rectangle(frame, Point(boundRect.x, boundRect.y), Point(boundRect.x + boundRect.width, boundRect.y + boundRect.height), Scalar( 0, 0, 255), 2);
添加发布话题
毕竟是在ros下编写的,我们要把像素坐标发布出去,这里自定义一个消息类型
boundingbox.msg
用来表示类和坐标值
主要代码
while (ros::ok()) { cap >> frame; //摄像头画面赋给frameif(!frame.empty()) //画面是否正常{ /*对图片二次处理*/cvtColor(frame, imghsv, COLOR_BGR2HSV);// 将图像转换为HSV颜色空间split(imghsv, hsvSplit);equalizeHist(hsvSplit[2], hsvSplit[2]);merge(hsvSplit, imghsv);inRange(imghsv, lower_red, upper_red, mask);//二值化红色部分Mat kernel = getStructuringElement(MORPH_RECT, Size(5, 5));morphologyEx(mask, mask, MORPH_OPEN, kernel);//开运算morphologyEx(mask, mask, MORPH_CLOSE, kernel);//闭运算GaussianBlur(mask, mask, Size(5, 5), 0);//高斯滤波Canny(mask, mask, 150, 100);//canny算子边缘检测vector<vector<Point> > contours;vector<Vec4i> hierarchy;findContours(mask,contours,hierarchy,RETR_EXTERNAL,CHAIN_APPROX_SIMPLE,Point()); //ROS_INFO("个数为%d",int(contours.size()));vector<double> Area(contours.size());if(contours.size() > 0 ){//寻找最大面积的轮廓for (int i = 1; i < contours.size(); i++) {Area[i] = contourArea(contours[i]);if (Area[i] > Area[max]) {max = i;} }Rect boundRect = boundingRect(Mat(contours[max]));circle(frame, Point(boundRect.x + boundRect.width/2, boundRect.y + boundRect.height/2), 5, Scalar(0,0,255), -1);ROS_INFO("x:%d,y:%d",boundRect.x+ boundRect.width/2, boundRect.y + boundRect.height/2);rectangle(frame, Point(boundRect.x, boundRect.y), Point(boundRect.x + boundRect.width, boundRect.y + boundRect.height), Scalar( 0, 0, 255), 2);detect_msg.Class = "red";detect_msg.xmin = boundRect.x;detect_msg.xmax=boundRect.x + boundRect.width;detect_msg.ymin=boundRect.y;detect_msg.ymax= boundRect.y + boundRect.height;}
四、成果
运行画面
查看话题
这里识别画面内所有红色区域
五、总结
写代码过程中还是遇到很多问题的,不知道是opencv版本不兼容的问题还是哪里我编写不细致,节点总是挂掉。
但还是能完成基本需求。
这里把报错留下,希望有大佬能帮帮我
OpenCV Error: Assertion failed (npoints >= 0 && (depth == CV_32F || depth == CV_32S)) in pointSetBoundingRect, file /build/opencv-L2vuMj/opencv-3.2.0+dfsg/modules/imgproc/src/shapedescr.cpp, line 466
terminate called after throwing an instance of 'cv::Exception'
what(): /build/opencv-L2vuMj/opencv-3.2.0+dfsg/modules/imgproc/src/shapedescr.cpp:466: error: (-215) npoints >= 0 && (depth == CV_32F || depth == CV_32S) in function pointSetBoundingRect
应该是boundingRect()函数的问题,但不知道问题在哪
欢迎评论区指正。
相关文章:
Opencv+ROS实现颜色识别应用
目录 一、工具 二、原理 概念 本质 三、实践 添加发布话题 主要代码 四、成果 五、总结 一、工具 opencvros ubuntu18.04 摄像头 二、原理 概念 彩色图像:RGB(红,绿,蓝) HSV图像:H࿰…...
蓝桥杯c++算法秒杀【6】之动态规划【下】(数字三角形、砝码称重(背包问题)、括号序列、异或三角:::非常典型的必刷例题!!!)
别忘了请点个赞收藏关注支持一下博主喵!!!! ! ! ! ! 关注博主,更多蓝桥杯nice题目静待更新:) 动态规划 三、括号序列 【问题描述】 给定一个括号序列,要求尽可能少地添加若干括号使得括号序列变得合…...
C++设计模式(单例模式)
一、介绍 1.动机 在软件系统中,经常有这样一些特殊的类,必须保证它们在系统中只存在一个实例,才能确保它们的逻辑正确性、以及良好的效率。 如何绕过常规的构造器,提供一种机制来保证一个类只有一个实例? 这应该是类设计者的…...
前端---CSS(部分用法)
HTML画页面--》这个页面就是页面上需要的元素罗列起来,但是页面效果很差,不好看,为了让页面好看,为了修饰页面---》CSS CSS的作用:修饰HTML页面 用了CSS之后,样式和元素本身做到了分离的效果。---》降低了代…...
2024年最新版Java八股文复习
最新版本Java八股文复习,每天更新一篇,博主正在持续努力更新中~~~ 一、Java基础篇1、怎么理解面向对象?简单说说封装、继承、多态三大特性?2、多态体现在哪几个方面?3、面向对象的设计原则你知道有哪些吗?4…...
计算机毕业设计Hadoop+Spark音乐推荐系统 音乐预测系统 音乐可视化大屏 音乐爬虫 HDFS hive数据仓库 机器学习 深度学习 大数据毕业设计
温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 作者简介:Java领…...
MyBatis高级扩展
一、Mapper批量映射优化: 1.需求: Mapper 配置文件很多时,在全局配置文件中一个一个注册太麻烦,希望有一个办法能够一劳永逸 2.配置方式: Mybatis允许在指定Mapper映射文件时,只指定其所在的包: <mappers><package name"c…...
代码美学2:MATLAB制作渐变色
效果: %代码美学:MATLAB制作渐变色 % 创建一个10x10的矩阵来表示热力图的数据 data reshape(1:100, [10, 10]);% 创建热力图 figure; imagesc(data);% 设置颜色映射为“cool” colormap(cool);% 在热力图上添加边框 axis on; grid on;% 设置热力图的颜色…...
浅谈- “ 变量中 无符号 与 有符号 的 值转换 ”
在同一个表达式中,若同时出现 无符号变量 与 有符号变量 : 1、都转换为无符号类型:(注:2^324294967296)即unsigned int 的最大值 2、然后再运行表达式 实例: #include <stdio.h>char fun(…...
【AI绘画】Midjourney进阶:色调详解(上)
博客主页: [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: AI绘画 | Midjourney 文章目录 💯前言💯Midjourney中的色彩控制为什么要控制色彩?为什么要在Midjourney中控制色彩? 💯色调白色调淡色调明色调 💯…...
代码管理之Gitlab
文章目录 Git基础概述场景本地修改未提交,拉取远程代码修改提交本地,远程已有新提交 GitIDEA引入Git拉取仓库代码最后位置 Git基础 概述 workspace 工作区:本地电脑上看到的目录; repository 本地仓库:就是工作区中隐…...
防御网络攻击的创新策略
关键要点 ● 了解各种类型的网络攻击对于组织加强防御至关重要。 ● 制定敏捷的网络安全策略可帮助企业快速应对新出现的威胁。 ● 跨行业协作和威胁情报共享可以增强整体安全性。 网络攻击威胁日益严重 网络攻击的数量和复杂程度急剧增加,对全球组织构成了重大…...
C++软件设计模式之组合模式概述
组合模式(Composite Pattern)是C软件设计模式中的一种,主要用于解决对象的层次结构问题。它允许你将对象组合成树形结构来表示“部分-整体”的层次结构,使得客户端可以统一地处理单个对象和组合对象。 主要用于解决的问题&#x…...
利用HTML5和CSS来实现一个漂亮的表格样式
利用HTML5和CSS来实现一个漂亮的表格样式 第一步:创建HTML结构第二步:添加CSS样式第三步:响应式设计第四步:加入交互效果 第一步:创建HTML结构 我们将用HTML创建一个基本的表格结构。代码如下: <!DOCT…...
Vivado程序固化到Flash
在上板调试FPGA时,通常使用JTAG接口下载程序到FPGA芯片中,FPGA本身是基于RAM工艺的器件,因此掉电后会丢失芯片内的程序,需要重新烧写程序。但是当程序需要投入使用时不能每一次都使用JTAG接口下载程序,一般FPGA的外围会…...
HCIA笔记3--TCP-UDP-交换机工作原理
1. tcp协议 可靠的连接 1.1 报文格式 1.2 三次握手 1.3 四次挥手 为什么TIME_WAIT需要2MSL的等待时间? (a) 为了实现可靠的关闭 (b)为了让过期的报文在网络上消失 对于(a), 假设host发给server的last ack丢了。 ser…...
计算机网络的功能
目录 信息交换 资源共享 分布式处理 可靠性增强 集中管理 信息交换 计算机网络最基本的功能之一是允许不同设备之间的数据通信。这包括电子邮件的发送和接收、即时消息的传递、文件传输等。通过网络,用户可以轻松地与全球各地的其他人进行沟通和协作。 信息交…...
Redis设计与实现第14章 -- 服务器 总结(命令执行器 serverCron函数 初始化)
14.1 命令请求的执行过程 一个命令请求从发送到获得回复的过程中,客户端和服务器都需要完成一系列操作。 14.1.1 发送命令请求 当用户在客户端中输入一个命令请求的时候,客户端会把这个命令请求转换为协议格式,然后通过连接到服务器的套接字…...
多输入多输出 | Matlab实现TCN-GRU时间卷积神经网络结合门控循环单元多输入多输出预测
多输入多输出 | Matlab实现TCN-GRU时间卷积神经网络结合门控循环单元多输入多输出预测 目录 多输入多输出 | Matlab实现TCN-GRU时间卷积神经网络结合门控循环单元多输入多输出预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 多输入多输出 | Matlab实现TCN-GRU时间卷积…...
windows安全中心,永久卸载工具分享
使用方法 2024Goby红队版工具分享,附2024年漏洞POC下载 下载链接: https://pan.quark.cn/s/4fc2712a2afc一路回车,选项Y即可 耐心等待几秒种,自动重启 此时打开windows安全中心,已经完全不能使用了,响应…...
《安富莱嵌入式周报》第346期:开源2GHz带宽,12bit分辨率,3.2Gsps采样率示波,开源固件安全分析器, 开源口袋电源,开源健康测量,FreeCAD
周报汇总地址:嵌入式周报 - uCOS & uCGUI & emWin & embOS & TouchGFX & ThreadX - 硬汉嵌入式论坛 - Powered by Discuz! 视频: https://www.bilibili.com/video/BV1TYBhYKECK/ 《安富莱嵌入式周报》第346期:开源2GHz带…...
Apache OFBiz xmlrpc XXE漏洞(CVE-2018-8033)
目录 1、漏洞描述 2、EXP下载地址 3、EXP利用 1、漏洞描述 Apache OFBiz是一套企业资源计划(ERP)系统。它提供了广泛的功能,包括销售、采购、库存、财务、CRM等。 Apache OFBiz还具有灵活的架构和可扩展性,允许用户根据业务需求…...
【论文复现】融入模糊规则的宽度神经网络结构
📝个人主页🌹:Eternity._ 🌹🌹期待您的关注 🌹🌹 ❀ 融入模糊规则的宽度神经网络结构 论文概述创新点及贡献 算法流程讲解核心代码复现main.py文件FBLS.py文件 使用方法测试结果示例:…...
sql server 获取当前日期的时间戳
SQL Server 获取当前日期的时间戳 在 SQL Server 中,可以使用 GETDATE() 函数获取当前日期和时间。如果想要获取当前日期的时间戳,可以将日期转换为 UNIX 时间戳格式。本文将介绍如何在 SQL Server 中获取当前日期的时间戳,并提供示例代码。 …...
LLM PPT Translator
LLM PPT Translator 引言Github 地址UI PreviewTranslated Result Samples 引言 周末开发了1个PowerPoint文档翻译工具,上传PowerPoint文档,指定想翻译的目标语言,通过LLM的能力将文档翻译成目标语言的文档。 Github 地址 https://github.…...
铲屎官进,2024年宠物空气净化器十大排行,看看哪款吸毛最佳?
不知道最近换毛季,铲屎官们还承受的住吗?我家猫咪每天都在表演“天女散花”,家里没有一块干净的地方,空气中也都是堆积的浮毛,幸好有宠物空气净化器这种清理好物。宠物空气净化器针对宠物浮毛设计,可以有效…...
python 中常用的定积分求解方法
【例1】 解:本例题使用 Scipy 科学计算库的 quad 函数,它的一般形式是 scipy.integrate.quad(f,a,b),其中 f 是积分的函数名称,a和b分别是下线和上线。 【代码如下】: import numpy as np from scipy.integrate impo…...
音视频相关的一些基本概念
音视频相关的一些基本概念 文章目录 音视频相关的一些基本概念RTTH264profile & levelI帧 vs IDRMP4 封装格式AAC封装格式TS封装格式Reference RTT TCP中的RTT指的是“往返时延”(Round-Trip Time),即从发送方发送数据开始,到…...
pikachu文件上传漏洞通关详解
声明:文章只是起演示作用,所有涉及的网站和内容,仅供大家学习交流,如有任何违法行为,均和本人无关,切勿触碰法律底线 目录 概念:什么是文件上传漏洞一、客户端check二、MIME type三、getimagesi…...
【拥抱AI】向量数据库有哪些常见的检索算法?
在信息检索领域,有许多常见的算法用于帮助用户从大量数据中找到相关的信息。以下是一些常见的检索算法: 布尔模型示例(文本操作) 在文本操作中,布尔模型可以通过编写一个简单的脚本来实现。例如,你可以创…...
模板网站修改教程视频/黑龙江头条今日新闻
volatile这个关键字,不仅仅在Java语言中有,在很多语言中都有的,而且其用法和语义也都是不尽相同的。尤其在C语言、C以及Java中,都有volatile关键字。都可以用来声明变量或者对象。 volatile 译为不稳定的,在Java中我们可以理解成…...
网站建设优化石家庄/如何推广外贸型网站
docker 使用一段时间之后,可能堆积很多用不着的,或者编译错误的镜像,一个一个删除就很麻烦,需要一个批量删除的方法,如下: docker rmi $(docker images | grep "provider" | awk {print $3})上面这条命令,可以删除所有名字中带 “provider” 关键字的镜像, grep 后面…...
wordpress万篇文章/电脑培训学校能学什么
Zabbix 基于SNMP监控1、介绍SNMP:简单网络管理协议;(非常古老的协议)三种通信方式:读(get, getnext)、写(set)、trap(陷阱);端口&…...
上海的网站建设公司/360推广平台登录入口
本篇文章主要与大家简要分享一下,我在AD学习过程中的一些学习笔记,本篇文章主要关于PCB布局设计部分。 本系列文章链接: ----------------------------------------------------------------------------- Altium Designer 2020 学习笔记&a…...
网站建设网页设计培训班/搜索引擎优化关键词的处理
欢迎关注”生信修炼手册”!mutagene是一个肿瘤突变频谱数据库,从ICGA, TCGA等肿瘤项目中收集整理蛋白编码基因上的体细胞突变数据,分析识别对应的突变频谱,对应的文章发表在Nucleic Acids Research,链接如下https://academic.oup.com/nar/art…...
网站内页做排名/今日国内最新新闻
目录Binlog日志介绍二进制log,别于数据库引擎的redo log。binlog记录记录DML DDL 。Binlog的记录模式statement 有点像redis的 rdb持久化。Binlog的文件结构这个log的格式了解即可,查看log时再来查询。Binlog的写入机制Binlog 文件操作如何做到删库而不跑…...