opencv3颜色识别(C++)

2023-05-16

文章目录

  • opencv3颜色识别(C++)
    • 目标
    • 思路
      • 1. 读取图像
      • 2. 对比度调整(直方图均衡)
      • 3.RGB颜色分类
      • 4.形态学去噪声
    • 代码
    • 结果
    • 参考

opencv3颜色识别(C++)

目标

给定一幅图像,可以是读取指定文件或者从摄像机获取,识别图像中的颜色。这里我们只识别8种颜色,包括黑、红、绿、黄、蓝、紫、靛、白。这8种颜色是RGB颜色空间中位于8个顶点的颜色。

思路

1. 读取图像

读取摄像机的一帧

VideoCapture cap(0); //capture the video from web cam
	if (!cap.isOpened())  // if not success, exit program
	{
		cout << "Cannot open the web cam" << endl;
		return -1;
	}
Mat imgOriginal;
		bool bSuccess = cap.read(imgOriginal); // read a new frame from video
		if (!bSuccess) //if not success, break loop
		{
			cout << "Cannot read a frame from video stream" << endl;
			break;
		}

读取指定路径的图片

Mat imgOriginal = imread("1.jpg");

2. 对比度调整(直方图均衡)

  • 这一步是可选步骤,根据情况选择是否使用。
  • 类似于灰度图像使用直方图均衡调整对比度。根据冈萨雷斯的书,对于彩色图像,一般不建议在RGB空间中分别对三种通道进行直方图均衡,因为这样可能会引入一些特殊的颜色。一般的做法是将RGB空间转换到HSI空间或者HSV空间。然后对强度分量或者明度分量进行直方图均衡。关于这三种颜色空间的区别和联系可以参考博客RGB、HSV、HSI颜色空间。
  • 直方图均衡完成以后再转回值RGB颜色空间。
vector<Mat> hsvSplit;   						//创建向量容器,存放HSV的三通道数据
cvtColor(imgOriginal, imgHSV, COLOR_BGR2HSV); 	//Convert the captured frame from BGR to HSV
split(imgHSV, hsvSplit);						//分类原图像的HSV三通道
equalizeHist(hsvSplit[2], hsvSplit[2]);   	 	//对HSV的亮度通道进行直方图均衡
merge(hsvSplit, imgHSV);				   		//合并三种通道
cvtColor(imgHSV, imgBGR, COLOR_HSV2BGR);    	//将HSV空间转回至RGB空间,为接下来的颜色识别做准备

3.RGB颜色分类

  • 将RGB颜色立方体分解为等大的8个小正方体,判断输入的RGB颜色值属于哪一个小块,则该RGB的颜色就是该小块的颜色。8个小正方体的颜色分别对应上述的8种颜色。
  • 注意opencv中图像的彩色通道顺序为BGR,而不是RGB。
  • 8种颜色BGR值分别为
颜色BGR
黑色0 0 0
红色0 0 255
绿色0 255 0
黄色0 255 255
蓝色255 0 0
紫色255 0 255
靛色255 255 0
白色255 255 255
  • 若输入的BRG为(x,y,z),则分别对三个变量与127作比较,确定其属于哪一个小块。
