0

I am working on a computer vision program and trying to create a background image by taking the median value of each pixel over the duration of the video. To do this I convert each video frame from RGB to gray scale and also convert the data to int32. Once I do this I want to read the gray-value of each pixel and add 1 to a bin of a histogram (each pixel has its own histogram assigned to it).

This should be a simple task however it is taking wayyyyyy to long. When I look at the time for each step I see the conversions are order of magnitude .01 sec, but the reading of the data across all pixels is on the order of magnitude of 1 sec.

Since the gray scale conversion is essentially doing more flops than just reading the data at each pixel and taking less time to do it, I know there must be a better way to do this. I have tried to multi-thread the process and saw no speed up between 2 threads and 4 threads, so I don't think this will help.

backgroundImg=[[[0 for col in range(64)]
                    for col in range(1920)]
                        for row in range(1080)]
while(True)
    ret,frame=cam.read()
    if ret:
        frame=Image.fromarray(frame).convert('LA')
        frame=np.int32(frame)
        for line in range(0,1080):
            for col in range(0,1920):
                backgroundImage[line][col][frame[line][col][0]]+=1

This is an example of my code. After the background image is calculated I will need to subtract this from every frame and run algorithm to find all the connected pixels.

JD Brown
  • 1
  • 1
  • 1
    Yes, loops are slow in Python. You need to look for vectorized operations using NumPy. How to vectorize your code depends on what happens inside the loop, so we can't help unless you post a more meaningful example. – Cris Luengo Feb 20 '20 at 23:16
  • PIL also supports ways of processing each pixel of an image by apply a function to each one of them as well as function to to many other common image-processing tasks — which may be able to do what you want much faster. Here's [one example](https://stackoverflow.com/a/12310820/355230), However, as @CrisLuengo said, without a more meaningful example of what you want to do, it's difficult to be more specific. – martineau Feb 21 '20 at 00:52
  • you should use numpy array - to create your `backgroundImg` I need 18s. With numpy it takes 0.6s `backgroundImg = numpy.zeros([1080, 1920, 64])` – furas Feb 21 '20 at 00:58
  • `backgroundImg[line][col][int(frame[line][col]/4)]+=1` is the only operation I need to do. I don't think there is a way to vectorzie or map a function for this becuase it needs reference to the position in the image. – JD Brown Mar 02 '20 at 18:24

0 Answers0