使用lut图来替换lena图里的像素
简单的来讲就是把lut图里的像素值x通过映射到图片lena中的像素值y
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main(int argc, const char *argv[])
{
//读取原图像,1b代表1个通道,0代表灰度图像
Mat1b src = imread("E:\\vs2017\\lut\\lena.jpg", 0);
//读取色彩表 3b代表RGB三个通道
Mat3b lut = imread("lut.bmp");
//输出lut的行和列
std::cout << "lut.size():" << lut.size() << std::endl;
if (src.empty())
{
printf("could not load image...\n");
return -1;
}
//.ptr<uchar>()获取像素值的函数 *imptr 指向像素值的指针
uchar* imptr = src.ptr<uchar>(0);
int pixSZ = src.size().area();
//获取原图像像素值最大的值(例如0-255)
int maxV = std::numeric_limits<int>::min();
int minV = std::numeric_limits<int>::max();
//获取映射图像像素值最大的值(例如0-255)
int normMin = 0;
int normMax = lut.rows - 1;
for (int p = 0; p < pixSZ; p++)
{
if (imptr[p] > maxV) maxV = imptr[p];
if (imptr[p] < minV) minV = imptr[p];
}
//映射y=kx+b
//得到k和b
float k = (float)(normMax - normMin) / (maxV - minV);
float b = normMin - k * minV;
cv::Mat3b color(src.size());
cv::Vec3b* cPtr = color.ptr<cv::Vec3b>(0);
for (int p = 0; p < pixSZ; p++)
{
int index = (int)(k* (imptr[p]) + b);
cPtr[p][0] = lut(index, 0)[0];
cPtr[p][1] = lut(index, 0)[1];
cPtr[p][2] = lut(index, 0)[2];
}
imshow("Color", color);
waitKey(0);
return 0;
}
#include <opencv2/opencv.hpp>
using namespace cv;
int main()
{
Mat grayImg = cv::imread("E:/vs2017/lut/lena.jpg", 0);
//imshow("原图", grayImg);
Mat R = grayImg.clone();
Mat G = grayImg.clone();
Mat B = grayImg.clone();
int rows = grayImg.rows;
int cols = grayImg.cols;
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
int current = grayImg.at<uchar>(i, j);
if (0 < current && current <= 64)
{
R.at<uchar>(i, j) = 0;
G.at<uchar>(i, j) = 4 * current;
B.at<uchar>(i, j) = 255;
}
else if (64 < current && current <= 128)
{
R.at<uchar>(i, j) = 0;
G.at<uchar>(i, j) = 255;
B.at<uchar>(i, j) = -4 * (current - 64) + 255;
}
else if (128 < current && current <= 192)
{
R.at<uchar>(i, j) = 4 * (current - 128);
G.at<uchar>(i, j) = 255;
B.at<uchar>(i, j) = 0;
}
else
{
R.at<uchar>(i, j) = 255;
G.at<uchar>(i, j) = -4 * (current - 255);
B.at<uchar>(i, j) = 0;
}
}
}
Mat channels[3]; //定义对象数组,分别存储三个通道
Mat pseuMat; //融合三个通道,存储在一个Mat里
channels[0] = B;
channels[1] = G;
channels[2] = R;
merge(channels, 3, pseuMat);
imshow("效果图", pseuMat);
waitKey(0);
return 0;
}
颜色空间减缩后图
#include<iostream>
#include<opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int main()
{
//建立一个查找表
int table[256];
int div = 50;
for (int i = 0; i < 256; i++)
{
table[i] = i / div * div;
}
Mat lut(1, 256, CV_8U);
//为Mat矩阵添加元素值
uchar *p = lut.data;
for (int i = 0; i < 256; i++)
{
p[i] = table[i];
}
Mat srcImage = imread("E:\\vs2017\\lut\\lena.jpg");
Mat dstImage;
dstImage.create(srcImage.size(), srcImage.type());
//查找表操作
LUT(srcImage, lut, dstImage);
imshow("[原图]", srcImage);
imshow("[颜色空间减缩后图]", dstImage);
waitKey(0);
return 0;
}