【OpenCV】笔记(9)——色彩空间和颜色处理

颜色空间:用三种或者更多特征来指定颜色的方法,被称为颜色空间或者颜色模型

颜色空间转换:OpenCV中有超过150种可用的颜色空间转换方法
最常用的是在imgproc模块中提供的void cvtColor函数


函数名 参数 解释
void cvtColor( InputArray src, OutputArray dst, int code, int dstCn = 0 );
@param src input image: 8-bit unsigned, 16-bit unsigned ( CV_16UC... ), or single-precision
floating-point.
@param dst output image of the same size and depth as src.
@param code color space conversion code (see cv::ColorConversionCodes).
@param dstCn number of channels in the destination image; if the parameter is 0, the number of the
channels is derived automatically from src and code.
输入图像,8或者16位无符号整形或者单精度浮点数



与src具有相同尺寸和深度的输出图像
颜色空间的转换代码

目标图像的通道数




颜色空间


1     RGB
一幅图像由三个独立的图像平面或者通道构成:红、蓝、绿(以及可选项:透明度alpha通道)
每个值代表每个像素的每个分量的度量值,值越高对应于更亮的像素
对应于人眼的三种光锥细胞,所以被广泛使用


2     灰度图
每个像素值只表示灰度信息这一单一信息
RGB[A]准换成灰度:Y=0.299*R+0.587*G+0.114*B
灰度转换为RGB[A]:R=Y,G=Y,B=Y,A=max(ChannelRange)




3     CLE XYZ
     
CLE XYZ系统采用一个亮度分量Y来描述颜色,它与人类视觉鄂亮度灵敏度和两个附加通道X,Y有关,为国际照明委员会CLE使用来自一些人观测实验的统计得到的标准
该颜色空间的主要问题是颜色以不均匀地方式被缩放

这种现象导致了CLE采用 CLE L*a*b* 和L*u*v*模型


4     YCrCb
该空间广泛用于视频和图像压缩,不能算作纯粹的色彩空间,它是RGB颜色空间的一种解码方式
Y通道表示亮度,而Cr和Cb表示红色差值(在RGB空间中R通道和Y的差值)和蓝色差值 (在RGB空间中B通道和Y的差值)各自的色度分量。

其变化计算如下:


5     HSV
HSV颜色空间输入面向色度的颜色坐标系统的一种。这种类型的颜色模型接近人类颜色感知的仿真模型。
HSV的三个通道表示色度(H给出的颜色光谱构成的一种度量),饱和度(S给出主波长中的纯光比例,这表明一种颜色距离相同亮度灰度的程度)和纯度(V给出相对于白色光照强度的亮度),对应于直觉上的色彩、明暗和色调。HSV广泛应用于色彩的比较。




TIP:OpenCV中的imshow()函数假设图像的颜色以RGB显示,因此其他显示均不正确。所以首先必须将其转换成RGB颜色空间

6     HLS
HLS属于面向色度的颜色坐标系统中的一种,和之前的HSV类似
用来指定每个通道中的一种颜色的色度值、明暗值、饱和度值
与HSV不同的是HSL定义的一种纯颜色的亮度等于一种中等灰色的亮度
而HSV定义的一种纯颜色的亮度等于白色的亮度

7     CLE L*a*b
8     CLE L*u*v

9     Bayer
Bayer像素空间组合被广泛用于只有一个图像传感器的数字相机中,每个RGB通道只有一个传感器,每个像素被一个不同颜色的滤波器覆盖掉,每个像素测量的只有一个值。使用Bayer方法时,会利用临近的像素来推断丢失的颜色信息,像素时交错分布的。


#include <opencv2/opencv.hpp>
#include <opencv2/imgproc.hpp>

using namespace std;
using namespace cv;

vector<Mat > showSeparatedChannels(vector< Mat> channels );

