1

I was just wondering if ther's a way to speed up the performances of this for loops in Python.

for i in range (0,img.shape[0],new_height):
    for j in range(0,img.shape[1],new_width):
        cropped_image = img[i:i+new_height,j:j+new_width]
        yuv_image = cv2.cvtColor(cropped_image,cv2.COLOR_BGR2YUV)
        Y,U,V = cv2.split(yuv_image)
        pixel_image_y = np.array(Y).flatten()
6
  • 1
    If your code works, this post belongs to codereview.stackexchange.com Commented May 27, 2020 at 9:08
  • Thank you i didn't know this site! Commented May 27, 2020 at 9:14
  • 2
    @azro Typically, question asking to speed up code that involves rewriting to include vectorization are considered reasonably on-topic with numpy or matlab tags. Commented May 27, 2020 at 9:14
  • Is img.shape[0] divisble by new_height and similarly for width? Commented May 27, 2020 at 9:50
  • 1
    All I can is to fo for multiprocessing. Commented May 27, 2020 at 9:54

1 Answer 1

2

We can simply reshape into those smaller blocks after converting the entire image to YUV space -

m,n = img.shape[:2]
yuv = cv2.cvtColor(img,cv2.COLOR_BGR2YUV)
yuv4D = yuv[...,0].reshape(m//new_height,new_height,n//new_width,new_width)
out = yuv4D.swapaxes(1,2).reshape(-1,new_height*new_width)

Timings on 1024x1024 RGB image -

In [157]: img = np.random.randint(0,256,(1024,1024,3)).astype(np.uint8)
     ...: new_height,new_width = 32,32

In [158]: %%timeit
     ...: out = []
     ...: for i in range (0,img.shape[0],new_height):
     ...:     for j in range(0,img.shape[1],new_width):
     ...:         cropped_image = img[i:i+new_height,j:j+new_width]
     ...:         yuv_image = cv2.cvtColor(cropped_image,cv2.COLOR_BGR2YUV)
     ...:         Y,U,V = cv2.split(yuv_image)
     ...:         pixel_image_y = np.array(Y).flatten()
     ...:         out.append(pixel_image_y)
11.9 ms ± 991 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [159]: %%timeit
     ...: m,n = img.shape[:2]
     ...: yuv = cv2.cvtColor(img,cv2.COLOR_BGR2YUV)
     ...: yuv4D = yuv[...,0].reshape(m//new_height,new_height,n//new_width,new_width)
     ...: out1 = yuv4D.swapaxes(1,2).reshape(-1,new_height*new_width)
1.48 ms ± 5.23 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.