基于opencv实现视频中的颜色识别功能

 更新时间:2022年07月22日 16:11:50   作者:chenguanging080  
这篇文章主要介绍了基于opencv实现视频中的颜色识别功能,文章详细介绍了颜色识别的原理及opencv中的颜色模型,基于c++代码实现颜色识别功能,需要的朋友可以参考下

颜色识别的原理

opencv中的颜色模型

RGB

RGB具有三个通道其,分别表示红色通道®,绿色通道(G),蓝色通道(B),3个通道在opencv中的取值均为0~255,它的颜色由3个通道的取值来共同决定,因此如果使用RGB图像来进行颜色的识别,会丢失很多的颜色。

HSV

HSV具有三个通道,其分别表示色调(H),饱和度(S),亮度(V),3个通道在opencv中的取值分别如下:

  • H:0~180
  • S:0~255
  • V:0~255

其中H通道和S通道决定了颜色,V通道决定亮度
各种颜色对应的三个通道的取值表如下:

在这里插入图片描述

因此通过限制HSV通道中相对应的数值,就可以识别出对应的颜色

颜色识别的实现(c++)

1.读取摄像头的实时画面

VideoCapture capture(1);//0为电脑本身摄像头,1位外置摄像头

2.读取摄像头的当前一帧的数据并转换到HSV空间

capture >> frame; //读取当前帧
cvtColor(frame, imgHSV, COLOR_BGR2HSV);

3.对HSV图像进行直方图均衡化
在此处使用直方图均衡化是因为可以使用这种方法可以使原来比较少像素的灰度会被分配到别的灰度去,像素相对集中, 处理后灰度范围变大,对比度变大,清晰度变大,所以能有效增强图像。

split(imgHSV,temporary);
equalizeHist(temporary[2], temporary[2]);
merge(temporary, imgHSV);   //将HSV图像分割通道,并且做直方图的均衡化

使用equalizeHist()函数,其输入必须是单通道的,因此使用split函数将得到的HSV图像分割为三个通道之后,在进行直方图均衡化,然后再使用merge函数来合并三个通道。
此处仅对V通道进行了直方图均衡化,因为通过比对发现只对V通道进行效果最好,具体的原因还不清楚。

4.将直方图均衡化之后,使用inRange()函数来进行图像的识别

inRange(imgHSV, Scalar(H_W_L, S_W_L, V_W_L), Scalar(H_W_H, S_W_H, V_W_H), image);

其中H_W_L,H_W_L, S_W_L, V_W_L. . . 等数值分别为前面表格对应的颜色值的最小值和最大值。
此函数是将在范围内的像素值为255,其与为0,反映到图像上就是,选中的颜色为白色,其与的均为黑色。
操作到此颜色可以进行识别,但是效果可能不会很好,因此可以再使用开操作来消除噪点,去掉小的干扰快,再使用闭操作来填充闭合区域。

5.开操作

kernel = getStructuringElement(MORPH_RECT, Size(3, 3));//3*3的矩形卷积核,只要是奇数的都可以
morphologyEx(image,image,2,kernel);

6.闭操作

morphologyEx(image,image,3,kernel);

源代码

