一、背景
一般例如红外图像,呈现出来的是灰度图效果,此时每个像素有一个,在0-255内,如果想要观看伪彩图,也就是人工设置的彩色,需要在灰度图的基础上,给它增加RGB三个通道的值,让它变为看起来有红绿蓝叠加的彩色效果,原理也就是把1个灰度值变为3个值RGB。
二、代码
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
Mat scaleGray(const Mat& inputGray)
{
Mat outputGray(inputGray.size(), CV_8U);
unsigned char grayValue, maxValue = 1;
for (int y = 0; y < inputGray.rows; y++)
for (int x = 0; x < inputGray.cols; x++)
{
grayValue = inputGray.at<uchar>(y, x);
maxValue = max(maxValue, grayValue);
}
float scale = 255.0 / maxValue;
for (int y = 0; y < inputGray.rows; y++)
for (int x = 0; x < inputGray.cols; x++)
{
outputGray.at<uchar>(y, x) = static_cast<unsigned char>(inputGray.at<uchar>(y, x) * scale + 0.5);
}
return outputGray;
}
Mat gray2pseudocolor(const Mat& scaledGray)
{
Mat outputPseudocolor(scaledGray.size(), CV_8UC3);
unsigned char grayValue;
for (int y = 0; y < scaledGray.rows; y++)
for (int x = 0; x < scaledGray.cols; x++)
{
//获取灰度值
grayValue = scaledGray.at<uchar>(y, x);
Vec3b& pixel = outputPseudocolor.at<Vec3b>(y, x);
//给mat的RGB三通道赋值 orange 255 127 0
pixel[0] = abs(255 - grayValue);
pixel[1] = abs(127 - grayValue);
pixel[2] = abs(0 - grayValue);
}
return outputPseudocolor;
}
/*
* color R G B gray
* red 255 0 0 255
* orange 255 127 0 204
* yellow 255 255 0 153
* green 0 255 0 102
* cyan 0 255 255 51
* blue 0 0 255 0
*
*/
Mat gray2rainbow(const Mat& scaledGray)
{
Mat outputRainbow(scaledGray.size(), CV_8UC3);
unsigned char grayValue;
for (int y = 0; y < scaledGray.rows; y++)
for (int x = 0; x < scaledGray.cols; x++)
{
grayValue = scaledGray.at<uchar>(y, x);
Vec3b& pixel = outputRainbow.at<Vec3b>(y, x);
//对灰度值进行分阶段处理,让色彩更丰富
if (grayValue <= 51)
{
pixel[0] = 255;
pixel[1] = grayValue * 5;
pixel[2] = 0;
}
else if (grayValue <= 102)
{
grayValue -= 51;
pixel[0] = 255 - grayValue * 5;
pixel[1] = 255;
pixel[2] = 0;
}
else if (grayValue <= 153)
{
grayValue -= 102;
pixel[0] = 0;
pixel[1] = 255;
pixel[2] = grayValue * 5;
}
else if (grayValue <= 204)
{
grayValue -= 153;
pixel[0] = 0;
pixel[1] = 255 - static_cast<unsigned char>(grayValue * 128.0 / 51 + 0.5);
pixel[2] = 255;
}
else if (grayValue <= 255)
{
grayValue -= 204;
pixel[0] = 0;
pixel[1] = 127 - static_cast<unsigned char>(grayValue * 127.0 / 51 + 0.5);
pixel[2] = 255;
}
}
return outputRainbow;
}
int main(int argc, char* argv[])
{
Mat inputGray = imread("red-2022-3-27_20-25-42.jpg", 0);
Mat scaledGray = scaleGray(inputGray);
//伪彩
Mat pseudocolor = gray2pseudocolor(scaledGray);
//五彩缤纷
Mat rainbow = gray2rainbow(scaledGray);
imwrite("scaledGray.jpg", scaledGray);
imwrite("pseudocolor.jpg", pseudocolor);
imwrite("rainbow.jpg", rainbow);
namedWindow("gray", WINDOW_NORMAL);
resizeWindow("gray", 640, 480);
//移动窗口位置
moveWindow("gray", 100, 20);
imshow("gray", inputGray);
namedWindow("pseudocolor", WINDOW_NORMAL);
resizeWindow("pseudocolor", 640, 480);
//移动窗口位置
moveWindow("pseudocolor", 740, 20);
imshow("pseudocolor", pseudocolor);
namedWindow("rainbow", WINDOW_NORMAL);
resizeWindow("rainbow", 640, 480);
//移动窗口位置
moveWindow("rainbow", 740, 500);
imshow("rainbow", rainbow);
waitKey(0);
return 0;
}