hugo
hugo

Reputation: 31

Use dst argument to reuse previously allocated memory with the cvtColor function in OpenCV with Python

I am implementing a program where I need to have an array of images which are reused (for speed purposes). I thought I could easily create a multidimensional numpy array and reuse each plane as a grayscale image without reallocating new memory, but I am having trouble doing so. Below is a piece of code I create just to illustrate this (this is a simplified version of what I need, just to illustrate my point):

import cv2
import numpy as np

# Access camera
cap = cv2.VideoCapture(0)
cv2.namedWindow('Main process')

# Confirm we are able to acquire images (and initialize the frame variable)
ret, rgb_frame = cap.read()
if ret is False:
    print('Error, unable to acquire frame...')
    exit(0)

NUM_BUFFERS = 3

gray_frames_array = np.zeros(
    (rgb_frame.shape[0], rgb_frame.shape[1], NUM_BUFFERS),
    dtype=rgb_frame.dtype)

i = 0
while True:
    ret, _ = cap.read(rgb_frame)
    if ret is False:
        print('Error, unable to acquire frame...')
        exit(0)
    cv2.cvtColor(src=rgb_frame, code=cv2.COLOR_BGR2GRAY,
                 dst=gray_frames_array[:, :, i])
    cv2.imshow('Main process', gray_frames_array[:, :, i])
    if cv2.waitKey(5) == 27:
        break
    # Use th next "buffer"
    i = (i+1) % NUM_BUFFERS

print('done')

My mistake is probably from my Matlab background, but, as it is, I would expect this program to just work without any memory being allocated during the "While True" cycle. However, I get the error:

Expected Ptr<cv::UMat> for argument 'dst'

I know that if I use a list of [height, width] numpy arrays, instead of a [height, width,NUM_BUFFERS], it will work just fine but I was looking to get this working with a single multidimensional numpy array.

Upvotes: 2

Views: 696

Answers (1)

hugo
hugo

Reputation: 31

Thanks to Dan Masek for pointing out the correct answer. I just shifted the dimensions and it does not give an error anymore.

Although the code is very similiar, I am leaving it here for future reference.

import cv2
import numpy as np

# Access camera
cap = cv2.VideoCapture(0)
cv2.namedWindow('Main process')

# Confirm we are able to acquire images (and initialize the frame variable)
ret, rgb_frame = cap.read()
if ret is False:
    print('Error, unable to acquire frame...')
    exit(0)

NUM_BUFFERS = 3

gray_frames_array = np.zeros(
    (NUM_BUFFERS, rgb_frame.shape[0], rgb_frame.shape[1]),
    dtype=rgb_frame.dtype)

i = 0
while True:
    ret, _ = cap.read(rgb_frame)
    if ret is False:
        print('Error, unable to acquire frame...')
        exit(0)
    cv2.cvtColor(src=rgb_frame, code=cv2.COLOR_BGR2GRAY,
                 dst=gray_frames_array[i, :, :])
    cv2.imshow('Main process', gray_frames_array[i, :, :])
    if cv2.waitKey(5) == 27:
        break
    # Use th next "buffer"
    i = (i+1) % NUM_BUFFERS

print('done')

Upvotes: 1

Related Questions