10

I am aware of iterating through pixels and accessing their values using OpenCV with C++. Now, i am trying to learn python myself and i tried to do the same thing in python. But when i am running the following code, it takes a lot of time (~7-10 seconds) to display the image. And the script keeps running on for few more seconds even after displaying the image.

I found a similar question here at SO but i am not able to understand how do i use numpy in my case (because i am a beginner in python) and whether or not it is really required?

Code Explanation: I am just trying to put the black pixels on the left and right side of the image.

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 Answer 1

16

(note: I'm not familiar with opencv, but this appears to be a numpy issue)

The "terribly slow" part is that you're looping in python bytecode, rather than letting numpy loop at C speed.

Try directly assigning to a (3-dimensional) slice that masks the region you want to zero out.

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

The above shows zeroing out the left side; doing the same for the right side is an exercise for the reader.

If the numpy slicing syntax trips you up, I suggest reading through the indexing docs.

Sign up to request clarification or add additional context in comments.

5 Comments

thanks for youe reply. As i have mentioned that i am completely new to python so, it would be very helpful for me if you could explain the basic idea of your code.
I'm not sure what you're asking about; I explained that you need to assign to a 3D slice, and commented the line where I do that. Be more specific about what you don't understand.
Or more simply, img[:,:width/4,:] = 0, and for the other edge, img[:,-width/4:,:] = 0
And if you're feeling like doing it in one line, img[:,np.r_[:width/4,-width/4:],:] = 0
In this line: img[0:height, 0:width//4, 0:depth] = 0 , can 0 be a custom function to be applied for every pixel?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.