Ink One

OpenCV 学习笔记(5)

对灰度图进行伪彩色处理。

定义常量

定义一个常量

1
2
#define <常量名> <常量值>
const <常量类型> <常量名> = <常量值>;

枚举类型 enum

1
2
enum <枚举类型名> {<枚举表>};
enum {<枚举表>} <变量名表>;

C++ enum 枚举表中每一个枚举值对应着一个整型数,通常情况下如果其中的枚举常量没有定义数值,那么第一个枚举值对应着常量值0,然后依次递增;如果第一个枚举常量定义了数值,那么其后的值将随之递增,其中每个常量之间用“,”隔开,而不是”;“,最后一个数值不用符号。
enum bool {false,true}; bool类型就是C++预定义的枚举。

问题描述

对下图进行伪彩色变换。
灰度图像
点此下载

采用如下灰度变换曲线:
灰度变换曲线

程序实现

灰度变换函数

由上图灰度变换曲线可得,RGB通道的灰度值为原灰度值的分段函数。



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
29
30
31
32
33
34
35
36
37
//彩色图通道的顺序为BGR
#define BLUE 0
#define GREEN 1
#define RED 2
//灰度变换
//x:像素灰度
//color:RED、GREEN 或 BLUE
//maxVal:灰度最大值,由图像深度得到
//若图像深度为CV_8U,则maxVal=255;若图像深度为CV_32F,则maxVal=1
float trans(float x, int color, int maxVal = 1)
{
//将输入灰度 x 缩放到 [0,1] 范围内
x /= maxVal;
if (x < 0) x = 0;
if (x > 1) x = 1;
float y;
if (color == RED) {
if (x < 0.5) y = 0;
else if (x < 0.75) y = 4 * x - 2;
else y = 1;
}
else if (color == GREEN) {
if (x < 0.25) y = 4 * x;
else if (x < 0.75) y = 1;
else y = -4 * x + 4;
}
else if (color == BLUE){
if (x < 0.25) y = 1;
else if (x < 0.5) y = -4 * x + 2;
else y = 0;
}
//若输入颜色不属于R、G、B,返回输入灰度
else y = x;
y *= maxVal;
return y;
}

伪彩色处理

根据灰度变换曲线分别计算得到三个单通道(B、G、R)的灰度图,再合成三通道的彩色图像。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//伪彩色处理
//输入灰度图像,输出伪彩色图像
Mat colorProcess(const Mat &grayImage) {
//计算三个单通道图像(BGR)
Mat plane[3];
for (int k = 0; k < 3; k++) {
plane[k] = Mat(grayImage.size(), grayImage.type());
for (int i = 0; i < grayImage.rows; i++) {
for (int j = 0; j < grayImage.cols; j++) {
plane[k].at<uchar>(i, j) = trans((grayImage.at<uchar>(i, j)), k, 255);
}
}
}
//将三个单通道图像合成一个三通道彩色图像
Mat rgbImage;
merge(plane, 3, rgbImage);
return rgbImage;
}

最后处理得到伪彩色图像如下:
伪彩色图像