I am trying to resize an OpenCV image Mat object to a smaller size as show below:
small = cv2.resize(big, (small_height, small_width))
This works perfectly fine, however, it ends up creating a new small OpenCV Mat object every time this line of code is called.
Therefore, I am trying to find a way in which I can avoid creation of a new small Mat object every time. Does anyone have an idea if it even possible to reuse a preallocated Mat object for resize output?
Instead of using small = cv2.resize(...)
, you can pass the output object by reference: cv2.resize(big, (w, h), small)
.
I can't say I really understand what happens under the hoods, but I almost certain that the following method can be used for reusing pre-allocated Python object for resize:
# Pre-allocate object (assume output format is uint8 BGR):
small = np.zeros((small_height, small_width, 3), np.uint8)
# Pass output ndarray by reference:
cv2.resize(big, (small_width, small_height), small)
Note:
The OpenCV convention is (width, height)
and not (height, width)
as in your sample code.
It's actually simple to check if cv2.resize
creates a new object, or reuses the existing one.
Here is a simple test that shows that the OpenCV reuses the existing object:
import cv2
import numpy as np
big = cv2.imread('chelsea.png', cv2.IMREAD_COLOR)
small_width, small_height = 160, 90
# Allocate as twice as much rows (allocate small_height*2 rows istead of small_height rows)
small = np.zeros((small_height*2, small_width, 3), np.uint8)
small[:, :, 1] = 255 # Fill small image with green color
small_slice = small[small_height//2:small_height*3//2, :, :] #Get a slice in the expected size of resized output
# Pass small_slice by reference
cv2.resize(big, (small_width, small_height), small_slice)
cv2.imshow('small', small)
cv2.waitKey(0)
cv2.destroyAllWindows()
As you can see the green color is preserved from the original object, and the slice is filled by the output of resize
.