我正在尝试使用此公式将灰度图像颜色从256减少到4 来自http://docs.opencv.org/2.4/doc/tutorials/core/how_to_scan_images/how_to_scan_images.html
我假设n是缩减因子,对于这种情况,它将是公式中的10种颜色。 我的代码如下。
void Reduction(Mat image1)
{
for (int r = 0;r < image1.rows;r++) {
for (int c = 0;c < image1.cols;c++) {
// get pixel
int tmp = (image1.at<Vec3b>(r, c)[0] + image1.at<Vec3b>(r, c)[1] + image1.at<Vec3b>(r, c)[2])/3 ;
tmp = (tmp/4)* 4;
image1.at<Vec3b>(r, c)[0] = tmp;
image1.at<Vec3b>(r, c)[1] = tmp;
image1.at<Vec3b>(r, c)[2] = tmp;
}
}
}
但是来自tmp =(tmp / 4)* 4;或tmp =(tmp / 8)* 8;
然后我尝试将其更改为tmp =(tmp / 40)* 40;
该公式如何运作以及我应该从我的代码中编辑哪些内容以准确获取我想要的结果? (如上面的预期结果)
答案 0 :(得分:2)
这是一种颜色量化。这是依赖于整数除法
的图像中reduce the number of colors的简单技术由于起始范围的值为256
,如果您希望以N
颜色结束,则需要整数除法,然后乘以K = 256 / N
因此,在您的情况下,N=8
需要K = 256 / 8 = 32
,而N = 4
需要K = 256 / 4 = 64
。
答案 1 :(得分:2)
使用您给出的公式的变体,您将无法在“预期结果”图像中获得4色图像,因为整数除法总是向下舍入。它产生了这个结果:
input output
0-63 0
64-127 64
128-191 128
192-255 192
因此,图像中的任何像素都不会超过全亮度的3/4(浅灰色),并且目标图像包含纯白色。
简单舍入到范围的中点也不会起作用,因为目标图像包含纯黑色和纯白色,因此对于黑色,您需要始终向下舍入而对于白色,您需要始终舍入起来。
您可能还希望将256色范围均匀地划分为4个相等的部分,如果您进行简单的舍入,这将无效,因为黑色和白色最终会被较小的范围覆盖。
它有助于完全阻止您希望范围划分的方式。例如,假设您要将其分成4,然后创建一个均匀间隔的范围,包括白色和黑色:
input output
0-63 0
64-127 85
128-191 170
192-255 255
您可以在绘画应用程序中打开预期的结果图像,并使用滴管工具验证这些是正确的输出值。
这个公式是:
int new_value = (value / 64) * 85;
或者更一般地说:
int num_colors = 4;
int divisor = 256 / num_colors;
int max_quantized_value = 255 / divisor;
int new_value = ((value / divisor) * 255) / max_quantized_value;
通过这种方式,您可以保证最小new_value为0,最大new_value为255.
答案 2 :(得分:1)
Another way to look at color quantization is to think of bits/pixel. Normally a grayscale image is stored using 8-bits for each pixel, hence the resulting range of values are from 0 to 255.
We can reduce the number of colors in an image by quantizing or in other words dropping the Least Significant Bits (LSBs). An 8-bit representation normally looks like this:
V V V V V V V V
When reduced we can drop the LSBs for example:
V V V V V V x x
or
V V V V x x x x
where V represents a binary value and x shows bits that are dropped. In your case you want to reduce to 4 colors which means that you only need two bits to represent your image. In that case each byte will look like this:
V V x x x x x x
This can be done simply by using left shift operator >>
on the uchar
values in a grayscale image (as shown in the attached answer).