基于Opencv实现颜色识别

 更新时间:2019年07月23日 10:33:56   作者:qq_37269094  
这篇文章主要为大家详细介绍了基于Opencv实现颜色识别,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

彩色模型  

数字图像处理中常用的采用模型是RGB(红,绿,蓝)模型和HSV(色调,饱和度,亮度),RGB广泛应用于彩色监视器和彩色视频摄像机,我们平时的图片一般都是RGB模型。而HSV模型更符合人描述和解释颜色的方式,HSV的彩色描述对人来说是自然且非常直观的。

HSV模型

HSV模型中颜色的参数分别是:色调(H:hue),饱和度(S:saturation),亮度(V:value)。由A. R. Smith在1978年创建的一种颜色空间, 也称六角锥体模型(Hexcone Model)。

(1)色调(H:hue):用角度度量,取值范围为0°~360°,从红色开始按逆时针方向计算,红色为0°,绿色为120°,蓝色为240°。它们的补色是:黄色为60°,青色为180°,品红为300°;

(2)饱和度(S:saturation):取值范围为0.0~1.0,值越大,颜色越饱和。

(3)亮度(V:value):取值范围为0(黑色)~255(白色)

RGB转成HSV

设 (r, g, b) 分别是一个颜色的红、绿和蓝坐标,它们的值是在 0 到 1 之间的实数。设 max 等价于 r, g 和 b 中的最大者。设 min 等于这些值中的最小者。要找到在 HSV 空间中的 (h, s, v) 值,这里的 h ∈ [0, 360)是角度的色相角,而 s, v ∈ [0,1] 是饱和度和亮度,方法如下:

max=max(R,G,B)

min=min(R,G,B)

if R = max, H = (G-B)/(max-min)

if G = max, H = 2 + (B-R)/(max-min)

if B = max, H = 4 + (R-G)/(max-min) 

H = H * 60

if H < 0, H = H + 360

  • V=max(R,G,B)
  • S=(max-min)/max

OpenCV下有个函数可以直接将RGB模型转换为HSV模型,OpenCV中H∈ [0, 180), S ∈ [0, 255], V ∈ [0, 255]。我们知道H分量基本能表示一个物体的颜色,但是S和V的取值也要在一定范围内,因为S代表的是H所表示的那个颜色和白色的混合程度,也就说S越小,颜色越发白,也就是越浅;V代表的是H所表示的那个颜色和黑色的混合程度,也就说V越小,颜色越发黑。经过实验,识别蓝色的取值是 H在100到140,S和V都在90到255之间。一些基本的颜色H的取值可以如下设置:

Orange 0-22,Yellow 22- 38,Green 38-75,Blue 75-130,Violet 130-160,Red 160-179

具体实现

(1) 读取一张图片

cvtColor(imgOriginal, imgHSV, COLOR_BGR2HSV);

(2)将彩色图像均衡化 

split(imgHSV, hsvSplit);
equalizeHist(hsvSplit[2],hsvSplit[2]);
merge(hsvSplit,imgHSV);

(3)检测颜色

inRange(imgHSV, Scalar(iLowH, iLowS, iLowV), Scalar(iHighH, iHighS, iHighV), imgThresholded);

(4)进行开操作和闭操作,去除噪声的影响。

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

代码:

#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<iostream>
 
using namespace cv;
using namespace std;
 
