《OpenCV图像处理》 第四章 处理颜色

1、颜色空间

  • OpenCV有超过150多种可用的颜色空间转换方法。
  • 在imgproc中提供的函数是void cvtColor(InputArray src, OutputArray dst, int code, int dstCn=0),其中src是一副8位无符号、16位无符号或单精度浮点输入图像;dst是与src相同尺寸和深度的输出图像;code是颜色空间转换代码,例如COLOR_BGR2GRAY和COLOR_YCrCb2BGR;dstCn是目标图像的通道数,如果为0或省略,由src和cod自动产生。

①RGB

  • RGB是一种加性模型,一副图像由三个独立的图像平面或通道组成(RGB),以及一个可选项透明度,也称为alpha通道。
  • void split(InputArray m, OutputArrayOfArrays mv)
  • void merge(InputArrayOfArrays mv, OutputArray dst)

②灰度图

  • 灰度图中,每个像素只有灰度强度信息单一值,由不同的灰色阴影特别形成的一副图像。
  • 转换参数有:COLOR_BGR2GRAY、COLOR_RGB2GRAY、COLOR_GRAY2BGR、COLOR_GRAY2RGB

③CIE XYZ

  • 该系统用一个亮度分量Y来描述颜色,它与人类视觉的亮度灵敏度和两个附加通道X和Z相关。
  • 转换参数有:COLOR_BGR2XYZ、COLOR_RGB2XYZ、COLOR_XYZ2BGR、COLOR_XYZ2RGB
  • 示例代码
#include <opencv2/opencv.hpp>
#include <opencv2/imgproc.hpp>
#include<iostream>

using namespace cv;
using namespace std;
vector<Mat> showSeparatedChannels(vector<Mat> channnels);
int main()
{
	Mat src,dst;
	//读入图片
	src = imread("test.jpg");
	imshow("Ori", src);
	//转换为CIEXYZ
	cvtColor(src, src, COLOR_BGR2XYZ);
	
	//拆分每个通道并显示
	vector<Mat> channels;
	split(src, channels);

	//在灰度空间中显示通道
	namedWindow("X channel(gray)", WINDOW_AUTOSIZE);
	imshow("X channel(gray)", channels[0]);
	namedWindow("X channel(gray)", WINDOW_AUTOSIZE);
	imshow("Y channel(gray)", channels[1]);
	namedWindow("X channel(gray)", WINDOW_AUTOSIZE);
	imshow("Z channel(gray)", channels[2]);

	//在BGR中显示通道
	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]);

	waitKey();
	return 0;
}

vector<Mat> showSeparatedChannels(vector<Mat> channnels) {
	vector<Mat> separatedChannels;
	//创建每副图像的每个通道
	for (int i = 0; i < 3; i++) {
		Mat zer = Mat::zeros(channnels[0].rows, channnels[0].cols, channnels[0].type());
		vector<Mat> aux;
		for (int j = 0; j < 3; j++) {
			if (j == i)
				aux.push_back(channnels[i]);
			else
				aux.push_back(zer);
		}
		Mat chann;
		merge(aux, chann);
		separatedChannels.push_back(chann);
	}
	return separatedChannels;
}

④YCrCb

  • Y通道表示亮度,Cr和Cb表示红色色差和蓝色色差(Y和R的差值、Y和B的差值)。该颜色空间广泛应用于MPEG和JPEG等视频和图像压缩方案。
  • 转换参数有:COLOR_BGR2YCrCb、COLOR_RGB2YCrCb、COLOR_YCrCb2BGR、COLOR_YCrCb2RGB

⑤HSV

  • HSV的三个通道表示色度(H给出颜色光谱构成的一种度量),饱和度(S给出主波长中的纯光比例,这表明一种颜色距离相同亮度灰度的程度)和纯度(V给出相对于白色光光照强度的亮度)
  • OpenCV的imshow函数以RGB显示图像,如果在其他颜色空间中有一副图像并希望正确显示它,应该先将其转为RGB
  • 示例代码
#include <opencv2/opencv.hpp>
#include <opencv2/imgproc.hpp>
#include<iostream>

using namespace cv;
using namespace std;

int main()
{
	Mat src;
	//读入图片
	src = imread("test.jpg");
	imshow("Ori", src);
	//转换为CIEXYZ
	cvtColor(src, src, COLOR_BGR2HSV);
	
	//拆分每个通道并显示
	vector<Mat> channels;
	split(src, channels);

	//在灰度空间中显示通道
	namedWindow("H channel(gray)", WINDOW_AUTOSIZE);
	imshow("H channel(gray)", channels[0]);
	namedWindow("S channel(gray)", WINDOW_AUTOSIZE);
	imshow("S channel(gray)", channels[1]);
	namedWindow("V channel(gray)", WINDOW_AUTOSIZE);
	imshow("V channel(gray)", channels[2]);

	namedWindow("HSV", WINDOW_AUTOSIZE);
	imshow("HSV", src);

	waitKey();
	return 0;
}

