我想通过执行颜色深度缩放颜色减少。
像这样的例子:
第一图像是CGA分辨率,第二个是EGA,第三是HAM。 我想和CV :: LUT这样做,因为我认为这是做的佰。 我可以用这个代码灰阶做:
Mat img = imread("test1.jpg", 0);
uchar* p;
Mat lookUpTable(1, 256, CV_8U);
p = lookUpTable.data;
for( int i = 0; i < 256; ++i)
p[i] = 16 * (i/16)
LUT(img, lookUpTable, reduced);
原版的:
彩色简化:
但是,如果我试图用颜色做我得到了奇怪的结果..
与此代码:
imgColor = imread("test1.jpg");
Mat reducedColor;
int n = 16;
for (int i=0; i<256; i++) {
uchar value = floor(i/n) * n;
cout << (int)value << endl;
lut.at<Vec3b>(i)[2]= (value >> 16) & 0xff;
lut.at<Vec3b>(i)[1]= (value >> 8) & 0xff;
lut.at<Vec3b>(i)[0]= value & 0xff;
}
LUT(imgColor, lut, reducedColor);
你可能已经被搬到现在的,但问题的根源是,你正在做一个16位移位uchar value
,这仅仅是8位长。 即使在这种情况下,8位移位实在是太多了,因为你会擦除在所有位uchar
。 再有是,这样的事实cv::LUT
文档明确指出src
必须是一个,这显然是不能在代码的情况下“的8位元素的输入数组”。 净结果是,只有彩色图像(蓝色通道)的所述第一信道是由转化的cv::LUT
。
解决这些限制的最佳方式是跨渠道分离的彩色图像,分别变换每个信道,然后合并转化通道进入一个新的彩色图像。 请参见下面的代码:
/*
Calculates a table of 256 assignments with the given number of distinct values.
Values are taken at equal intervals from the ranges [0, 128) and [128, 256),
such that both 0 and 255 are always included in the range.
*/
cv::Mat lookupTable(int levels) {
int factor = 256 / levels;
cv::Mat table(1, 256, CV_8U);
uchar *p = table.data;
for(int i = 0; i < 128; ++i) {
p[i] = factor * (i / factor);
}
for(int i = 128; i < 256; ++i) {
p[i] = factor * (1 + (i / factor)) - 1;
}
return table;
}
/*
Truncates channel levels in the given image to the given number of
equally-spaced values.
Arguments:
image
Input multi-channel image. The specific color space is not
important, as long as all channels are encoded from 0 to 255.
levels
The number of distinct values for the channels of the output
image. Output values are drawn from the range [0, 255] from
the extremes inwards, resulting in a nearly equally-spaced scale
where the smallest and largest values are always 0 and 255.
Returns:
Multi-channel images with values truncated to the specified number of
distinct levels.
*/
cv::Mat colorReduce(const cv::Mat &image, int levels) {
cv::Mat table = lookupTable(levels);
std::vector<cv::Mat> c;
cv::split(image, c);
for (std::vector<cv::Mat>::iterator i = c.begin(), n = c.end(); i != n; ++i) {
cv::Mat &channel = *i;
cv::LUT(channel.clone(), table, channel);
}
cv::Mat reduced;
cv::merge(c, reduced);
return reduced;
}
既i
和n
是整数,因此i/n
是一个整数。 也许你想它转换成(DOUBLE (double)i/n
发言并乘以之前) n
?