gpt4 book ai didi

c++ - 为什么这个 "reduction factor"算法在做 "+ div/2"

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:07:25 27 4
gpt4 key购买 nike

所以我正在浏览 Robert Laganiere 的“OpenCV 2 计算机视觉应用程序编程指南”。在第 42 页左右,它正在谈论一种图像缩小算法。我理解算法(我认为)但我不明白为什么要放入一个部分。我想我知道为什么但如果我错了我想纠正。我将在此处复制并粘贴其中的一些内容:

"Color images are composed of 3-channel pixels. Each of these channels corresponds to the intensity value of one of the three primary colors (red, green, blue). Since each of these values is an 8-bit unsigned char, the total number of colors is 256x256x256, which is more than 16 million colors. Consequently, to reduce the complexity of an analysis, it is sometimes useful to reduce the number of colors in an image. One simple way to achieve this goal is to simply subdivide the RGB space into cubes of equal sizes. For example, if you reduce the number of colors in each dimension by 8, then you would obtain a total of 32x32x32 colors. Each color in the original image is then assigned a new color value in the color-reduced image that corresponds to the value in the center of the cube to which it belongs. Therefore, the basic color reduction algorithm is simple. If N is the reduction factor, then for each pixel in the image and for each channel of this pixel, divide the value by N (integer division, therefore the reminder is lost). Then multiply the result by N, this will give you the multiple of N just below the input pixel value. Just add N/2 and you obtain the central position of the interval between two adjacent multiples of N. if you repeat this process for each 8-bit channel value, then you will obtain a total of 256/N x 256/N x 256/N possible color values. How to do it... The signature of our color reduction function will be as follows: void colorReduce(cv::Mat &image, int div=64); The user provides an image and the per-channel reduction factor. Here, the processing is done in-place, that is the pixel values of the input image are modified by the function. See the There's more... section of this recipe for a more general function signature with input and output arguments. The processing is simply done by creating a double loop that goes over all pixel values: "

void colorReduce(cv::Mat &image, int div=64) {
int nl= image.rows; // number of lines
// total number of elements per line
int nc= image.cols * image.channels();
for (int j=0; j<nl; j++) {
// get the address of row j
uchar* data= image.ptr<uchar>(j);
for (int i=0; i<nc; i++) {
// process each pixel ---------------------
data[i]=
data[i]/div*div + div/2;// <-HERE IS WHERE I NEED UNDERSTANDING!!!
// end of pixel processing ---------------
}}}

所以我明白了如何将 0:255 像素值减少 div 数量。然后我失去了剩下的任何剩余部分。然后再次将它乘以 div 数量,我们将它按比例放大以保持在 0:255 的范围内。 为什么我们然后将 (div/2) 添加回答案? 我能想到的唯一原因是这会导致某些值向下舍入,而某些值向上舍入。如果您不使用它,那么您的所有值都会向下舍入。所以在某种程度上它给出了一个“更好”的平均值?

不知道,你们觉得怎么样?

最佳答案

说明这一点的最简单方法是使用示例。

为简单起见,假设我们正在处理图像的单个 channel 。有 256 种不同的颜色,范围从 0 到 255。我们还将在示例中使用 N=64。

使用这些数字,我们会将颜色的数量从 256 减少到 256/64 = 4。让我们画一个颜色空间图:

|......|......|......|......| 
0 63 127 191 255

虚线表示我们的色彩空间,从 0 到 255。我们将这个区间分成 4 个部分,分割由垂直线表示。

为了将所有 256 种颜色减少为 4 种颜色,我们将每种颜色除以 64(失去余数),然后再乘以 64。让我们看看这是怎么回事:

[0  , 63 ] / 64 * 64 = 0
[64 , 127] / 64 * 64 = 64
[128, 191] / 64 * 64 = 128
[192, 255] / 64 * 64 = 192

如您所见,第一部分的所有颜色变为 0,第二部分的所有颜色变为 64,第三部分 128,第四部分 192。所以我们的颜色空间如下所示:

|......|......|......|......| 
0 63 127 191 255
|______/|_____/|_____/|_____/
| | | |
0 64 128 192

但这不是很有用。你可以看到我们所有的颜色都向间隔的左侧倾斜。如果他们在间隔的中间会更有帮助。这就是我们将 64/2 = 32 添加到值的原因。添加一半的间隔长度会将颜色移动到间隔的中心。书上也是这么说的:“只要加上 N/2,你就得到了 N 的两个相邻倍数之间的间隔的中心位置。”

所以让我们将 32 添加到我们的值中,看看一切看起来如何:

[0  , 63 ] / 64 * 64 + 32 = 32
[64 , 127] / 64 * 64 + 32 = 96
[128, 191] / 64 * 64 + 32 = 160
[192, 255] / 64 * 64 + 32 = 224

间隔看起来像这样:

|......|......|......|......| 
0 63 127 191 255
\______/\_____/\_____/\_____/
| | | |
32 96 160 224

这是一个更好的颜色还原。该算法将我们的色彩空间从 256 种颜色减少到 4 种颜色,并且这些颜色位于它们减少的间隔的中间。

关于c++ - 为什么这个 "reduction factor"算法在做 "+ div/2",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23919916/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com