然而,OpenCV里面已经有了相应函数可以让我们更加方便地对像素进行操作,那便是LUT函数,而且推荐使用OpenCV的内建函数,因为已经针对芯片做了优化设计,使得速度有很大提升。
函数原型为:void LUT(InputArray src, InputArray lut, OutputArray dst)
第一个参数:原始图像的地址;
第二个参数:查找表的地址,对于多通道图像的查找,它可以有一个通道,也可以与原始图像有相同的通道;
第三个参数:输出图像的地址。
实现的映射关系如下所示:
也就是说比如原来src中值为1会映射为table[1]所对应的值再加上d。
所以上面的操作,我们其实只需要使用LUT函数就可以了。结合我们自己设计的table表,就能够实现对图像的操作。
#include <opencv2/opencv.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include<math.h>
using namespace cv;
using namespace std;
int main()
{
string picName="C://1.bmp";
Mat A=imread (picName,CV_LOAD_IMAGE_GRAYSCALE); //读入灰度图像
Mat lookUpLut(1,256,CV_8UC1); //建立一个256个元素的映射表lookUpLut
imshow ("变换前",A);
for (int i=0;i<256;i++)
{
lookUpLut.at<uchar>(i)=i/100*100; //用at操作映射表的像素
}
Mat B;
LUT (A,lookUpLut,B); //LUT查表变换
imshow ("变换后",B);
waitKey (0);
return 0;
}
效果图:
我们得出一些结论: 尽量使用 OpenCV 内置函数. 调用LUT 函数可以获得最快的速度. 这是因为OpenCV库可以通过英特尔线程架构启用多线程,下面的opencv矩阵操作均是优化的多线程并行处理,较高效
结论:其实用查询表来进行图像处理的实质就是:根据源图像(img)中的像素值例如灰度值是78,然后去查询表中去找它对应的是哪个灰度值(对于上面的程序78在查询表中对应的灰度值是0),然后把查询表中78对应的灰度值0赋值给新的图像矩阵(out)中。
上一篇csdn博客:图像反取 https://blog.csdn.net/zqx951102/article/details/83719234
也可以用LUT函数写
代码如下:
#include<iostream>
#include<opencv2/core/core.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/highgui/highgui.hpp>
using namespace std;
using namespace cv;
int main()
{
Mat src=imread("C://1.bmp");
if(!src.data)
{
cout<<"error! The image is not built!"<<endl;
return -1;
}
// 为了演示效果,将图片转换成灰度图片
Mat img1=src;
//cvtColor( src, img1, CV_RGB2GRAY );
imshow("First",img1);
//建立查找表
Mat lookUpLut(1, 256, CV_8U);
for(int i=0; i<256; i++)
{
lookUpLut.at<uchar>(i)=255-i;
}
//通过LUT函数实现图像取反
LUT(img1,lookUpLut,img1);
imshow("Second",img1);
waitKey();
return 0;
}
结果是一样的!