int main()
{
                 //read source image
                 Mat src = imread("lijiang.jpg" );
                imshow( "Picture", src);

                 //xyz        
                 //cvtColor(src, src, COLOR_BGR2XYZ);
                
                 //vector<Mat> channels;
                 //split(src, channels);

                 //split
                 //vector<Mat> channels;
                 //cout << "-----------------1\n";
                 ///split(src, channels);
                 //cout << "-----------------2\n";//不知道为啥总是出错


                 /*show B,G,R channels(gray)
                namedWindow("Blue channel(gray)", WINDOW_AUTOSIZE);
                imshow("Blue channel(gray)", channels[0]);

                namedWindow("Green channel(gray)", WINDOW_AUTOSIZE);
                imshow("Green channel(gray)", channels[1]);

                namedWindow("Red channel(gray)", WINDOW_AUTOSIZE);
                imshow("Red channel(gray)", channels[2]);

                //show B,G,R channels(colorful)
                vector<Mat> separatedChannels = showSeparatedChannels(channels);

                namedWindow("Blue channel", WINDOW_AUTOSIZE);
                imshow("Blue channel", separatedChannels[0]);

                namedWindow("Green channel", WINDOW_AUTOSIZE);
                imshow("Green channel", separatedChannels[1]);

                namedWindow("Red channel", WINDOW_AUTOSIZE);
                imshow("Red channel", separatedChannels[2]);

                Mat imageGray;
                cvtColor(src, imageGray, COLOR_BGR2GRAY);

                namedWindow("Gray picture", WINDOW_AUTOSIZE);
                imshow("Gray picture", imageGray);
                */

                 /*
                namedWindow("X channel(gray)", WINDOW_AUTOSIZE);
                imshow("Xchannel(gray)", channels[0]);

                namedWindow("Y channel(gray)", WINDOW_AUTOSIZE);
                imshow("Y channel(gray)", channels[1]);

                namedWindow("Z channel(gray)", WINDOW_AUTOSIZE);
                imshow("Z channel(gray)", channels[2]);

                vector<Mat> separatedChannels = showSeparatedChannels(channels);
                for (int i = 0;i < 3;i++)
                {
                                cvtColor(separatedChannels[i], separatedChannels[i], COLOR_XYZ2BGR);
                }

                namedWindow("X channel", WINDOW_AUTOSIZE);
                imshow("X channel", separatedChannels[0]);

                namedWindow("Y channel", WINDOW_AUTOSIZE);
                imshow("Y channel", separatedChannels[1]);

                namedWindow("Z channel", WINDOW_AUTOSIZE);
                imshow("Z channel", separatedChannels[2]);

                */

                 Mat bayer = imread("lijiang.jpg" , CV_8UC3);
                namedWindow( "Bayer picture", WINDOW_AUTOSIZE );
                imshow( "Bayer picture", bayer);

                 Mat imageColor;
                cvtColor(bayer, imageColor, COLOR_BayerRG2BGR);

                namedWindow( "Color picture", WINDOW_AUTOSIZE );
                imshow( "Color picture", imageColor);

                waitKey();

                 return 0;
}


vector<Mat > showSeparatedChannels(vector< Mat> channels )
{
                 vector<Mat > separatedChannels;

                 for (int i = 0; i < 3; i++)
                {
                                 Mat zer = Mat ::zeros(channels[ 0].rows, channels[0].cols, channels[0].type());

                                 vector<Mat > aux;
                                 for (int j = 0;j < 3;j++)
                                {
                                                 if (j == i)
                                                {
                                                                aux.push_back( channels[i]);
                                                }
                                                 else
                                                {
                                                                aux.push_back(zer);
                                                }

                                }
                                 Mat chann;
                                merge(aux, chann);

                                separatedChannels.push_back(chann);

                }
                 return separatedChannels;

}



基于颜色空间的分割

When the lower and/or upper boundary parameters are scalars, the indexes
(I) at lowerb and upperb in the above formulas should be omitted.
@param src first input array.
@param lowerb inclusive lower boundary array or a scalar.
@param upperb inclusive upper boundary array or a scalar.
@param dst output array of the same size as src and CV_8U type.
*/
CV_EXPORTS_W void inRange(InputArray src, InputArray lowerb,
                          InputArray upperb, OutputArray dst);

利用HSV空间



利用YCrCb空间

#include <opencv2/opencv.hpp>
#include <opencv2/imgproc.hpp>

using namespace std;
using namespace cv;

int main()
{
                 //read source image
                 Mat src = imread("hand.png" );
                imshow( "Picture", src);

                 //Mat hsv;
                 //cvtColor(src, hsv, COLOR_BGR2HSV);

                 //Mat bw;
                 //inRange(hsv, Scalar(0, 10, 60), Scalar(20, 150, 255), bw);
                 Mat ycrcb;
                 Mat bw;
                cvtColor(src, ycrcb, COLOR_BGR2YCrCb);
                inRange(ycrcb, Scalar(0, 133, 77), Scalar (255, 173, 177), bw);

                namedWindow( "Selected pixels", WINDOW_AUTOSIZE );
                imshow( "Selected pixels", bw);

                waitKey();

                 return 0;
}
  





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值