0

One image can be resized using opencv on python3

import cv2 
res_image = cv2.resize(image, dsize=(50, 100))

Also, multiple images can be resized through for syntax.

for image in images:
  res_image = cv2.resize(image, dsize=(50, 100))

But I want to resize the the same size of images(array) at once instead of using for loop.

 >>> images.shape 
 (32, 64, 64, 3)

Please let me know if you have any solve to this problem. (even if don't use opencv)

thank you.

2 Answers 2

2

cv.resize() apparently supports an arbitrary number of channels. Since it doesn't mix data between channels, you could use this to your advantage.

Note that cv::Mat() currently only supports upto 512 channels. That is relevant here because numpy arrays are mapped to cv::Mat for OpenCV to handle the data.

Approach:

  • transpose from NHWC to HWCN
  • reshape to (H, W, C*N)
  • resize
  • undo reshape
  • undo transpose
images = ...
(N,H,W,C) = images.shape
assert N*C <= 512

instack = images.transpose((1,2,3,0)).reshape((H,W,C*N))

outstack = cv.resize(instack, ...)

out_images = outstack.reshape((H,W,C,N)).transpose((3,0,1,2))

Beyond that number of channels, you will have to use a loop.

Sign up to request clarification or add additional context in comments.

Comments

0

The following code could do the trick.

def resize_batch(img_batch, resize_width, resize_height):
    """
    :params
        image: np.array(), shape -> (batch, width, height, channels)
        resize_width: The resize width dimension. 
        resize_height: The resize height dimension. 

    :returns
        array of shape -> (batch, resized_width, resized_height, channels)
    """
    batch, original_width, original_height, channel = img_batch.shape
    
    rd_ch = img_batch[:,:,:,0]
    gr_ch = img_batch[:,:,:,1]
    bl_ch = img_batch[:,:,:,2]
    
    resized_images = np.zeros((batch, resize_width, resize_height, channel), dtype=np.uint8)
    
    x_scale = original_width/resize_width
    y_scale = original_height/resize_height
    
    resize_idx = np.zeros((resize_width, resize_height))
    resize_index_x = np.ceil(np.arange(0, original_width, x_scale)).astype(int)
    resize_index_y = np.ceil(np.arange(0, original_height, y_scale)).astype(int)
    resize_index_x[np.where(resize_index_x == original_width)]  -= 1
    resize_index_y[np.where(resize_index_y == original_height)] -= 1
    
    resized_images[:,:,:,0] = rd_ch[:,resize_index_x,:][:,:,resize_index_y]
    resized_images[:,:,:,1] = gr_ch[:,resize_index_x,:][:,:,resize_index_y]
    resized_images[:,:,:,2] = bl_ch[:,resize_index_x,:][:,:,resize_index_y]
    
    return resized_images

2 Comments

what does that do? nearest neighbor sampling? you're throwing around index arrays. I think that'll be slow. also... crosspost: stackoverflow.com/questions/64576675/…
The code above is just for resizing all the images in a batch. Yes, I understand it's slower than using cv2.resize() in a loop. The above code was just a part of an experiment. I was trying to make my own resize function for a particular batch of images. I thought using NumPy arrays could make the resize operation faster. I thought my above code could give someone an understanding of how to create their own resize function, or maybe someone could suggest me a better approach to resize all images in a batch more quickly.

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.