OpenCV学习心得——基础篇——三种常见色彩空间——RGB、GRAY、HSV颜色识别
FOR THE SIGMA
FOR THE GTINDER
FOR THE ROBOMASTER
简介:
这一系列的学习心得第一轮将参考《学习OpenCV3》一书
操作系统版本
:Ubuntu16.04(在这里博主在Linux下进行运行的)
http://www.ubuntu.org.cn/download/desktop 桌面版ubuntu16.04 下载
电子版书籍下载地址
暂无资源
内容:
颜色空间是指针对一个给定的颜色,如何组合颜色元素以及对其编码。在OpenCV中,色彩空间赋予了机器能够读取不同颜色信息的能力,根据这个能力识别并标记对应颜色以完成捕获。
常见的三种色彩空间
RGB | HSV | GRAY | |
---|---|---|---|
模型 | 红( R )、绿( G )、蓝( B ) | 色调( H ),饱和度( S ),亮度( V ) | 灰度 |
作用 | 广泛应用于彩色监视器和彩色视频摄像机 | 更符合人描述和解释颜色的方式 | 用于将前两者信息转换为灰度值构成灰度图 |
补充,灰度图就是每个像素点只能有一个值表示颜色,它的像素值在0到255之间,0是黑色,255是白色,中间值是一些不同等级的灰色,可以说灰度是黑与白之间的过渡色,注意这个值不是RGB里的任何一个元素,显示设备是直接通过CRT(彩色阴极射线显像管)将单通道里的像素值显示黑白色图像,值越高黑色图越亮,一般灰度值大小不会超过125!
RGB色彩空间:
RGB色彩模式是工业界的一种颜色标准,是通过对红®、绿(G)、蓝(B)三个颜色通道的变化以及它们相互之间的叠加来得到各式各样的颜色的,RGB即是代表红、绿、蓝三个通道的颜色,这个标准几乎包括了人类视力所能感知的所有颜色,是目前运用最广的颜色系统之一。
任何颜色都有红、绿、蓝三原色组成,假如原来某点的颜色为RGB(R,G,B),那么,我们可以通过下面几种方法,将其转换为灰度:
1)浮点算法:Gray=R
0.3+G
0.59+B
0.11
2)整数方法:Gray=(R
30+G
59+B
11)/100
3)移位方法:Gray =(R
76+G
151+B*28)>>8;
4)平均值法:Gray=(R+G+B)/3;
5)仅取绿色:Gray=G;
通过上述任一种方法求得Gray后,将原来的RGB(R,G,B)中的R,G,B统一用Gray替换,形成新的颜色RGB(Gray,Gray,Gray),用它替换原来的RGB(R,G,B)就是灰度图了。
附上RGB常见颜色表:
颜色样式 | RGB数值 | 颜色代码 |
---|---|---|
黑色 | 0,0,0 | #000000 |
白色 | 255,255,255 | #FFFFFF |
红色 | 255,0,0 | #FF0000 |
黄色 | 255,255,0 | #FFFF00 |
绿色 | 0,255,0 | #00FF00 |
蓝色 | 0,0,255 | #0000FF |
紫色(深红) | 255.0.255 | #FF00FF |
青色 | 0,255,255 | #00FFFF |
橘黄 | 255,128,0 | #FF8000 |
HSV色彩空间:
HSV(Hue, Saturation, Value)是根据颜色的直观特性由A. R. Smith在1978年创建的一种颜色空间, 也称六角锥体模型(Hexcone Model)。这个模型中颜色的参数分别是:色调(H),饱和度(S),明度(V)。
色调(H):用角度度量,取值范围为0°~360°,从红色开始按逆时针方向计算,红色为0°,绿色为120°,蓝色为240°。它们的补色是:黄色为60°,青色为180°,品红为300°;
饱和度(S):饱和度S表示颜色接近光谱色的程度。一种颜色,可以看成是某种光谱色与白色混合的结果。其中光谱色所占的比例愈大,颜色接近光谱色的程度就愈高,颜色的饱和度也就愈高。饱和度高,颜色则深而艳。光谱色的白光成分为0,饱和度达到最高。通常取值范围为0%~100%,值越大,颜色越饱和。
明度(V):明度表示颜色明亮的程度,对于光源色,明度值与发光体的光亮度有关;对于物体色,此值和物体的透射比或反射比有关。通常取值范围为0%(黑)~100%(白)。
色彩转换:
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
实例:
#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); //这里选用的是自身电脑的摄像头可以替换为其他外接摄像头或是视频
//VideoCapture cap("F:\\NOW\\2\\2.1.mp4"); //加载视频
if ( !cap.isOpened() ) // 不成功便退出程序
{
cout << "Cannot open the web cam" << endl;
return -1;
}
namedWindow("Control", CV_WINDOW_AUTOSIZE); //create a window called "Control"
int iLowH = 100;
int iHighH = 140;
int iLowS = 90;
int iHighS = 255;
int iLowV = 90;
int iHighV = 255;
//Create trackbars in "Control" window
cvCreateTrackbar("LowH", "Control", &iLowH, 179); //Hue (0 - 179)
cvCreateTrackbar("HighH", "Control", &iHighH, 179);
cvCreateTrackbar("LowS", "Control", &iLowS, 255); //Saturation (0 - 255)
cvCreateTrackbar("HighS", "Control", &iHighS, 255);
cvCreateTrackbar("LowV", "Control", &iLowV, 255); //Value (0 - 255)
cvCreateTrackbar("HighV", "Control", &iHighV, 255);
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;
}
Mat imgHSV;
vector<Mat> hsvSplit;
cvtColor(imgOriginal, imgHSV, COLOR_BGR2HSV); //Convert the captured frame from BGR to HSV
//因为我们读取的是彩色图,直方图均衡化需要在HSV空间做
split(imgHSV, hsvSplit);
equalizeHist(hsvSplit[2],hsvSplit[2]);
merge(hsvSplit,imgHSV);
Mat imgThresholded;
inRange(imgHSV, Scalar(iLowH, iLowS, iLowV), Scalar(iHighH, iHighS, iHighV), imgThresholded); //Threshold the image
//开操作 (去除一些噪点)
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;
}
参考:
https://blog.csdn.net/bjbz_cxy/article/details/79701006RGB
颜色空间、色调、饱和度、亮度、HSV颜色空间详解