LUT查找表
一、引言
存在的意义:
在OpenCV中,LUT代表查找表(Lookup Table),它是一种用于像素值映射的技术。查找表是一个数组,其中每个元素对应于输入像素值的一个映射值。使用LUT可以有效地对图像进行像素值的转换,常用于颜色空间转换或者对特定像素值进行操作。
LUT通常在需要将图像像素值映射到其他值域时使用,例如将灰度图像转换为伪彩色图像。通过定义一个映射表,可以将原始图像中的每个像素值映射到新的颜色或灰度值,从而实现不同的效果。
而二值化阈值化(Thresholding)是另一种常见的图像处理技术,它将灰度图像转换为二值图像(只有两个像素值,通常是黑色和白色)。二值化是根据阈值将灰度图像中的像素值分成两个类别,通常是将低于阈值的像素设为一个值(例如0),高于阈值的像素设为另一个值(例如255)。二值化通常用于图像分割、边缘检测等应用中。
因此,LUT主要用于对图像像素值进行映射,从而实现颜色空间转换等操作,而二值化阈值化则用于将灰度图像转换为二值图像。两者的主要区别在于处理的目标和操作方式。
都是阈值分割和阈值shreshold有什么区别?
阈值shreshold只能将图片全局按照一个阈值进行映射,LUT可以按照自己设置的阈值范围进行映射
兼容了shreshold的二值化,但是可以多阈值划分。不仅仅可以应用于0-255像素值。
原理:映射
灰度值低于100映射为0,大于100小鱼253的映射为1,其余映射为2
比如一个灰度图像,其本质就是一个像素矩阵,我将其每一个像素的灰度值与我的映射矩阵进行比较,如果灰度值为150,则将其映射为1
如果此处还不明白,请见实操部分
二、代码源码
void::cv::LUT( InputArray src,
InputArray lut,
OutputArray dst
)
-
src:输入矩阵,其数据类型只能是CV_8U
-
lut:256个灰度值的查找表,只能是单通道或者与src通道数相同(src3通道,lut不能是2通道,只能是1或者3通道,由此可见其是一个n*256的矩阵
-
dst:输出图像矩阵,其尺寸与src相同,但是数据类型和lut相同(因为src经过lut映射后,输出的dst其像素矩阵值只能是我们规定好的值,如图1的0/1/2)
如果src是三通道,lut是单通道。则是将三通道分离后每个通道单独与lut进行映射后再复合在一起,输出一个图像矩阵
如果src是三通道,lut是三通道。则是两两对应的通道进行映射,对应三个图像矩阵映射后复合在一起(src的R和lut的R映射、src的G和lut的G映射、src的B和lut的B映射)
三、实操
原图:
#include<opencv2/opencv.hpp>
#include<iostream>
#include<vector>
using namespace std;
using namespace cv;
int main()
{
Mat img = imread("E://学习//OPEN-CV学习//lena.png");
if (img.empty())
{
cout << "读取失败!" << endl;
return -1;
}
uchar Lutfirst[256];
//lut矩阵的第一个通道的数组值
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矩阵
Mat lutOne(1, 256, CV_8U, Lutfirst);
//lut矩阵的第二个通道的数组值
uchar Lutsecond[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矩阵
Mat lutTwo(1, 256, CV_8U, Lutsecond);
//lut矩阵的第三个通道的数组值
uchar Lutthrid[256];
for (int i = 0; i < 256; i++)
{
if (i <= 100)
{
Lutfirst[i] = 100;
}
if (i > 100 && i <= 200)
{
Lutfirst[i] = 200;
}
if (i > 200)
{
Lutfirst[i] = 255;
}
}
//通过数组的方式构造Mat矩阵
Mat lutThree(1, 256, CV_8U, Lutthrid);
vector<Mat> mergeMats;
mergeMats.push_back(lutOne);
mergeMats.push_back(lutTwo);
mergeMats.push_back(lutThree);
Mat mergeTree;
merge(mergeMats, mergeTree);
Mat out_three,img_one,gary,gary_one;
//原图与单通道进行映射
LUT(img, lutOne, img_one);
//原图与多通道进行映射
LUT(img, mergeTree, out_three);
imshow("out_three", out_three);
imshow("out_three", img_one);
//灰度图与单通道进行映射
cvtColor(img, gary, COLOR_BGR2GRAY);
LUT(gary, lutOne, gary_one);
waitKey(0);
return 0;
}
}
生成的三个lut(1*256)矩阵和(3 *256)mergeTree映射矩阵,一个长条形的图像,从长条最左端到最右端代表了0-255
其不同的颜色就代表了映射不同的值
左图为转换为的单通道灰度图,右图为和lutOne映射矩阵映射后的图像
例子:
左图为原灰度值图像的截取一部分的像素矩阵图,灰度值高于100的将其映射为灰度值200,原灰度值低于100的将其灰度值映射为100(映射矩阵为实操代码中的lutOne)
左图为原图和lutOne映射矩阵映射后的图像,右图为原图(三通道)和mergeTree(三通道映射矩阵)映射后的结果图
四、使用时机
选择使用LUT还是二值化阈值化方法取决于你希望实现的图像处理目标。下面是一些指导原则,可以帮助你确定使用哪种方法:
使用LUT:
-
颜色空间转换:如果你需要将图像从一种颜色空间(如RGB)转换为另一种颜色空间(如HSV、Lab等),可以使用LUT来实现。
-
伪彩色图像:如果你希望将灰度图像转换为伪彩色图像,其中不同的灰度值映射到不同的颜色,你可以使用LUT来进行映射。
使用二值化阈值化:
-
图像分割:如果你需要将图像分成具有明显区别的目标和背景,二值化阈值化是一种常用的方法。通过选择合适的阈值,你可以将目标与背景分离开。
-
边缘检测:在某些情况下,你可能对图像中的边缘感兴趣。通过将图像转换为二值图像,边缘将以明显的黑白边界显示出来。文章来源:https://www.toymoban.com/news/detail-739297.html
此外,还可以根据具体的图像内容和处理需求来决定使用哪种方法。在实际应用中,可以尝试不同的方法,并根据结果进行评估和调整,以达到最佳效果。文章来源地址https://www.toymoban.com/news/detail-739297.html
到了这里,关于【C++ OpenCV】LUT查找表原理、实操、使用时机的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!