首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么这个“减缩因子”要做"+ div/2“?

为什么这个“减缩因子”要做"+ div/2“?
EN

Stack Overflow用户
提问于 2014-05-28 19:07:46
回答 2查看 342关注 0票数 5

因此,我正在运行的"OpenCV 2计算机视觉应用程序编程手册“由罗伯特拉加尼尔。在第42页,它讨论的是一种图像约简算法。我理解算法(我认为),但我不明白为什么要放一个部分。我想我知道为什么,但如果我错了,我想纠正。我要在这里复制并粘贴一点:

“彩色图像由3通道像素组成。每个通道对应三种原色(红色、绿色、蓝色)之一的强度值。由于每个值都是8位的无符号字符,因此颜色总数为256x256x256,超过1600万种颜色。因此,为了降低分析的复杂性,有时减少图像中的颜色数量是有用的。实现这一目标的一个简单方法是简单地将RGB空间细分为大小相等的多维数据集。例如,如果将每个维度中的颜色数量减少8,那么您将得到总共32x32x32颜色。然后,将原始图像中的每一种颜色分配给颜色缩减图像中的新颜色值,该颜色值对应于其所属的立方体中心的值。因此,基本的色彩约简算法是简单的。如果N是约简因子,那么对于图像中的每个像素和该像素的每个通道,将该值除以N(整数除法,因此将丢失提醒)。然后将结果乘以N,这将给出N的倍数,正好低于输入像素值。只要添加N/2,就可以得到N的两个相邻倍数之间间隔的中心位置。如果您对每个8位信道值重复这个过程,那么您将得到总共256/N 256/N256/N可能的颜色值。怎么做..。我们的色彩缩减功能的签名如下: void colorReduce(cv::Mat &div=64,int div=64);用户提供图像和每个通道的缩减因子。这里,处理是就地进行的,即输入图像的像素值由函数修改。看还有更多的..。本节中有一个更通用的函数签名,其中包含输入和输出参数。处理过程只需创建一个遍历所有像素值的双循环:“

代码语言:javascript
复制
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)加回到答案中呢?,我认为这会导致一些值被四舍五入,而另一些值会被舍入。如果不使用它,那么所有的值都会四舍五入。所以,在某种程度上,这是一个“更好”的平均值?

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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-05-28 20:05:50

它是为了给出一个平均的量化界,而不是它的地板。例如,对于N= 32,从0到31的所有数据都将给出16而不是0。

请检查以下图片或我的excel文件

票数 3
EN

Stack Overflow用户

发布于 2014-05-28 19:46:47

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

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

使用这些数字,我们将把颜色从256减少到256/64 = 4。

代码语言:javascript
复制
|......|......|......|......| 
0      63    127    191    255

虚线表示我们的颜色空间,从0到255。我们把这个区间分成四个部分,分裂用垂直线表示。

为了将256种颜色减少到4种颜色,我们将每种颜色除以64 (失去剩余的颜色),然后再乘以64。让我们看看这是如何进行的:

代码语言:javascript
复制
[0  , 63 ] / 64 * 64 = 0
[64 , 127] / 64 * 64 = 64
[128, 191] / 64 * 64 = 128
[192, 255] / 64 * 64 = 192

正如你所看到的,第一部分的所有颜色都变成0,第二部分的所有颜色变成64,第三部分128,第四部分192。我们的颜色空间是这样的:

代码语言:javascript
复制
|......|......|......|......| 
0      63    127    191    255
|______/|_____/|_____/|_____/ 
|       |      |      |
0       64     128    192

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

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

代码语言:javascript
复制
[0  , 63 ] / 64 * 64 + 32 = 32
[64 , 127] / 64 * 64 + 32 = 96
[128, 191] / 64 * 64 + 32 = 160
[192, 255] / 64 * 64 + 32 = 224

时间间隔是这样的:

代码语言:javascript
复制
|......|......|......|......| 
0      63    127    191    255
\______/\_____/\_____/\_____/ 
   |       |      |      |
   32      96    160    224

这是一个更好的减色。该算法将我们的颜色空间从256种颜色减少到4种颜色,而这些颜色是在它们减少的间隔的中间。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23919916

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档