⑥HLS

  • HLS与HSV类型,与HSV不同的是:由HLS定义的一种纯颜色的亮度等于一种中等灰色的亮度,而由HSV定义的一种纯颜色的亮度等于白色的亮度。

⑦CIE L*a*b*

  • 由CIE XYZ衍生而来。L*表示颜色的亮度,a*表示在品红和绿色之间的位置,b*表示在黄色和蓝色之间的位置。

⑧CIE L*u*v*

  • CIE XYZ空间和白色参考点的一种简化计算转换,尝试达到感知均匀性。L*亮度,u*表示位于绿色和红色间位置,v*表示在多大程度上是蓝色和紫色。

⑨Bayer

  • Bayer像素空间组合 广泛应用于只有一个图像传感器的数字相机。

2、基于颜色空间的分割

  • void inRange( InputArray src, InputArray loewrb, InputArray upperb, OutputArray dst )。检查一个元素数组是否位于两个其他数组的元素之间。获取一副图像src的像素集合,各个通道的值位于下边界lowerb和上边界upperb之间,得到一副图像dst。

①HSV分割

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

using namespace cv;
using namespace std;

int main()
{
	Mat src,hsv,bw;
	//读入图片
	src = imread("test.jpg");
	imshow("Ori", src);

	//转换为CIEXYZ
	cvtColor(src, hsv, COLOR_BGR2HSV);
	
	//选取像素
	inRange(hsv, Scalar(0, 10, 60), Scalar(20, 150, 255), bw);

	namedWindow("Select pixel", WINDOW_AUTOSIZE);
	imshow("Select pixel", bw);

	waitKey();
	return 0;
}

②YCrCb分割

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

using namespace cv;
using namespace std;

int main()
{
	Mat src,ycrcb,bw;
	//读入图片
	src = imread("test.jpg");
	imshow("Ori", src);

	//转换为CIEXYZ
	cvtColor(src, ycrcb, COLOR_BGR2YCrCb);
	
	//选取像素
	inRange(ycrcb, Scalar(0, 133, 77), Scalar(255, 173, 177), bw);

	namedWindow("Select pixel", WINDOW_AUTOSIZE);
	imshow("Select pixel", bw);

	waitKey();
	return 0;
}

3、颜色变换

  • 为修改一副图像的颜色,特别是在有必要删除一个主要或不希望的颜色场合,方法之一就是颜色变换。
  • colorTransfer示例代码
#include <opencv2/opencv.hpp>
#include <opencv2/imgproc.hpp>
#include<iostream>

using namespace cv;
using namespace std;

int main()
{
	Mat src,tar,src_lab,tar_lab,output;
	//读入图片
	src = imread("test1.jpg");
	tar = imread("test2.jpg");
	//变换到Lab空间和CV_32F1
	cvtColor(src, src_lab, COLOR_BGR2Lab);
	cvtColor(tar, tar_lab, COLOR_BGR2Lab);
	
	src_lab.convertTo(src_lab, CV_32FC1);
	tar_lab.convertTo(tar_lab, CV_32FC1);
	
	//为每副图像找到每个通道的均值和std值
	Mat mean_src, mean_tar, stdd_src, stdd_tar;
	meanStdDev(src_lab, mean_src, stdd_src);
	meanStdDev(tar_lab, mean_tar, stdd_tar);

	//拆分成独立的通道
	vector<Mat> src_chan, tar_chan;
	split(src_lab, src_chan);
	split(tar_lab, tar_chan);

	for (int i = 0; i < 3; i++) {
		tar_chan[i] -= mean_tar.at<double>(i);
		tar_chan[i] *= (stdd_src.at<double>(i) / stdd_src.at<double>(i));
		tar_chan[i] += mean_src.at<double>(i);
	}

	//合并通道,转换到CV_8UC1,并转到BGR
	merge(tar_chan, output);
	output.convertTo(output, CV_8UC1);
	cvtColor(output, output, COLOR_Lab2BGR);

	namedWindow("Ori", WINDOW_AUTOSIZE);
	imshow("Ori", src);
	namedWindow("tar", WINDOW_AUTOSIZE);
	imshow("tar", tar);
	namedWindow("output", WINDOW_AUTOSIZE);
	imshow("output", output);

	waitKey();
	return 0;
}

4、参考资料

     《OpenCV 图像处理》Gloria Bueno Garcia、Oscar Deniz Suarez、Jose Luis Espinosa Aranda著,刘冰 翻译,机械工业出版社出版,2016年11月

猜你喜欢

转载自blog.csdn.net/weixin_39731083/article/details/81262394