使用 python (OpenCV) 对图像中像素的迭代非常慢

Iterations through pixels in an image are terribly slow with python (OpenCV)

提问人:skm 提问时间:10/19/2014 最后编辑:Communityskm 更新时间:10/20/2014 访问量:27673

问:

我知道使用带有 C++ 的 OpenCV 遍历像素并访问它们的值。现在,我正在尝试自己学习 python,我尝试在 python 中做同样的事情。但是当我运行以下代码时,显示图像需要很多时间(~7-10 秒)。即使在显示图像后,脚本也会继续运行几秒钟。

我在 SO 发现了一个类似的问题,但我无法理解我如何在我的情况下使用 numpy(因为我是 python 的初学者)以及它是否真的需要?

代码说明:我只是想把黑色像素放在图像的左侧和右侧。

import numpy as np
import cv2 as cv

#reading an image
img = cv.imread('image.jpg')
height, width, depth = img.shape

for i in range(0, height):
    for j in range(0, (width/4)):
        img[i,j] = [0,0,0]  

for i in range(0, height):
    for j in range(3*(width/4), width):
        img[i,j] = [0,0,0]        

cv.imshow('image',img)

cv.waitKey(0)
蟒蛇 opencv numpy

评论


答:

16赞 roippi 10/19/2014 #1

(注意:我不熟悉,但这似乎是一个问题)opencvnumpy

“非常慢”的部分是你在 python 字节码中循环,而不是让循环以 C 速度。numpy

尝试直接分配给一个(3 维)切片,该切片会屏蔽要清零的区域。

import numpy as np

example = np.ones([500,500,500], dtype=np.uint8)

def slow():
     img = example.copy()
     height, width, depth = img.shape
     for i in range(0, height):             #looping at python speed...
         for j in range(0, (width//4)):     #...
             for k in range(0,depth):       #...
                 img[i,j,k] = 0
     return img


def fast():
     img = example.copy()
     height, width, depth = img.shape
     img[0:height, 0:width//4, 0:depth] = 0 # DO THIS INSTEAD
     return img 

np.alltrue(slow() == fast())
Out[22]: True

%timeit slow()
1 loops, best of 3: 6.13 s per loop

%timeit fast()
10 loops, best of 3: 40 ms per loop

上面显示了将左侧归零;对右侧做同样的事情对读者来说是一种练习。

如果 numpy 切片语法让您感到困惑,我建议您通读索引文档

评论

0赞 skm 10/19/2014
谢谢你的回复。正如我所提到的,我对 python 完全陌生,所以,如果你能解释你的代码的基本思想,那对我来说会非常有帮助。
0赞 roippi 10/19/2014
我不确定你在问什么;我解释说您需要分配给 3D 切片,并注释了我这样做的行。更具体地说明你不理解的内容。
2赞 Eric 10/19/2014
或者更简单地说,,对于另一条边缘,img[:,:width/4,:] = 0img[:,-width/4:,:] = 0
1赞 Eric 10/19/2014
如果你想在一行内完成,img[:,np.r_[:width/4,-width/4:],:] = 0
0赞 Alaa M. 3/2/2019
在这一行中:,可以是要应用于每个像素的自定义函数吗?img[0:height, 0:width//4, 0:depth] = 00