【7】opencv图像LUT查找表
LUT查找表简单来说就是一个像素灰度值的映射表,它以像素灰度值作为索引,以灰度值映射后的数值作为表中的内容。例如我们有一个长度为5的存放字符的数组P [ a , b , c , d , e ] P[a,b,c,d,e]P[a,b,c,d,e] ,LUT查找表就是通过这个数组将0映射成a,将1映射成b,依次类推,其映射关系为P [ 0 ] = a P[0] = aP[0]=a 、P [ 1 ] = b P[1] = b P[1]=b
其实本质上是对图片的像素点映射到另一个处理后的图片,映射是方法就是LUT查找表。
void cv::LUT(InputArray src, InputArray lut, OutputArray dst )
- src:输入图像矩阵,其数据类型只能是CV_8U。
- lut:256个像素灰度值的查找表,单通道或者与src通道数相同。
- dst:输出图像矩阵,其尺寸与src相同,数据类型与lut相同。
关于LUT表(三通道)
我找到了两种构建方法:
1,直接构造大数组,循环赋值
2,利用mat分别构建三个矩阵,用向量的方法,将三个连起来(比较烦)
#include<highgui\highgui.hpp> using namespace cv; int main() { uchar lutData[256 * 3]; int j = 0; for (int i = 0; i < 256; i++) { if (i <= 100) { lutData[i * 3] = 255; lutData[i * 3 + 1] = 50; lutData[i * 3 + 2] = 50; } if (i > 100 && i <= 200) { lutData[i * 3] = 100; lutData[i * 3 + 1] = 10; lutData[i * 3 + 2] = 200; } if (i > 200) { lutData[i * 3] = 255; lutData[i * 3 + 1] = 200; lutData[i * 3 + 2] = 100; } } Mat lut(1, 256, CV_8UC3, lutData); Mat a = imread("002.jpg"); Mat b; namedWindow("anjis", WINDOW_AUTOSIZE); namedWindow("anjis1", WINDOW_AUTOSIZE); imshow("anjis", a); LUT(a, lut, b); imshow("anjis1", b); waitKey(); }
//图像查找表 LUT #include <opencv2\opencv.hpp> #include <iostream> using namespace std; using namespace cv; int main() { //构建LUT查找表第一层,利用uchar类型的数组存储,后来复制到mat类型的lutone中 uchar lutFirst[256]; for (int i = 0; i < 256; i++) { if (i <= 100) lutFirst[i] = 234; if (i > 100 && i <= 200) lutFirst[i] = 255; if (i > 200) lutFirst[i] = 255; } Mat lutOne(1, 256, CV_8UC1, lutFirst); //Unsigned 8bits 一个通道 赋值类型 //LUT查找表第二层 uchar lutSecond[256]; for (int i = 0; i < 256; i++) { if (i <= 100) lutSecond[i] = 255; if (i > 100 && i <= 150) lutSecond[i] = 105; if (i > 150 && i <= 200) lutSecond[i] = 25; 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); //这一步是合并所有通道,形成LUT表(三个通道) //计算图像的查找表 Mat img = imread("0001.jpg"); cv::imshow("origin", img); if (img.empty()) { cout << "请确认图像文件名称是否正确" << endl; return -1; } Mat gray, out0, out1, out2; cvtColor(img, gray, COLOR_BGR2GRAY); //色彩空间转换函数 /* API详解:void cv::cvtColor(cv::InputArray src, // 输入图 cv::OutputArray dst, // 输出图 int code, // 颜色映射类型,可以查表得到,有很多 int dstCn = 0 // 输出的通道数 (0='automatic'),我们可以使用默认值,什么都不写。 */ LUT(gray, lutOne, out0); //实现单通道LUT表对黑白图的处理 LUT(img, lutOne, out1); //实现单通道LUT表对彩图的处理 LUT(img, LutTree, out2);// 实现多通道LUT表对彩图的处理 imshow("out0", out0); imshow("out1", out1); imshow("out2", out2); waitKey(0); return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端