我的目标是能够使用链接 3复制这个OpenCV显示的避障方法,看起来他们提供的软件只适用于OpenCV。我认为使用OpenCV进行复制是可能的。我目前在第二步使用Canny边缘检测。我不知道我可以使用什么函数来创建第3步,在这个步骤3中,图像是从底部填充的,直到检测到边缘。如有任何参考资料,将不胜感激。谢谢。




发布于 2017-07-17 08:08:38
方法0
这是标准的,基于循环的方法来完成这一点。这个想法是从每一列的底部开始,把每个像素都涂成白色,直到一个白色像素被击中。这就是小猪在下面的建议。
h, w = edges.shape[:2]
filled_from_bottom = np.zeros((h, w))
for col in range(w):
for row in reversed(range(h)):
if edges[row][col] < 255: filled_from_bottom[row][col] = 255
else: break方法1
现在,这个方法使用了一些numpy技巧来加速操作。
首先,对于每一列,在边缘图像中有一个非零值的地方,查找最大行索引。
h, w = img.shape[:2]
row_inds = np.indices((h, w))[0] # gives row indices in shape of img
row_inds_at_edges = row_inds.copy()
row_inds_at_edges[edges==0] = 0 # only get indices at edges, 0 elsewhere
max_row_inds = np.amax(row_inds_at_edges, axis=0) # find the max row ind over each col然后,您可以创建一个布尔数组,其中每个大于或等于最大索引的索引都是True。
inds_after_edges = row_inds >= max_row_inds然后,您只需在布尔数组给出的新索引处填充一个新的空白图像就可以了。
filled_from_bottom = np.zeros((h, w))
filled_from_bottom[inds_after_edges] = 255方法2
这种方法的内存效率略高,速度效率略高一些。这是与方法1相同的基本前提。
首先,对于每一列,查找与每列中的最大值相对应的行索引(即边缘图像中的白色颜色)。注意,函数np.argmax将返回数组中最大值的第一个实例,而我们希望得到最后一个实例:
在最大值多次出现的情况下,返回对应于第一次出现的索引。
因此,一个简单的方法是垂直翻转数组,但这给了我们倒转数组的索引。我认为在看到它之后,仅仅解释一下一条龙就更直观了:
h, w = img.shape[:2]
max_row_inds = h - np.argmax(edges[::-1], axis=0)切片[::-1]从上到下反转边缘(也可以使用np.flipud)。然后,由于数组是翻转的,np.argmax从末尾给出索引,所以h - np.argmax将索引赋给正确的定向数组。np.argmax(..., axis=0)的意思是,我们取每列的最大值。
现在,我们可以像前面一样创建布尔数组:
row_inds = np.indices((h, w))[0]
inds_after_edges = row_inds >= max_row_inds这个方法比较好的原因是我们没有创建数组的副本,而是删除了许多值的数组赋值。
速度试验
第一种方法是最简单的,但在Python中是最慢的。Python循环非常慢,而numpy操作通常是用基于C或Fortran的方法实现的,因此它们非常快速。我用以下代码测试了这种差异:
import timeit
times = range(1000)
start_time = timeit.default_timer()
A = [method0(edges) for t in times]
print("method0: ", timeit.default_timer() - start_time)
start_time = timeit.default_timer()
B = [method1(edges) for t in times]
print("method1: ", timeit.default_timer() - start_time)
start_time = timeit.default_timer()
C = [method2(edges) for t in times]
print("method2: ", timeit.default_timer() - start_time)所以每种方法都运行了1000次。结果:
method0: 62.79985192901222
method1: 0.9703722179983743
method2: 0.7760374149947893我们看到,最终的方法是最快的,就像预期的那样;只是比method1快一点,但并不疯狂。然而,基于循环的方法之间的差别是巨大的。
输出

发布于 2017-07-17 07:58:28
这是从图像的底部开始,然后逐个像素进行垂直处理,填充每个空白的黑色像素,直到看到一个非黑色像素为止。然后,填充停止垂直列,并继续进行下一列。
为此,您不需要任何花哨的OpenCV函数。这可以通过简单地使用几个循环来实现。
您可以就地执行此操作,也可以使用单独的输出映像,使用零进行初始化。
您所要做的就是从底部开始对图像的列进行迭代。如果像素的值为零,则将输出像素设置为255,一旦碰到不是零的像素,则将其余像素设置为0(或将其保留为0)
https://stackoverflow.com/questions/45135950
复制相似问题