【发布时间】:2018-05-13 17:22:33
【问题描述】:
我得到了一个 200x200 的图像,作为像素的字节数组(每个像素 3 个字节,代表 RGB 值)。我想选择所有边界点,定义为一个非白色的点,并且位于图像的边界上或具有不同颜色的相邻像素。
为此编写了简单的 C 代码:
int i = 0, row = 0, column = 0, width3 = width*3;
char r,g,b;
while (i < length) {
r = pixels[i], g = pixels[i+1], b = pixels[i+2];
if (r != -1 || g != -1 || b != -1) { // Not white
// Check for border point
if (column == 0 || column == width-1 || row == 0 || row == height-1
|| r != pixels[i-3] || r != pixels[i+3] || r != pixels[i-width3] || r != pixels[i+width3]
|| g != pixels[i-2] || g != pixels[i+4] || g != pixels[i-width3+1] || g != pixels[i+width3+1]
|| b != pixels[i-1] || b != pixels[i+5] || b != pixels[i-width3+2] || b != pixels[i+width3+2]) {
// Border point
}
}
i += 3;
if (++column == width) {
column = 0;
row++;
// printf("new row");
}
}
现在我想知道如何尽可能加快速度。 我可以使用 GPU,但从 GPU 到 GPU 的内存传输非常昂贵。
由于我对任何类型的优化技术(例如 openCV 中使用的技术)都是全新的,我想知道是否有任何方法可以让我的 sn-p 更快。
(更多上下文;我想将图像上每个非白色对象的边界点解释为可见对象的“轮廓”,然后使用 Douglas-Peucker 将轮廓近似为多边形)
【问题讨论】:
-
注意
pixels[i-3]和pixels[i+5]不要破坏数组边界。你没有显示i是如何开始的,但你确实显示了i < length。 -
他们不能,因为我第一次检查边界点。
i、row和column从 0 开始并遍历所有字节(一次 3 个字节,对于 RGB 值)。width3是width*3,在 200x200 图像的情况下为 600(我猜应该将所有这些添加到 sn-p 中)。 -
“我可以使用 GPU,但是从 GPU 到 GPU 的内存传输非常昂贵。”肯定不会像在 CPU 中执行整个操作那样昂贵! IIRC 复制到 VRAM 只比普通的
memcpy慢一点。 -
你确定吗? GPU 的问题是我想为每种颜色的单独队列添加边界点,但我不确定如何使用 GPU 来做到这一点(这对所有这些来说都是新事物)。
-
@0x5453 这是否非常适合 GPU 输出边界点列表?我假设输出本质上必须是串行的,就像一个可变大小的 x/y 对列表,否则 CPU 可能不得不做一些昂贵的事情来读回 GPU 输出的任何内容。我是 GPGPU 的新手,但考虑到输出的串行性质,这似乎很尴尬。
标签: c image-processing optimization