使用Python(OpenCV)迭代处理图像像素非常缓慢

10

我知道如何使用C++和OpenCV迭代遍历像素并访问它们的值。现在,我正在尝试学习Python,并尝试用Python做同样的事情。但是当我运行以下代码时,显示图像需要很长时间(约7-10秒),即使在显示图像后,脚本仍然持续运行几秒钟。

我在SO上找到了一个类似的问题(在这里),但我不知道在我的情况下如何使用numpy(因为我是Python的初学者),也不知道是否真的需要使用numpy?

代码解释:我只是试图在图像的左右两侧放置黑色像素。

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)
1个回答

16

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

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

尝试直接分配给一个(三维)切片,该切片掩盖了您想要清零的区域。

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切片语法让您感到困惑,建议阅读索引文档


感谢您的回复。正如我所提到的,我对Python完全不了解,所以如果您能解释一下您的代码的基本思想,那将非常有帮助。 - skm
我不确定你在问什么;我解释了你需要分配给一个三维切片,并在我执行该操作的代码行上进行了注释。请更具体地说明你不理解的内容。 - roippi
2
更简单地说,img[:,:width/4,:] = 0,对于另一边缘,img[:,-width/4:,:] = 0 - Eric
1
如果你想在一行代码中完成它,可以这样写:img[:,np.r_[:width/4,-width/4:],:] = 0 - Eric
在这行代码中:img[0:height, 0:width//4, 0:depth] = 00可以是一个自定义函数来应用于每个像素吗? - Alaa M.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接