Mat imgThresholded;
int ctrl = 0;       //该变量用于控制识别何种颜色
switch(ctrl)
		{
		case 0:
			{
				inRange(imgBGR, Scalar(128, 0, 0), Scalar(255, 127, 127), imgThresholded); //蓝色  
				//这个函数将BGR图像中满足在(128, 0, 0)与(255, 127, 127)范围内的像素点选出来,并将该范围内的像素值赋值为白色,
				//其他区域赋值为黑色,并将这个二值图像存入 imgThresholded。
				break;
			}
		case 1:
			{
				inRange(imgBGR, Scalar(128, 128, 128), Scalar(255, 255, 255), imgThresholded); //白色
				break;
			}
		case 2:
			{
				inRange(imgBGR, Scalar(128, 128, 0), Scalar(255, 255, 127), imgThresholded); //靛色
				break;
			}
		case 3:
			{
				inRange(imgBGR, Scalar(128, 0, 128), Scalar(255, 127, 255), imgThresholded); //紫色
				break;
			}
		case 4:
			{
				inRange(imgBGR, Scalar(0, 128, 128), Scalar(127, 255, 255), imgThresholded); //黄色
				break;
			}
		case 5:
			{
				inRange(imgBGR, Scalar(0, 128, 0), Scalar(127, 255, 127), imgThresholded); //绿色
				break;
			}
		case 6:
			{
				inRange(imgBGR, Scalar(0, 0, 128), Scalar(127, 127, 255), imgThresholded); //红色
				break;
			}
		case 7:
			{
				inRange(imgBGR, Scalar(0, 0, 0), Scalar(127, 127, 127), imgThresholded); //黑色
				break;
			}
		}

4.形态学去噪声

  • 使用开操作和闭操作去除二值化图像中的噪声。原理可以参考冈萨雷斯的书。
Mat element = getStructuringElement(MORPH_RECT, Size(5, 5));             //设置结构元
morphologyEx(imgThresholded, imgThresholded, MORPH_OPEN, element);		 //开操作
morphologyEx(imgThresholded, imgThresholded, MORPH_CLOSE, element);      //闭操作

代码

#include <iostream>
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"

using namespace cv;
using namespace std;

int main(int argc, char** argv)
{
	VideoCapture cap(0); //capture the video from web cam
	
	if (!cap.isOpened())  // if not success, exit program
	{
		cout << "Cannot open the web cam" << endl;
		return -1;
	}

	namedWindow("control", 1);
	int ctrl = 0;
	createTrackbar("ctrl", "control", &ctrl, 7);

	while (true)
	{
		Mat imgOriginal;

		bool bSuccess = cap.read(imgOriginal); // read a new frame from video
		if (!bSuccess) //if not success, break loop
		{
			cout << "Cannot read a frame from video stream" << endl;
			break;
		}

		// imgOriginal = imread("4.jpg");

		Mat imgHSV, imgBGR;
		Mat imgThresholded;

		if(0)
		{
			vector<Mat> hsvSplit;   //创建向量容器,存放HSV的三通道数据
			cvtColor(imgOriginal, imgHSV, COLOR_BGR2HSV); //Convert the captured frame from BGR to HSV
			split(imgHSV, hsvSplit);			//分类原图像的HSV三通道
			equalizeHist(hsvSplit[2], hsvSplit[2]);    //对HSV的亮度通道进行直方图均衡
			merge(hsvSplit, imgHSV);				   //合并三种通道
			cvtColor(imgHSV, imgBGR, COLOR_HSV2BGR);    //将HSV空间转回至RGB空间,为接下来的颜色识别做准备
		}
		else
		{
			imgBGR = imgOriginal.clone();
		}



		switch(ctrl)
		{
		case 0:
			{
				inRange(imgBGR, Scalar(128, 0, 0), Scalar(255, 127, 127), imgThresholded); //蓝色
				break;
			}
		case 1:
			{
				inRange(imgBGR, Scalar(128, 128, 128), Scalar(255, 255, 255), imgThresholded); //白色
				break;
			}
		case 2:
			{
				inRange(imgBGR, Scalar(128, 128, 0), Scalar(255, 255, 127), imgThresholded); //靛色
				break;
			}
		case 3:
			{
				inRange(imgBGR, Scalar(128, 0, 128), Scalar(255, 127, 255), imgThresholded); //紫色
				break;
			}
		case 4:
			{
				inRange(imgBGR, Scalar(0, 128, 128), Scalar(127, 255, 255), imgThresholded); //黄色
				break;
			}
		case 5:
			{
				inRange(imgBGR, Scalar(0, 128, 0), Scalar(127, 255, 127), imgThresholded); //绿色
				break;
			}
		case 6:
			{
				inRange(imgBGR, Scalar(0, 0, 128), Scalar(127, 127, 255), imgThresholded); //红色
				break;
			}
		case 7:
			{
				inRange(imgBGR, Scalar(0, 0, 0), Scalar(127, 127, 127), imgThresholded); //黑色
				break;
			}
		}
																		
		imshow("形态学去噪声前", imgThresholded);

		Mat element = getStructuringElement(MORPH_RECT, Size(5, 5));
		morphologyEx(imgThresholded, imgThresholded, MORPH_OPEN, element);
		morphologyEx(imgThresholded, imgThresholded, MORPH_CLOSE, element);

		imshow("Thresholded Image", imgThresholded); //show the thresholded image
		imshow("直方图均衡以后", imgBGR);
		imshow("Original", imgOriginal); //show the original image

		char key = (char)waitKey(300);
		if (key == 27)
			break;
	}

	return 0;

}

