OpenCV + CPP 系列(六)色彩映射(颜色表)

本文详细介绍了OpenCV中的`cv::applyColorMap()`函数,用于将灰度图像转换为预定义的彩色图像,展示了20种不同的颜色映射效果。同时,还探讨了`cv::LUT`函数,利用查找表进行像素映射,以增强图像的对比度和突出有用信息。通过示例代码,演示了如何使用这两个函数在C++中实现图像处理操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


彩色映射 cv::applyColorMap()cv::LUT() 函数

一、cv::applyColorMap()

cv::applyColorMap()是使用opencv预定义的colormap,将灰度图映射成彩色图像。opencv中提供了20个预定义的colormaps,如下函数参数所示

函数参数

No.cpppython图像示例
1COLORMAP_AUTUMNcv2.COLORMAP_AUTUMNautumn
2COLORMAP_BONEcv2.COLORMAP_BONEBONE
3COLORMAP_JETcv2.COLORMAP_JET在这里插入图片描述
4COLORMAP_WINTERcv2.COLORMAP_WINTER在这里插入图片描述
5COLORMAP_RAINBOWcv2.COLORMAP_RAINBOW在这里插入图片描述
6COLORMAP_OCEANcv2.COLORMAP_OCEAN在这里插入图片描述
7COLORMAP_SUMMERcv2.COLORMAP_SUMMER在这里插入图片描述
8COLORMAP_SPRINGcv2.COLORMAP_SPRING在这里插入图片描述
9COLORMAP_COOLcv2.COLORMAP_COOL在这里插入图片描述
10COLORMAP_HSVcv2.COLORMAP_HSV在这里插入图片描述
11COLORMAP_PINKcv2.COLORMAP_PINK在这里插入图片描述
12COLORMAP_HOTcv2.COLORMAP_HOT在这里插入图片描述
13COLORMAP_PARULAcv2.COLORMAP_PARULA在这里插入图片描述
14COLORMAP_MAGMAcv2.COLORMAP_MAGMA在这里插入图片描述
15COLORMAP_INFERNOcv2.COLORMAP_INFERNO在这里插入图片描述
16COLORMAP_PLASMAcv2.COLORMAP_PLASMA在这里插入图片描述
17COLORMAP_VIRIDIScv2.COLORMAP_VIRIDIS在这里插入图片描述
18COLORMAP_CIVIDIScv2.COLORMAP_CIVIDIS在这里插入图片描述
19COLORMAP_TWILIGHTcv2.COLORMAP_TWILIGHT在这里插入图片描述
20COLORMAP_TWILIGHT_SHIFTEDcv2.COLORMAP_TWILIGHT_SHIFTED在这里插入图片描述

opencv-python实现效果:点击查看

头文件 quick_opencv.h:添加声明公共函数

#pragma once
#include <opencv2\opencv.hpp>
using namespace cv;

class QuickDemo {
public:
	void color_style_Demo(Mat& image);
	void LUT_Demo(Mat& image);
};

主函数调用该类的公共成员函数

#include <opencv2\opencv.hpp>
#include <quick_opencv.h>
#include <iostream>
using namespace cv;


int main(int argc, char** argv) {
	Mat src = imread("D:\\Desktop\\pandas_small2.png");
	if (src.empty()) {
		printf("Could not load images...\n");
		return -1;
	}
	namedWindow("input", WINDOW_NORMAL);
	imshow("input", src);

	QuickDemo qk;

	qk.color_style_Demo(src);
	qk.LUT_Demo(src);
	waitKey(0);
	destroyAllWindows();
	return 0;
}


方法演示

源文件 quick_demo.cpp:实现类与公共函数

#include <quick_opencv.h>


// 新增了实现函数
void QuickDemo::color_style_Demo(Mat& image) {
	int colormap[] = {
		COLORMAP_AUTUMN,
		COLORMAP_BONE,
		COLORMAP_JET,
		COLORMAP_WINTER,
		COLORMAP_RAINBOW,
		COLORMAP_OCEAN,
		COLORMAP_SUMMER,
		COLORMAP_SPRING,
		COLORMAP_COOL,
		COLORMAP_HSV,
		COLORMAP_PINK,
		COLORMAP_HOT,
		COLORMAP_PARULA,
		COLORMAP_MAGMA,
		COLORMAP_INFERNO,
		COLORMAP_PLASMA,
		COLORMAP_VIRIDIS,
		COLORMAP_CIVIDIS,
		COLORMAP_TWILIGHT,
		COLORMAP_TWILIGHT_SHIFTED,
	};

	Mat dst;
	int index = 0;
	while (true)
	{
		int c = waitKey(2000);
		if (c == 27) {
			break;
		}
		applyColorMap(image, dst,colormap[index%19]);
		imwrite("D:\\Desktop\\" + std::to_string(colormap[index % 19]) + ".png", dst);
		index++;

		// 保存18张图片
		imshow("颜色风格", dst);
		if (index == 18) {
			break;
		}
	}
}


在这里插入图片描述

二、cv::LUT

LUT(Look-Up Table) 像素映射表。
它将实际采样到的像素灰度值经过一定的变换如阈值、反转、二值化、对比度调整、线性变换等,变成了另外一个与之对应的灰度值,这样可以起到突出图像的有用信息,增强图像的光对比度的作用。

