OpenCV4入门系列教程10:颜色空间

索引地址:系列教程索引地址

上一篇:OpenCV4入门系列教程9:imread()/imshow()/imwrite()

颜色通道

所谓通道,即路。每条路上有不同的数据,如果只有一条路(单通道)就组成二值图,即值只有0和255;如果是三通道,由R(ed)G(reen)B(lue)组成,就成了最常见的彩色图,三通道也有可能是其他组成,比如YUV。

OpenCV中颜色通道由CV_8UC1等表示:8表示数据有8位(00000000);UC表示unsigned char,即无符号整数,那么数据值为0-255;1表示1通道。CV_8UC1表示一张灰度图。float是32位的,对应数据结构参数就是:CV_32FC1,CV_32FC2,CV_32FC3…double是64位,对应数据结构参数:CV_64FC1,CV_64FC2,CV_64FC3等。

以上是最常用的RGB表示法,还有HVI表示法等等。如果不同通道类型的图片需要转换使用,使用函数cvColor()。

颜色空间转换:cvtColor()函数

函数作用:转换图像的颜色,彩色-灰度,HSV 等等

函数调用形式:

1
void cvtColor(InputArray src, OutputArray dst, int code, int dstCn=0 );

参数说明:

  • InputArray src:输入图像
  • OutputArray dst:输出图像
  • int code:表示图像转换的类型;<彩色图像—灰度图像>CV_RGB2GRAY,CV_BGR2YCrCb, CV_RGB2YCrCb, CV_YCrCb2BGR, CV_YCrCb2RGB,CV_BGR2HSV, CV_RGB2HSV, CV_HSV2BGR, CV_HSV2RGB
  • int dstCn=0:表示输出图像的通道,如果是0表示跟输入图像的通道数一样

测试代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include "opencv2/opencv.hpp"
using namespace cv;

int main() {
/// 读取一副图片,不改变图片本身的颜色类型(该读取方式为DOS运行模式)
Mat src = imread("lena.jpg", 1);
Mat src_gray;

/// 将图片转换成灰度图片
cvtColor(src, src_gray, COLOR_RGB2GRAY);
imshow("gray", src_gray);
waitKey(0);
return 0;
}

效果:

gray

Scalar

函数原型:

1
Scalar_ (_Tp v0, _Tp v1, _Tp v2=0, _Tp v3=0);

默认四个参数,其中两个是有默认值的,分别对应RGBA四个参数。通过其可以设置一个颜色。

默认使用方法是:

1
Mat M(7,7,CV_32FC2,Scalar(1,3));

上面的代码表示:创建一个2通道,且每个通道的值都为(1,3),深度为32,7行7列的图像矩阵。CV_32F表示每个元素的值的类型为32位浮点数,C2表示通道数为2,Scalar(1,3)表示对矩阵每个元素都赋值为(1,3),第一个通道中的值都是1,第二个通道中的值都是3。

测试代码1:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <iostream>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>

using namespace std;
using namespace cv;
void scalar_demo1(){
Mat M(4,4,CV_32FC2,Scalar(1,3));
cout<<M<<endl;
}
void scalar_demo2(){
Mat M(4,4,CV_32FC3,Scalar(1,2,3));
cout<<M<<endl;
}
void scalar_demo3(){
Mat M(4,4,CV_32FC4,Scalar(1,2,3));
cout<<M<<endl;
}
int main(void)
{
scalar_demo1();
cout<<"**********************************"<<endl;
scalar_demo2();
cout<<"**********************************"<<endl;
scalar_demo3();
return 0;
}

编译运行以上代码输出如下,可以发现最后一个矩阵是4通道的,但是我们在初始化的时候只给出了三个通道的值,所以第四个通道的值都默认为0。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ ./scalar
[1, 3, 1, 3, 1, 3, 1, 3;
1, 3, 1, 3, 1, 3, 1, 3;
1, 3, 1, 3, 1, 3, 1, 3;
1, 3, 1, 3, 1, 3, 1, 3]
**********************************
[1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3;
1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3;
1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3;
1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3]
**********************************
[1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0;
1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0;
1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0;
1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0]

测试代码2:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>

using namespace std;
using namespace cv;

int main(void)
{
Mat blue_m(256,256,CV_8UC3,Scalar(255,0,0));
Mat green_m(256,256,CV_8UC3,Scalar(0,255,0));
Mat red_m(256,256,CV_8UC3,Scalar(0,0,255));
imshow("Blue",blue_m);
waitKey(0);
imshow("Green",green_m);
waitKey(0);
imshow("Red",red_m);
waitKey(0);

return 0;
}

编译之后再终端运行,点击一次之后显示一张结果,连点三下之后显示三个结果,点击第四下自动关闭运行界面。

rgb

相信读到这你已经明白Scalar是用来干什么的了,它将各个通道的值构成一个整体,赋给具有相同通道数的矩阵元素。

下一篇:OpenCV4入门系列教程11:计时getTickCount()


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!