NDE*_*hos 5 c++ algorithm opencv image-processing
所以我正在阅读Robert Laganiere的"OpenCV 2计算机视觉应用程序编程手册".在第42页左右,它讨论的是图像缩减算法.我理解算法(我认为),但我不明白为什么要放入一个部分.我想我知道为什么,但如果我错了,我想纠正.我将在这里复制并粘贴一点:
"彩色图像由3通道像素组成.这些通道中的每一个都对应于三原色之一(红色,绿色,蓝色)的强度值.由于这些值中的每一个都是8位无符号字符,因此总数颜色数量是256x256x256,超过1600万种颜色.因此,为了降低分析的复杂性,减少图像中的颜色数量有时是有用的.实现这一目标的一个简单方法是简单地细分将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 ---------------
}}}
Run Code Online (Sandbox Code Playgroud)
所以我得到了如何通过div量减少0:255像素值.然后我失去剩下的剩余物.然后再将它乘以div值,我们将其缩放回来以使其保持在0:255的范围内.为什么我们再添加(div/2)回答答案?我能想到的唯一原因是这会导致一些值向下舍入,一些值向上舍入.如果您不使用它,那么所有值都会向下舍入.所以在某种程度上它给出了"更好"的平均值?
不知道,所以你们/女孩们怎么想?
说明这一点的最简单方法是使用一个例子.
为简单起见,假设我们正在处理图像的单个通道.有256种不同的颜色,范围从0到255.在我们的例子中我们也将使用N = 64.
使用这些数字,我们将颜色数量从256减少到256/64 = 4.让我们绘制颜色空间的图形:
|......|......|......|......|
0 63 127 191 255
Run Code Online (Sandbox Code Playgroud)
虚线表示我们的色彩空间,从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
Run Code Online (Sandbox Code Playgroud)
如您所见,第一部分的所有颜色都变为0,第二部分的所有颜色变为64,第三部分128,第四部分192.所以我们的颜色空间如下所示:
|......|......|......|......|
0 63 127 191 255
|______/|_____/|_____/|_____/
| | | |
0 64 128 192
Run Code Online (Sandbox Code Playgroud)
但这不是很有用.你可以看到我们所有的颜色都倾斜到间隔的左边.如果他们处于间隔的中间会更有帮助.这就是我们增加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
Run Code Online (Sandbox Code Playgroud)
间隔看起来像这样:
|......|......|......|......|
0 63 127 191 255
\______/\_____/\_____/\_____/
| | | |
32 96 160 224
Run Code Online (Sandbox Code Playgroud)
这是一种更好的色彩还原.该算法将我们的色彩空间从256色减少到4色,这些色彩位于它们减少的间隔的中间.