opencv#17 LUT查找表

在对图像进行二值化时,将图像的像素与单一的阈值进行比较,从而区分出像素是大于阈值还是小于阈值,这个阈值只能是作用在全局,或者是局部的唯一阈值,如果想将0~255之间所有的像素分割成0,125,255这三个数据,通过阈值化处理是没办法实现的。

通过LUT查找表可以实现在0~255之间任意的划分。

简单的说LUT查找表可以看成是简单的线性映射,首先规定映射规则,然后将所有像素根据此规则进行映射。

比如下图在0~99全定义为0,100~252定义为1,253~255定义为2。

通过这种方式不仅可以实现二值化,也可以实现多值化。这种映射关系不仅仅限于CV_8U类型,也可以运用于其它数据类型。

LUT查找表函数()

vodi cv::LUT(InputArray    src,
             InputArray    lut,
             OutputArray   dst
            )

·src:输入图像矩阵,其数据类型只能是CV_8U(opencv中定义函数要求0~255,但是映射关系不限于0~255)。

·lut:256个像素灰度值的查找表,单通道或者与src通道数相同。如果输入的图像是多通道,而查找表是单通道,那么会对每一个通道分别进行 映射,在映射之后重新组成新的图像;如果是多通道的图像,输入多通道的查找表中,那么就是每一个通道对应一个通道的查找表,从而进行映射再次组成一个新的图像。

· dst:输出图像矩阵,其尺寸与src相同,数据类型与lut相同。数据类型不与原图像相同,因为这是是一个映射关系,我们可以将这个0~255映射为0~1,甚至可以映射为0~10000,这样的数据是映射后的数据,它需要与映射之后的数据类型保持相同,映射之后的数据类型就是LUT查找表中的数据类型。

在输入时注意,第二个参数一定要是256个像素灰度值图像,也就是我们在输入它的时候要输入一个Mat类型的变量,这个变量中,存入的是1*256个数据,每一个数据代表着灰度值的映射关系。

示例

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv; //opencv的命名空间
using namespace std;

int main()
{
	//LUT查找表第一层
	uchar lutFirst[256];
	for (int i = 0; i < 256; i++)
	{
		if (i <= 100)
			lutFirst[i] = 0;
		if (i > 100 && i <= 200)
			lutFirst[i] = 100;
		if (i > 200)
			lutFirst[i] = 255;
	}
	Mat lutOne(1, 256, CV_8UC1, lutFirst);

	//LUT查找表第二层
	uchar lutSecond[256];
	for (int i = 0; i < 256; i++)
	{
		if (i <= 100)
			lutSecond[i] = 0;
		if (i > 100 && i <= 150)
			lutSecond[i] = 100;
		if (i > 150 && i <= 200)
			lutSecond[i] = 150;
		if (i > 200)
			lutSecond[i] = 255;
	}
	Mat lutTwo(1, 256, CV_8UC1, lutSecond);

	//LUT查找表第三层
	uchar lutThird[256];
	for (int i = 0; i < 256; i++)
	{
		if (i <= 100)
			lutThird[i] = 100;
		if (i > 100 && i <= 200)
			lutThird[i] = 200;
		if (i > 200)
			lutThird[i] = 255;
	}
	Mat lutThree(1, 256, CV_8UC1, lutThird);

	//拥有三通道的LUT查找表矩阵
	vector<Mat> mergeMats; //生成多通道向量
	mergeMats.push_back(lutOne); 
	mergeMats.push_back(lutTwo);
	mergeMats.push_back(lutThree);
	Mat lutTree; //生成多通道图像
	merge(mergeMats, lutTree); //多通道合并函数

	//计算图像的查找表
	Mat img = imread("E:/opencv/opencv-4.6.0-vc14_vc15/opencv/lenac.png");
	if (img.empty())
	{
		cout << "请确认图像文件名称是否正确" << endl;
		return -1;
	}
	Mat gray, out0, out1, out2;
	cvtColor(img, gray, COLOR_BGR2GRAY); //灰度图,单通道
	LUT(gray, lutOne, out0); //将第一个查找表与灰度图映射
	LUT(img, lutOne, out1); //将第一个查找表与彩色图映射
	LUT(img, lutTree, out2); //将多通道查找表与彩色图映射
	imshow("out0", out0);
	imshow("out1", out1);

	waitKey(0);
	return 0;

}

 结果

自己运行就知道了,懒得截图了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值