简体   繁体   English

python和opencv中的快速组件标签

[英]Fast component labelling in python and opencv

I'm implementing the component labelling algorithm as in this paper using python and opencv. 我作为实施的标记算法本文使用python和OpenCV。 It requires checking the input image pixel-by-pixel and perform the so-called contour tracing subroutine to assign label to the blobs of a binary image. 它要求逐像素检查输入图像,并执行所谓的轮廓跟踪子例程,以将标签分配给二进制图像的斑点。

I manage to have it running, but it seems very slow. 我设法使其运行,但它看起来非常慢。 Profiling the code shows that the for-loop to access the pixels seems to be the bottleneck. 对代码进行性能分析表明,访问像素的for循环似乎是瓶颈。 It takes about 200ms for a 256px*256px image. 256px * 256px的图像大约需要200毫秒。 Here's roughly what I do: 这大致是我的工作:

for i in image.height:
    for j in image.width:
        p = image[i, j]
            pa = image[i - 1, j]
            pb = image[i + 1, j] 
            # etc...

where "image" is a binary opencv image. 其中“ image”是二进制opencv映像。

I wonder if there's a faster way of doing it so that it's usable also for video applications. 我想知道是否有更快的方法可以将其用于视频应用程序。 I'm targeting something like 40-50ms running time for the same problem size, to get 20-25fps. 对于相同的问题大小,我将目标运行时间定为40-50ms,以获得20-25fps。 10-15fps would probably be acceptable as well (66-100ms running time). 10-15fps也可能是可以接受的(运行时间66-100ms)。

Any hints, ideas what I can do is much appreciated. 任何提示,想法我能做的都非常感谢。

Many are the posts I've seen lamenting the lack of OpenCV labeling. 我见过很多帖子,对缺少OpenCV标签感到遗憾。

As @malloc47 said, scipy.ndimage.label will work. 正如@ malloc47所说, scipy.ndimage.label将起作用。 I've used it, but I wasn't happy with its performance while I was looking for the largest blob in an image. 我使用过它,但是当我寻找图像中最大的斑点时,我对它的性能并不满意。 I didn't specifically need a labeling, so I ended up using the cv2.findContours and cv2.contourArea to isolate the largest one: 我并不是特别需要标签,因此最终使用了cv2.findContourscv2.contourArea来隔离最大的标签:

# The [0] is because I didn't care about the hierarchy, which is the second
# return value of cv2.findContours.
contours = cv2.findContours(numpy_array,
                            mode=cv2.RETR_EXTERNAL,
                            method=cv2.CHAIN_APPROX_SIMPLE
                            )[0]

areas = [cv2.contourArea(ctr) for ctr in contours]
max_contour = [contours[areas.index(max(areas))]]

This ended up being a lot faster for me than scipy.ndimage.label for very similar results. 对于我来说,这比scipy.ndimage.label快得多,结果非常相似。 As I said, this isn't exactly a labeling, but one could probably use the contour finder to give a reasonably good labeling. 就像我说的那样,这并非完全是一种标签,但是可能可以使用轮廓查找器给出一个相当好的标签。

The latest OpenCV bindings for Python return numpy data types, meaning you have the full numpy arsenal at your disposal. 适用于Python的最新OpenCV绑定返回numpy数据类型,这意味着您可以使用完整的numpy武库。 Looping over a 2D array in numpy (with indices) is generally done with an ndenumerate , which should offer at least a little speedup (since it's a single loop optimized for ND arrays). 通常使用ndenumerate循环遍历numpy中的2D数组(带有索引),这应该至少提供一点加速(因为它是为ND数组优化的单循环)。 You could look into numpy vectorize which would yield even more speedup, but if you need the indices of the array, then an ndenumerate would be what you need. 您可以考虑使用numpy vectorize来提高速度,但是如果需要数组的索引,则需要ndenumerate

Beyond this, your best bet may be writing bottleneck operations in C. 除此之外,您最好的选择可能是使用C编写瓶颈操作。

Update 更新资料

If it would help, I believe scipy.ndimage.label does exactly what you're attempting to do, and might even use the same algorithm. 如果有帮助的话,我相信scipy.ndimage.label确实可以完成您要尝试的操作,甚至可以使用相同的算法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM