该代码是一个使用OpenCV库实现的C++程序,主要用来展示如何通过applyColorMap
函数将色彩映射应用到一个灰度图像上,并提供一个滑动条来实时改变色彩映射的效果。此外,该程序还可以绘制包含不同形状的灰度图像,用作applyColorMap
函数的输入。程序的总体流程为:
-
引入OpenCV库和标准I/O库。
-
声明使用命名空间cv和std。
-
定义形状类型枚举MyShape。
-
定义ParamColorMap结构体保存色彩映射参数。
-
定义一个色彩映射窗口名称和色彩映射名称数组。
-
实现TrackColorMap回调函数,用于响应色彩映射滑动条操作。
-
实现DrawMyImage函数,绘制灰度图像并在图像上绘制随机形状。
-
main函数中读取或生成输入图像,创建窗口环境,并展示图像和色彩映射效果。
-
等待用户按键退出程序。
整个程序示范了如何使用OpenCV函数动态地对图像应用不同的色彩映射,并且通过用户界面交互,让用户可以选择和查看不同的色彩映射效果。
cpp
#include "opencv2/imgproc.hpp" // 包含OpenCV图像处理库
#include "opencv2/imgcodecs.hpp" // 包含OpenCV图像编解码库
#include "opencv2/highgui.hpp" // 包含OpenCV高级用户界面库
#include <iostream> // 包含标准输入输出流库
// 使用命名空间 cv 和 std 来简化代码中的类型和成员函数的引用
using namespace cv;
using namespace std;
// 定义一个枚举类型 MyShape 表示形状类型
enum MyShape{MyCIRCLE=0,MyRECTANGLE,MyELLIPSE};
// 定义一个结构体 ParamColorMap 存储色彩映射的参数
struct ParamColorMap {
int iColormap; // 当前色彩映射的编号
Mat img; // 存储将要映射色彩的图像
};
// 定义一个窗口名称常量
String winName="False color";
// 定义一个色彩映射名称数组,包括各种色彩映射的名称
static const String ColorMaps[] = {
"Autumn", "Bone", "Jet", "Winter", "Rainbow", "Ocean", "Summer", "Spring",
"Cool", "HSV", "Pink", "Hot", "Parula", "Magma", "Inferno", "Plasma", "Viridis",
"Cividis", "Twilight", "Twilight Shifted", "Turbo", "Deep Green", "User defined (random)"
};
// 定义TrackColorMap回调函数,当拖动条改变时调用此函数实现色彩映射的更新
static void TrackColorMap(int x, void *r)
{
ParamColorMap *p = (ParamColorMap*)r; // 将传入的void指针转换为ParamColorMap结构体指针
Mat dst; // 创建一个输出图像
p->iColormap = x; // 设置当前色彩映射的编号
// 判断是否为用户自定义色彩映射
if (x == COLORMAP_DEEPGREEN + 1)
{
// 创建一个随机的查找表 LUT (Look Up Table)
Mat lutRND(256, 1, CV_8UC3);
// 使用随机值填充查找表
randu(lutRND, Scalar(0, 0, 0), Scalar(255, 255, 255));
// 应用用户自定义的随机色彩映射
applyColorMap(p->img, dst, lutRND);
}
else
{
// 应用官方定义的色彩映射
applyColorMap(p->img, dst, p->iColormap);
}
// 在输出图像上添加文字,显示当前的色彩映射名称
putText(dst, "Colormap : "+ColorMaps[p->iColormap], Point(10, 20), FONT_HERSHEY_SIMPLEX, 0.8, Scalar(255, 255, 255), 2);
// 在窗口中展示色彩映射后的图像
imshow(winName, dst);
}
// 定义DrawMyImage函数,用于生成包含不同形状的灰度图像
static Mat DrawMyImage(int thickness, int nbShape)
{
// 创建一个黑色背景的图像
Mat img = Mat::zeros(500, 256*thickness + 100, CV_8UC1);
// 定义线和形状的偏移量
int offsetx = 50, offsety = 25;
// 定义线的长度
int lineLength = 50;
// 绘制256个灰度梯度的线条
for (int i=0; i<256; i++)
line(img, Point(thickness * i + offsetx, offsety), Point(thickness * i + offsetx, offsety + lineLength), Scalar(i), thickness);
// 创建随机数生成器对象 r
RNG r;
// 存储形状参数的变量
Point center;
int radius;
int width, height;
int angle;
Rect rc;
// 根据参数 nbShape 绘制随机数量和类型的形状
for (int i=1; i<=nbShape; i++)
{
// 随机选择一个形状类型
int typeShape = r.uniform(MyCIRCLE, MyELLIPSE + 1);
switch (typeShape) {
case MyCIRCLE:
// 绘制一个圆形
center = Point(r.uniform(offsetx, img.cols - offsetx), r.uniform(offsety + lineLength, img.rows - offsety));
radius = r.uniform(1, min(offsetx, offsety));
circle(img, center, radius, Scalar(i), -1);
break;
case MyRECTANGLE:
// 绘制一个矩形
center = Point(r.uniform(offsetx, img.cols - offsetx), r.uniform(offsety + lineLength, img.rows - offsety));
width = r.uniform(1, min(offsetx, offsety));
height = r.uniform(1, min(offsetx, offsety));
rc = Rect(center - Point(width, height) / 2, center + Point(width, height) / 2);
rectangle(img, rc, Scalar(i), -1);
break;
case MyELLIPSE:
// 绘制一个椭圆
center = Point(r.uniform(offsetx, img.cols - offsetx), r.uniform(offsety + lineLength, img.rows - offsety));
width = r.uniform(1, min(offsetx, offsety));
height = r.uniform(1, min(offsetx, offsety));
angle = r.uniform(0, 180);
ellipse(img, center, Size(width / 2, height / 2), angle, 0, 360, Scalar(i), -1);
break;
}
}
// 返回生成的图像
return img;
}
// 程序的主入口
int main(int argc, char** argv)
{
// 输出程序的简短描述
cout << "This program demonstrates the use of applyColorMap function.\n\n";
// 创建一个ParamColorMap结构体变量 p 来存储色彩映射的参数
ParamColorMap p;
Mat img;
// 判断命令行是否提供了输入文件路径
if (argc > 1)
// 如果提供了,则读取指定的图像文件
img = imread(samples::findFile(argv[1]), IMREAD_GRAYSCALE);
else
// 如果没有提供,则生成一个图像
img = DrawMyImage(2, 256);
// 设置色彩映射的参数
p.img = img;
p.iColormap = 0;
// 展示灰度图像
imshow("Gray image", img);
// 创建一个新窗口
namedWindow(winName);
// 在新窗口中创建一个滑动条,用于调节色彩映射
createTrackbar("colormap", winName, NULL, COLORMAP_DEEPGREEN + 1, TrackColorMap, (void*)&p);
// 设置滑动条的最小值
setTrackbarMin("colormap", winName, COLORMAP_AUTUMN);
// 设置滑动条的最大值
setTrackbarMax("colormap", winName, COLORMAP_DEEPGREEN + 1);
// 设置滑动条的当前位置
setTrackbarPos("colormap", winName, COLORMAP_AUTUMN);
// 初始调用TrackColorMap函数来展示色彩映射效果
TrackColorMap(0, (void*)&p);
// 打印提示信息,告知用户可以按任意键退出程序
cout << "Press a key to exit" << endl;
// 等待用户按键,然后关闭程序
waitKey(0);
return 0;
}