结果

  • 通过滑动条控制识别和种颜色
    在这里插入图片描述
  • 对该图像进行颜色识别
    在这里插入图片描述
  • 识别蓝色
    在这里插入图片描述
  • 识别红色
    在这里插入图片描述

参考

https://blog.csdn.net/zhenguo26/article/details/82803241

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

opencv3颜色识别(C++) 的相关文章

随机推荐

  • 安卓TV开发遇到的那些坑

    最近公司需要开发一个TV的luancher xff0c 就是那种纯物理按键的遥控 xff0c 没有触摸屏 xff0c 现在说说我踩得那些坑 xff08 其实布局和代码逻辑和正常的安卓应用差不多 xff09 1 焦点 焦点 焦点 xff0c
  • 安卓TV列表刷新时焦点自动变成第一个

    最近在开发安卓TV项目 xff0c 列表调用notifyDataSetChanged xff08 xff09 方法刷新数据时 xff0c 焦点自动就变成第一个子item去了 xff0c 查了半天发现用notifyItemRangeChang
  • 安卓蓝牙BLE设备通讯发送和接受超过20个字节的问题

    最近做的项目是手机端和BLE设备通讯 xff0c 而BLE设备又做了限制一次包只能传递20个字节的数据 xff0c 多了就得分包发送 xff0c 在这里记录一下如何解决这个问题 xff08 PS xff1a 之前链接什么的回调什么的 就不过
  • 获取最近运行应用方法和杀进程的方法

    最近公司的项目有个需求就是获取最近手机正在运行的进程 xff0c 以及杀掉进程 就是类似于安卓手机中的长按home键的效果 先说说获取最近手机正在运行的进程方法 xff1a 直接上代码 xff0c 代码中有注释 xff1a appbeans
  • 把自己的应用程序push至system/app下,把自己的app改成系统级别的app

    想把一个应用程序放入到系统文件夹下的话 xff0c 手机必须的root的情况下才能push进去 下面我就说说步骤吧 xff1a 1 先把手机用USB和电脑连接 2 如果电脑配置了adb的环境的话直接cmd xff0c 未配置环境的话找到sd
  • ConcurrentModificationException异常出现原因以及解决方法

    今天在开发过程中遇到一个异常叫ConcurrentModificationException xff0c 这个异常用我的白话翻译是叫同时修改异常 这个异常是怎么出现的呢 xff0c 先看看已下的代码 xff1a span class hlj
  • retrofit中使用body标签传RequestBody

    现在的Android开发者基本上都用过retrofit这个第三方网络请求库吧 xff01 xff01 xff01 网络请求中有get post delete和put等等请求方式 现在我们需要用到post请求 xff1a span class
  • SpringBoot配置拦截器拦截器使用

    拦截器介绍 Java中的拦截器是动态拦截 action 调用的对象 xff0c 然后提供了可以在 action 执行前后增加一些操作 xff0c 也可以在 action执行前停止操作 xff0c 功能与过滤器类似 xff0c 但是标准和实现
  • 百度地图上根据经纬度集合绘制行车轨迹

    以下是素材 最近项目中用到了根据一段线路的经纬度集合来在地图上播放该车辆的行驶轨迹的需求 下面我就讲一下我实现步骤 效果图如下 因为制作gif图为了控制大小去掉了很多帧 不必在意这些细节 嘿嘿 1 首先在界面上展示百度地图 这不是废话么 如
  • skip-GANomaly复现总结

    文章目录 skip GANomaly复现总结附MvTec数据集介绍实验结果总结谈谈我对于skip GANomaly的看法最后的感想 代码 skip GANomaly复现总结 附MvTec数据集 链接 xff1a https pan baid
  • YOLOv3 从入门到部署:(五)YOLOv3模型的部署(基于C++ opencv)

    文章目录 YOLOv3 从入门到部署 xff1a xff08 五 xff09 YOLOv3模型的部署 xff08 基于C 43 43 opencv xff09 目录关于opencv的DNN介绍代码讲解效果展示 YOLOv3 从入门到部署 x
  • 基于YOLO-fastest-xl的OCR

    文章目录 基于YOLO fastest xl的OCR项目介绍对于yolo fastest xl的结构的更改运行方法效果总结 基于YOLO fastest xl的OCR github链接https github com qqsuhao yol
  • Pytorch多GPU训练时使用hook提取模型中间层输出时与模型输入张量不在同一个GPU上的解决办法

    Pytorch多GPU训练时使用hook提取模型中间层输出时与模型输入张量不在同一个GPU上的解决办法 通常对于单卡训练的模型 xff0c 使用hook可以较为方便地提取出模型中间层输出 例如我们想要获取自定义模型DBL中的conv2d的输
  • 发布自己的Python包

    文章目录 发布自己的Python包第一步 xff1a 注册Pypi账号第二步 xff1a 准备本地文件第三部 xff1a 构建包并上传 发布自己的Python包 参考https packaging python org en latest
  • Python音频信号处理库函数librosa介绍

    文章目录 Python音频信号处理库函数librosa介绍 部分内容将陆续添加 介绍安装综述 xff08 库函数结构 xff09 Core IO and DSP xff08 核心输入输出功能和数字信号处理 xff09 Audio proce
  • python库函数之scipy.signal——滤波器设计

    文章目录 python库函数之scipy signal butter 函数参数设计模拟滤波器设计数字滤波器 2021 06 03 有位博主评论了这篇博客 xff08 评论已被删除 xff09 xff0c 特此说明 python库函数之sci
  • 使用python绘制短时傅里叶变换(STFT)频谱图(时频像)

    文章目录 使用python绘制短时傅里叶变换 xff08 STFT xff09 频谱图 xff08 时频像 xff09 使用python绘制短时傅里叶变换 xff08 STFT xff09 频谱图 xff08 时频像 xff09 使用sci
  • python csv文件数据写入和读取(适用于超大数据量)

    文章目录 python csv文件数据写入和读取 xff08 适用于超大数据量 xff09 python csv文件数据写入和读取 xff08 适用于超大数据量 xff09 一般情况下由于我们使用的数据量比较小 xff0c 因此可以将数据一
  • CentOS 开启端口方法

    查看已经开放的端口 xff1a firewall cmd list ports 查看防火墙状态 xff1a firewall cmd state 开启防火墙 xff1a systemctl start firewalld service 开
  • opencv3颜色识别(C++)

    文章目录 opencv3颜色识别 C 43 43 目标思路1 读取图像2 对比度调整 xff08 直方图均衡 xff09 3 RGB颜色分类4 形态学去噪声 代码结果参考 opencv3颜色识别 C 43 43 目标 给定一幅图像 xff0