【发布时间】:2014-07-18 03:59:39
【问题描述】:
所以我正在阅读 Robert Laganiere 的“OpenCV 2 计算机视觉应用程序编程食谱”。在第 42 页左右,它正在讨论图像缩减算法。我理解算法(我认为),但我不明白为什么要放入一个部分。我想我知道为什么,但如果我错了,我想纠正。我将在这里复制并粘贴一点:
"彩色图像由 3 通道像素组成。每个通道 对应于三基色之一的强度值 (红色、绿色、蓝色)。由于这些值中的每一个都是 8 位无符号 char,颜色总数为256x256x256,大于16 万种颜色。因此,为了降低分析的复杂性, 有时减少图像中的颜色数量很有用。一 实现这个目标的简单方法是简单地细分 RGB 空间 成大小相等的立方体。例如,如果您减少 每个维度的颜色乘以 8,那么您将获得总共 32x32x32 颜色。然后为原始图像中的每种颜色分配一个 减色图像中对应的新颜色值 它所属的立方体中心的值。因此, 基本的颜色减少算法很简单。如果 N 是减少 因子,然后对于图像中的每个像素和每个通道 像素,将值除以 N(整数除法,因此提醒 丢失)。然后将结果乘以 N,这将为您提供 N 的倍数刚好低于输入像素值。只需添加 N/2 即可 获得两个相邻的区间的中心位置 N 的倍数。如果对每个 8 位通道重复此过程 值,那么您将获得总共 256/N x 256/N x 256/N 可能 颜色值。怎么做……我们减色的签名 函数如下: void colorReduce(cv::Mat &image, int div=64);用户提供图像和每个通道的缩减 因素。在这里,处理是就地完成的,即像素 输入图像的值由函数修改。见 还有更多...这个配方的部分用于更通用的功能 带有输入和输出参数的签名。处理很简单 通过创建一个遍历所有像素值的双循环来完成:“
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 ---------------
}}}
所以我知道我是如何通过 div 数量减少 0:255 像素值的。然后我失去了剩下的任何东西。然后通过再次将它乘以 div 数量,我们将其放大以使其保持在 0:255 的范围内。 为什么我们还要在答案中添加 (div/2)? 我能想到的唯一原因是这会导致一些值向下舍入和一些值向上舍入。如果您不使用它,那么您的所有值都会向下舍入。所以在某种程度上它给出了一个“更好”的平均值?
不知道,你们觉得怎么样?
【问题讨论】:
标签: c++ algorithm opencv image-processing