- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
所以我正在浏览 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/
我有一个关于 JavaScript 语法的问题。实际上,我在自学 MEAN 堆栈教程时想出了编码(https://thinkster.io/mean-stack-tutorial#adding-aut
在我的书中它使用了这样的东西: for($ARGV[0]) { Expression && do { print "..."; last; }; ... } for 循环不完整吗?另外,do 的意义何
我已经编写了读取开关状态的代码,如果按 3 次 # 则退出。 void allkeypadTest(void) { static uint8_t modeKeyCount=0; do
因此,对于上周我必须做的作业,我必须使用 4 个 do-while 循环和 if 语句在 Java 中制作一个猜谜游戏。我无法成功完成它,类(class)已经继续,没有为我提供任何帮助。如果有人可以查
int i=1,j=0,n=10,k; do{ j+=i; i<<1; printf("%d\n",i); // printf("%d\n",12<<1); }while
此代码用于基本杂货计算器的按钮。当我按下按钮时,一个输入对话框会显示您输入商品价格的位置。我遇到的问题是我无法弄清楚如何获得 do ... while 循环以使输入对话框在输入后弹出。 我希望它始终恢
当我在循环中修改字符串或另一个变量时,它的条件是否每次都重新计算?或者在循环开始前一次 std::string a("aa"); do { a = "aaaa"; } while(a.size<10)
我刚刚写了这个,但我找不到问题。我使用代码块并编写了这个问题 error: expected 'while' before '{' token === Build finished: 1 errors
do { printf("Enter number (0-6): ", ""); scanf("%d", &Num); }while(Num >= 0 && Num 表示“超过”,<表
我有一个包含 10 个项目的 vector (为简单起见,所有项目都属于同一类,称其为“a”)。我想要做的是检查“A”不是 a) 隐藏墙壁或 b) 隐藏另一个“A”。我有一个碰撞函数可以做到这一点。
嗨,这是我的第二个问题。我有下表 |-----|-------|------|------| |._id.|..INFO.|.DONE.|.LAST.| |..1..|...A...|...N..|.
这个问题在这里已经有了答案: 关闭 12 年前。 Possible Duplicates: Why are there sometimes meaningless do/while and if/e
来自 wikibook在 F# 上有一小部分它说: What does let! do?# let! runs an async object on its own thread, then it i
我在 Real World Haskell 书中遇到了以下函数: namesMatching pat | not (isPattern pat) = do exists do
我有一个类似于下面的用例,我创建了多个图并使用 gridExtra 将它们排列到一些页面布局中,最后使用 ggsave 将其保存为 PDF : p1 % mutate(label2
当我使用具有 for 循环的嵌套 let 语句时,如果没有 (do (html5 ..)),我将无法运行内部 [:tr]。 (defpartial column-settings-layout [&
执行 vagrant up 时出现此错误: anr@anr-Lenovo-G505s ~ $ vagrant up Bringing machine 'default' up with 'virtua
# ################################################# # Subroutine to add data to the table Blas
我想创建一个检查特定日期格式的读取主机。此外,目标是检查用户输入是否正确,如果不正确,则提示应再次弹出。 当我刚接触编程时,发现了这段代码,这似乎很合适。我仍然在努力“直到” do {
我关注这个tutorial在谷歌云机器学习引擎上进行培训。我一步一步地跟着它,但是在将 ml 作业提交到云时我遇到了错误。我运行了这个命令。 sam@sam-VirtualBox:~/models/r
我是一名优秀的程序员,十分优秀!