Thank you both for your response. Much appreciated. As said, I work in Python. But I may not have been clear what I’m trying to do. Excuse me. This is the code that currently works like a charm: (as in: it produces the results I want)
subFrame = jetson.utils.cudaAllocMapped(width=area.width, height=area.height, format=frame.format)
jetson.utils.cudaCrop(frame, subFrame, area.roi)
# First convert the frame (in GPU memory) to something OpenCV can use
cvFrame = jetson.utils.cudaAllocMapped(width=frame.width, height=frame.height, format="bgr8")
# TODO: convert to grayscale with CUDA/in GPU MEM?
jetson.utils.cudaConvertColor(frame, cvFrame)
# make sure the GPU is done working before we convert to cv2
jetson.utils.cudaDeviceSynchronize()
# convert to cv2 image (cv2 images are numpy arrays)
cvFrame = jetson.utils.cudaToNumpy(cvFrame)
# Convert to grayscale - TODO: do this sooner in the process
cvFrame = cv2.cvtColor(cvFrame, cv2.COLOR_BGR2GRAY)
cvFrame = cv2.equalizeHist(cvFrame)
frameDelta = cv2.absdiff(area.previous_frame, cvFrame)
thresh = cv2.threshold(frameDelta, 128, 255, cv2.THRESH_BINARY)
thresh = cv2.dilate(thresh, None, iterations=2)
But I have to run this every single frame (albeit, the regions that are cropped to are quite small) so I would like to optimize this and run everything in/on GPU. The OpenCV functions that I use are - as far as I know - all available in CUDA. So I wanted to change it to:
subFrame = jetson.utils.cudaAllocMapped(width=area.width, height=area.height, format=frame.format)
jetson.utils.cudaCrop(frame, subFrame, area.roi)
# First convert the frame (in GPU memory) to something OpenCV can use
cvFrame = jetson.utils.cudaAllocMapped(width=frame.width, height=frame.height, format="gray8")
# TODO: convert to grayscale with CUDA/in GPU MEM?
jetson.utils.cudaConvertColor(frame, cvFrame)
# make sure the GPU is done working before we convert to cv2
jetson.utils.cudaDeviceSynchronize()
# This doesn't work:
# cvFrame = jetson.utils.cudaToNumpy(cvFrame)
cvFrame = cv2.cuda.equalizeHist(cvFrame)
# Detect areas with motion
frameDelta = cv2.cuda.absdiff(area.previous_frame, cvFrame)
thresh = cv2.cuda.threshold(frameDelta, 128, 255, cv2.THRESH_BINARY)
thresh = cv2.cuda.dilate(thresh, None, iterations=2)
But this doesn’t work because the cudaImage object that cudaConvertColor() produces can’t be given to the CV2 function(s). Also, converting to a Numpy array doesn’t work. The cv2.cuda.* functions expect a GpuMat object as input. How do I go about this efficiently?