OpenCV:灰度色彩还原

时间:2016-10-20 18:13:10

标签: c++ algorithm opencv colors

我正在尝试使用此公式将灰度图像颜色从256减少到4 来自http://docs.opencv.org/2.4/doc/tutorials/core/how_to_scan_images/how_to_scan_images.html enter image description here

我假设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;
    }

    }
}

我的预期结果是enter image description here

但是来自tmp =(tmp / 4)* 4;或tmp =(tmp / 8)* 8;

我的图片与原始图片相同; enter image description here

然后我尝试将其更改为tmp =(tmp / 40)* 40;

enter image description here我得到的结果与我想要的结果类似。

该公式如何运作以及我应该从我的代码中编辑哪些内容以准确获取我想要的结果? (如上面的预期结果)

3 个答案:

答案 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).