目前一些相机和美颜滤镜算法使用的是3dlut,通过颜色 映射来达到滤镜 美肤的目的,因此生成的像素需要查找调整好的颜色表。opencv 官方文档强烈推荐使用LUT函数来进行。
原型:
void LUT(InputArray src, InputArray lut, OutputArray dst);
src:目标图像,可以是单通道也可以是多通道
lut:映射表格,当src为单时,必须为单;当src为多通道时,lut可单 也可以多通道,为单通道意思是src 多通道共用一个lut,多通道时,则各自对应着用。
dst:输出图像
查表方法: src 中像素值 r、g、b 的值变成 lut中data[r]、data[g]、data[b]的值
下面给出一个例子:将图片logo的3通道颜色 压缩为原来30倍数,0-255 变成0,30,60.....,可发现 lut三个通道 和 单通道得到结果一样。
int main()
{
int divideWidth = 30;
uchar table1[256];
uchar table3[256*3];
for (int i = 0; i < 256; ++i) {
table1[i] = divideWidth * (i / divideWidth);
}
for (int i = 0; i < 256; ++i) {
table3[i * 3] = divideWidth * (i / divideWidth);
table3[i * 3 + 1] = divideWidth * (i / divideWidth);
table3[i * 3 + 2] = divideWidth * (i / divideWidth);
}
// 创建Mat 类型的 lookupTable
Mat lookupTable1(1, 256, CV_8U, table1);
Mat lookupTable3(1, 256, CV_8UC3, table3);
/*uchar *p = lookupTable.data;
for (int i = 0; i < 256; i++) {
p[i] = table[i];
}*/
Mat logo = imread("images/logo.jpg" );
Mat logo2, logo3 ;
LUT(logo, lookupTable1, logo2);
LUT(logo, lookupTable3, logo3);
imshow("logo" , logo);
imshow("logo2" , logo2);
imshow("logo3" , logo3);
waitKey(0);
return 0;
}