opencv 颜色识别

彩色模型

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

HSV模型

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

  • 色调(H:hue):用角度度量,取值范围为0°~360°,从红色开始按逆时针方向计算,红色为0°,绿色为120°,蓝色为240°。它们的补色是:黄色为60°,青色为180°,品红为300°;
  • 饱和度(S:saturation):取值范围为0.0~1.0,值越大,颜色越饱和。
  • 亮度(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] 是饱和度和亮度,计算为:

 
  1. max=max(R,G,B)

  2. min=min(R,G,B)

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

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

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

  6.  
  7. H = H * 60

  8. if H < 0, H = H + 360

  9.  
  10. V=max(R,G,B)

  11. 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的取值可以如下设置:

 
  1. Orange 0-22

  2. Yellow 22- 38

  3. Green 38-75

  4. Blue 75-130

  5. Violet 130-160

  6. Red 160-179


OpenCV实现

首先我们读取一张图片或从视频读取一帧图像,用下面的函数转为HSV模型。

 

cvtColor(imgOriginal, imgHSV, COLOR_BGR2HSV);


然后我们对彩色图像做直方图均衡化

 
  1. //因为我们读取的是彩色图,直方图均衡化需要在HSV空间做

  2. split(imgHSV, hsvSplit);

  3. equalizeHist(hsvSplit[2],hsvSplit[2]);

  4. merge(hsvSplit,imgHSV);


接着就是进行颜色检测,我们用void inRange(InputArray src, InputArray lowerb, InputArray upperb, OutputArray dst);函数进行颜色检测,这个函数的作用就是检测src图像的每一个像素是不是在lowerb和upperb之间,如果是,这个像素就设置为255,并保存在dst图像中,否则为0。

 

inRange(imgHSV, Scalar(iLowH, iLowS, iLowV), Scalar(iHighH, iHighS, iHighV), imgThresholded); //Threshold the image


通过上面的函数我们就可以得到目标颜色的二值图像,接着我们先对二值图像进行开操作,删除一些零零星星的噪点,再使用闭操作,连接一些连通域,也就是删除一些目标区域的白色的洞。

 
  1. //开操作 (去除一些噪点)

  2. Mat element = getStructuringElement(MORPH_RECT, Size(5, 5));

  3. morphologyEx(imgThresholded, imgThresholded, MORPH_OPEN, element);

  4.  
  5. //闭操作 (连接一些连通域)

  6. morphologyEx(imgThresholded, imgThresholded, MORPH_CLOSE, element);


整个代码实现

 
  1. #include <iostream>

  2. #include "opencv2/highgui/highgui_c.h"

  3. #include "opencv2/imgproc/imgproc_c.h"

  4. #include<opencv2/opencv.hpp>

  5. using namespace cv;

  6. using namespace std;

  7.  
  8. int main(int argc, char** argv)

  9. {

  10. VideoCapture cap(0); //capture the video from web cam

  11.  
  12. if (!cap.isOpened()) // if not success, exit program

  13. {

  14. cout << "Cannot open the web cam" << endl;

  15. return -1;

  16. }

  17.  
  18. namedWindow("Control", CV_WINDOW_AUTOSIZE); //create a window called "Control"

  19.  
  20. int iLowH = 100;

  21. int iHighH = 140;

  22.  
  23. int iLowS = 90;

  24. int iHighS = 255;

  25.  
  26. int iLowV = 90;

  27. int iHighV = 255;

  28.  
  29. //Create trackbars in "Control" window

  30. cvCreateTrackbar("LowH", "Control", &iLowH, 179); //Hue (0 - 179)

  31. cvCreateTrackbar("HighH", "Control", &iHighH, 179);

  32.  
  33. cvCreateTrackbar("LowS", "Control", &iLowS, 255); //Saturation (0 - 255)

  34. cvCreateTrackbar("HighS", "Control", &iHighS, 255);

  35.  
  36. cvCreateTrackbar("LowV", "Control", &iLowV, 255); //Value (0 - 255)

  37. cvCreateTrackbar("HighV", "Control", &iHighV, 255);

  38.  
  39. while (true)

  40. {

  41. Mat imgOriginal;

  42.  
  43. bool bSuccess = cap.read(imgOriginal); // read a new frame from video

  44.  
  45. if (!bSuccess) //if not success, break loop

  46. {

  47. cout << "Cannot read a frame from video stream" << endl;

  48. break;

  49. }

  50.  
  51. Mat imgHSV;

  52. vector<Mat> hsvSplit;

  53. cvtColor(imgOriginal, imgHSV, COLOR_BGR2HSV); //Convert the captured frame from BGR to HSV

  54.  
  55. //因为我们读取的是彩色图,直方图均衡化需要在HSV空间做

  56. split(imgHSV, hsvSplit);

  57. equalizeHist(hsvSplit[2], hsvSplit[2]);

  58. merge(hsvSplit, imgHSV);

  59. Mat imgThresholded;

  60.  
  61. inRange(imgHSV, Scalar(iLowH, iLowS, iLowV), Scalar(iHighH, iHighS, iHighV), imgThresholded); //Threshold the image

  62.  
  63. //开操作 (去除一些噪点)

  64. Mat element = getStructuringElement(MORPH_RECT, Size(5, 5));

  65. morphologyEx(imgThresholded, imgThresholded, MORPH_OPEN, element);

  66.  
  67. //闭操作 (连接一些连通域)

  68. morphologyEx(imgThresholded, imgThresholded, MORPH_CLOSE, element);

  69.  
  70. imshow("Thresholded Image", imgThresholded); //show the thresholded image

  71. imshow("Original", imgOriginal); //show the original image

  72.  
  73. char key = (char)waitKey(300);

  74. if (key == 27)

  75. break;

  76. }

  77.  
  78. return 0;

  79.  
  80. }


   //开操作 (去除一些噪点)
   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("Original", imgOriginal); //show the original image
 
   char key = (char) waitKey(300);
   if(key == 27)
         break;
    }
 
   return 0;
 
}

实验结果图: 

这里写图片描述

颜色识别的应用

经典的颜色识别的经典应用就是车牌定位了,因为中国的车牌无非就是蓝色和黄色,还有就是交通标志定位也是个应用。比如下面两张图片,有很明显的颜色区分。 
这里写图片描述 
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值