#include <opencv2\opencv.hpp>  
using namespace cv;
using namespace std;
int main()
{
	Mat frame,imgHSV,image,kernel;
	vector<Mat>temporary;
	int H_W_L = 0, H_W_H = 180;
	int S_W_L = 0, S_W_H = 30;
	int V_W_L = 221, V_W_H = 255;
	VideoCapture capture(1);//读取视摄像头实时画面数据,0默认是笔记本的摄像头;如果是外接摄像头,这里改为1
	while (true)
	{
		capture >> frame; //读取当前帧
		
		if (!frame.empty())
		{          //判断输入的视频帧是否为空的
			cvtColor(frame, imgHSV, COLOR_BGR2HSV);
			//threshold(gray, two_value, 125, 255, THRESH_BINARY);//二值图像
			
			split(imgHSV,temporary);
			equalizeHist(temporary[2], temporary[2]);
			/*equalizeHist(temporary[1], temporary[1]);
			equalizeHist(temporary[0], temporary[0]);*/
			merge(temporary, imgHSV);   //将HSV图像分割通道,并且做直方图的均衡化
			inRange(imgHSV, Scalar(H_W_L, S_W_L, V_W_L), Scalar(H_W_H, S_W_H, V_W_H), image);
			kernel = getStructuringElement(MORPH_RECT, Size(3, 3));
			morphologyEx(image,image,2,kernel);
			morphologyEx(image,image,3,kernel);
			imshow("直方图", imgHSV);
			imshow("原图",frame);
			imshow("window", image);  //在window窗口显示frame摄像头数据画面
		}
		if (waitKey(20) == 'q')   //延时20ms,获取用户是否按键的情况,如果按下q,会推出程序 
			break;
	}
	capture.release();     //释放摄像头资源
	destroyAllWindows();   //释放全部窗口
	return 0;
}

##结果

在这里插入图片描述

到此这篇关于基于opencv实现视频中的颜色识别的文章就介绍到这了,更多相关OpenCV颜色识别内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C语言深度解剖篇之关键字以及补充内容

    C语言深度解剖篇之关键字以及补充内容

    C语言的关键字共有32个,根据关键字的作用,可分其为数据类型关键字、控制语句关键字、存储类型关键字和其它关键字四类,这篇文章主要给大家介绍了关于C语言深度解剖篇之关键字以及补充内容的相关资料,需要的朋友可以参考下
    2022-06-06
  • C语言打印输出杨辉三角

    C语言打印输出杨辉三角

    这篇文章主要为大家详细介绍了C语言打印输出杨辉三角,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-12-12
  • C++私有继承(二)

    C++私有继承(二)

    这篇文章主要介绍了C++私有继承,在私有继承时,基类的公有对象以及保护对象会变成派生类的私有对象。我们可以在派生类方法当中使用它,但无法通过派生类对象直接调用,但无法访问基类的私有方法和对象,下面具体内容,需要的朋友可以参考一下
    2022-01-01
  • C语言实现红黑树的实例代码

    C语言实现红黑树的实例代码

    这篇文章主要介绍了C语言实现红黑树的实例代码,有需要的朋友可以参考一下
    2013-12-12
  • C语言二分查找算法及实现代码

    C语言二分查找算法及实现代码

    本文主要介绍C语言的二分查找算法,这里给大家详细介绍了什么是二分查找,并提供代码实例,需要的小伙伴可以参考下
    2016-07-07
  • C++动态调用动态链接库(DLL或SO)的方法实现

    C++动态调用动态链接库(DLL或SO)的方法实现

    动态链接库是一种Windows操作系统下常见的可执行文件格式,它包含了一些可被其他应用程序调用的函数和数据,本文主要介绍了C++动态调用动态链接库(DLL或SO),感兴趣的可以了解一下
    2024-01-01
  • C++设计模式之享元模式

    C++设计模式之享元模式

    这篇文章主要介绍了C++设计模式之享元模式,本文讲解了什么是享元模式、享元模式代码实例、享元模式的优点等内容,需要的朋友可以参考下
    2014-10-10
  • 重构-C++实现矩阵的简单实例

    重构-C++实现矩阵的简单实例

    下面小编就为大家带来一篇重构-C++实现矩阵的简单实例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-06-06
  • 基于C++中覆盖,重载,隐藏的一点重要说明

    基于C++中覆盖,重载,隐藏的一点重要说明

    下面小编就为大家带来一篇基于C++中覆盖,重载,隐藏的一点重要说明。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-12-12
  • C语言中带头双向循环链表基本操作的实现详解

    C语言中带头双向循环链表基本操作的实现详解

    无头单向非循环链表结构简单,一般不会单独用来存数据。而带头双向循环链表的结构较为复杂,一般用在单独存储数据。本文将介绍带头双向循环链表的基本操作,需要的可以参考一下
    2022-11-11

最新评论