//入口主函数
int main(int argc, char** argv)
{
 //打开摄像头,从摄像头获取图像
 VideoCapture cap(0);
 if (!cap.isOpened())
 {
 cout << "Cannot open the web cam"<<endl;
 return -1;
 }
 //创建窗口
 namedWindow("Control",CV_WINDOW_AUTOSIZE);
 
 int iLowH = 100;
 int iHighH = 140;
 
 int iLowS = 90;
 int iHighS = 255;
 
 int iLowV = 90;
 int iHighV = 255;
 //创建进度条
 cvCreateTrackbar("LowH","Control",&iLowH,179);
 cvCreateTrackbar("HighH", "Control", &iHighH,179);
 
 cvCreateTrackbar("LowS", "Control", &iLowS,255);
 cvCreateTrackbar("Highs", "Control", &iHighS,255);
 
 cvCreateTrackbar("LowV", "Control", &iLowV,255);
 cvCreateTrackbar("HighV", "Control", &iHighV,255);
 //while循环加载图片
 while (true)
 {
 Mat imgOriginal;
 bool bSuccess = cap.read(imgOriginal);
  
 if (!bSuccess)
 {
 cout << "Cannot read a frame from video stream" << endl;
 break;
 }
 //
 Mat imgHSV;
 vector<Mat> hsvSplit;
 cvtColor(imgOriginal,imgHSV,COLOR_BGR2HSV);
 
 //转化成直方图均衡化
 split(imgHSV,hsvSplit);
 equalizeHist(hsvSplit[2],hsvSplit[2]);
 merge(hsvSplit,imgHSV);
 Mat imgThresholded;
 //确定颜色显示的范围
 inRange(imgHSV, Scalar(iLowH, iLowS, iLowV), Scalar(iHighH, iHighS,iHighV),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);
 imshow("Original",imgOriginal);
 //等待时间
 char Key = (char)waitKey(300);
 if (Key==27)
 {
 break;
 }
 }
 return 0;
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • C语言 深入讲解条件编译的用处

    C语言 深入讲解条件编译的用处

    C语言提供了条件编译的语法,就是在编译源码的时候,可以选择性地编译指定的代码。例如我们开发一个兼容windows系统和linux系统运行的项目,那么,一些与操作系统密切相关的代码,就需要进行选择性编译
    2022-04-04
  • 详解C++ 前置声明

    详解C++ 前置声明

    这篇文章主要介绍了C++ 前置声明的相关资料,帮助大家更好的理解和使用c++,感兴趣的朋友可以了解下
    2020-09-09
  • C++详细分析线程间的同步通信

    C++详细分析线程间的同步通信

    线程间不通信的话,每个线程受CPU的调度,没有任何执行上的顺序可言,线程1和线程2是根据CPU调度算法来的,两个线程都有可能先运行,是不确定的,线程间的运行顺序是不确定的,所以多线程程序出问题,难以复现,本章我们就来了解线程间的同步通信
    2022-05-05
  • C/C++仿华容道小游戏

    C/C++仿华容道小游戏

    这篇文章主要介绍了C/C++仿华容道小游戏的相关资料,模仿实现华容道游戏,感兴趣的朋友可以参考一下
    2016-02-02
  • C语言员工业绩销售源代码

    C语言员工业绩销售源代码

    这篇文章主要为大家详细介绍了C语言员工业绩销售源代码,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-11-11
  • C语言数组全面总结梳理

    C语言数组全面总结梳理

    在C语言和C++等语言中,数组元素全为指针变量的数组称为指针数组,指针数组中的元素都必须具有相同的存储类型、指向相同数据类型的指针变量。指针数组比较适合用来指向若干个字符串,使字符串处理更加方便、灵活
    2022-02-02
  • C++ Vector迭代器失效问题的解决方法

    C++ Vector迭代器失效问题的解决方法

    最近我学习了C++中的迭代器失效问题,迭代器失效问题是非常非常重要的,所以特意整理出来一篇文章供我们一起复习和学习
    2022-08-08
  • 浅谈do {...} while (0) 在宏定义中的作用

    浅谈do {...} while (0) 在宏定义中的作用

    下面小编就为大家带来一篇浅谈do {...} while (0) 在宏定义中的作用。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-12-12
  • C++中图片类型的识别与转换详解方法

    C++中图片类型的识别与转换详解方法

    本文简单的介绍一下C++语言中如何识别图片文件的类型,以及各图片类型之间的转换方法,并提供相关的源码供大家参考,感兴趣的朋友快来看看吧
    2021-11-11
  • 哈夫曼的c语言实现代码

    哈夫曼的c语言实现代码

    着先通过 HuffmanTree() 函数构造哈夫曼树,然后在主函数 main()中自底向上开始(也就是从数组序号为零的结点开始)向上层层判断,若在父结点左侧,则置码为 0,若在右侧,则置码为 1。最后输出生成的编码
    2013-07-07

最新评论