其实查询表的实质就是:把图像中的数据从之前的比较高的灰度级降下来,例如灰度级是256的char类型的灰度级,我们通过一个参数,将原来的256个灰度级降到了3个灰度级,原来图像中灰度值在0-100的数据现在灰度值变成了0,原来灰度值为101-200的图像数据现在灰度值变为了1,而201-256的灰度值就变为了2。所以通过参数100,图像的灰度级就到了2,只有0,1,2三个灰度值,那么原来的图像矩阵中的每一位数据我们是char型的,需要8位来表示一个数据,而灰度级降下来之后,我们只需要2位就足以表示所有灰度值。

void LUT(
InputArray src,    输入图像(可以是单通道也可是3通道)
InputArray lut,     查找表(与输入图像通道数相同)
OutputArray dst   输出图像
);
// 定义灰度图 像素映射关系表
void generator_lutdata_U1(uchar* lutdata) {
	for (int i = 0; i < 256; i++) {
		if (i < 128) { lutdata[i] = 0; }
		else if (i > 128 && i<200) { lutdata[i] = 128; }
		else { lutdata[i] = 255; }
	}
}

// 定义BGR图 像素映射关系表
void generator_lutdata_U3(uchar* lutdata_U3) {
	for (int i = 0; i < 256; i++){
		if (i <= 100){
			lutdata_U3[i * 3] = 0;
			lutdata_U3[i * 3 + 1] = 50;
			lutdata_U3[i * 3 + 2] = 50;
		}
		if (i > 100 && i <= 200){
			lutdata_U3[i * 3] = 100;
			lutdata_U3[i * 3 + 1] = 10;
			lutdata_U3[i * 3 + 2] = 200;
		}
		if (i > 200){
			lutdata_U3[i * 3] = 255;
			lutdata_U3[i * 3 + 1] = 200;
			lutdata_U3[i * 3 + 2] = 100;
		}
	}
}



void QuickDemo::LUT_Demo(Mat& image) {
	// 单通道映射
	Mat gray_img, dst;
	cvtColor(image, gray_img, COLOR_BGR2GRAY);

	uchar lutdata[256] = {0};
	generator_lutdata_U1(lutdata);
	Mat lut(1, 256, CV_8UC1, lutdata);
	LUT(gray_img, lut, dst);
	imshow("gray_img", gray_img);
	imshow("dst", dst);

	// 3通道映射
	Mat dst_u3;

	uchar lutdata_U3[256 * 3] = {0};
	generator_lutdata_U3(lutdata_U3);
	Mat lut_U3(1, 256, CV_8UC3, lutdata_U3);
	LUT(image, lut_U3, dst_u3);
	imshow("dst_u3", dst_u3);
}

在这里插入图片描述

鸣谢:
伪色彩:https://blog.csdn.net/jningwei/article/details/78803669
关于像素访问速度比较1:https://blog.csdn.net/xiaowei_cqu/article/details/7771760

OpenCVC++中,透视变换(Perspective Transform)是一种图像处理技术,用于将一个图像从一种几何投影变换到另一种。当你需要对图像中的矩形区域进行等比例缩放、拉伸或者旋转时,透视变换非常有用。透视变换通常涉及到四个关键点,也称为“源”点和它们对应的“目标”点,用来定义变换矩阵。 创建一个查找表(Look-up Table,LUT),在这个场景下,通常是用来存储映射后的像素颜色值。这里我们假设你想保存源点到目标点的变换结果,以便于快速查询。以下是基本的代码范例: ```cpp #include <opencv2/opencv.hpp> // 假设src_points是4x2数组,存放源图像中的四个角点 cv::Point2f src_points[4]; // 目标图像的对应角点 cv::Point2f dst_points[4]; // 创建透视变换矩阵 cv::Mat perspectiveTransform = cv::getPerspectiveTransform(src_points, dst_points); // 定义lut大小,比如500x500表示一个500*500的小图,每个像素代表原图的一个像素 int lutSize = 500; cv::Mat lut(lutSize, lutSize, CV_8UC3); // 使用uchar3作为颜色分量 for (int x = 0; x < lutSize; ++x) { for (int y = 0; y < lutSize; ++y) { float srcX = (float)x / lutSize * (src_points[0].x - src_points[2].x) + src_points[2].x; float srcY = (float)y / lutSize * (src_points[3].y - src_points[1].y) + src_points[1].y; // 应用透视变换到源坐标 cv::Point2f transformedPoint = cv::perspectiveTransform(cv::Mat(1, 1, CV_32FC2, {srcX, srcY}), perspectiveTransform); // 将transformedPoint转换回图像索引并获取颜色 int targetX = cvRound(transformedPoint.x); int targetY = cvRound(transformedPoint.y); cv::Vec3b color = img.at<cv::Vec3b>(targetY, targetX); // 假设img是输入图像 // 将颜色值存入lut lut.at<cv::Vec3b>(y, x) = color; } } // 现在lut是一个映射表,可以用于查找源点坐标映射到的目标像素颜色 ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SongpingWang

你的鼓励是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值