python和opencv中的快速组件标记

python和opencv中的快速组件标记,python,opencv,Python,Opencv,我正在使用python和opencv实现组件标签算法。它需要逐像素检查输入图像,并执行所谓的轮廓跟踪子例程,将标签指定给二值图像的斑点 我设法让它运转起来,但似乎很慢。分析代码表明,访问像素的for循环似乎是瓶颈。256px*256px的图像大约需要200毫秒。我大致是这样做的: for i in image.height: for j in image.width: p = image[i, j] pa = image[i - 1, j]

我正在使用python和opencv实现组件标签算法。它需要逐像素检查输入图像,并执行所谓的轮廓跟踪子例程,将标签指定给二值图像的斑点

我设法让它运转起来,但似乎很慢。分析代码表明,访问像素的for循环似乎是瓶颈。256px*256px的图像大约需要200毫秒。我大致是这样做的:

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...
其中“图像”是一个二进制opencv图像

我想知道是否有一种更快的方法,这样它也可以用于视频应用程序。对于同样大小的问题,我的目标是40-50ms的运行时间,达到20-25fps。10-15fps也可以接受(66-100ms运行时间)


非常感谢任何提示、想法和我能做的事情。

最新的Python OpenCV绑定返回numpy数据类型,这意味着您可以使用完整的numpy库。在numpy中的2D数组上循环(带索引)通常使用,这至少会提供一点加速(因为它是针对N-D数组优化的单循环)。您可以查看numpy,它将产生更多的加速,但是如果您需要数组的索引,那么您需要的就是
ndenumerate

除此之外,最好的选择可能是用C编写瓶颈操作

更新


如果有帮助的话,我相信
scipy.ndimage.label
正是您想要做的,甚至可能使用相同的算法。

我看到的许多帖子都在哀叹OpenCV标签的缺失

正如@malloc47所说,
scipy.ndimage.label将起作用。我用过它,但当我在寻找图像中最大的斑点时,我对它的性能不满意。我并不特别需要一个标签,所以我最终使用
cv2.findContours
cv2.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))]]

对于我来说,对于非常相似的结果,这比
scipy.ndimage.label
要快得多。正如我所说的,这并不完全是一种标记,但是可以使用contour finder来给出一个相当好的标记。

Python在这里并不是一种高性能的语言。。。请使用Java、C/C++或其他更快的工具再试一次。