Resize an image without distortion OpenCV

前端 未结 9 1948
日久生厌
日久生厌 2020-12-07 12:30

I am using python 3 and latest version of openCV. I am trying to resize an image using the resize function provided but after resizing the image is very distorted. Code :

相关标签:
9条回答
  • 2020-12-07 13:20

    The answer, provided by @vijay jha is too case specific. Also includes additional unnecessary padding. I propose fixed code below:

    def resize2SquareKeepingAspectRation(img, size, interpolation):
      h, w = img.shape[:2]
      c = None if len(img.shape) < 3 else img.shape[2]
      if h == w: return cv2.resize(img, (size, size), interpolation)
      if h > w: dif = h
      else:     dif = w
      x_pos = int((dif - w)/2.)
      y_pos = int((dif - h)/2.)
      if c is None:
        mask = np.zeros((dif, dif), dtype=img.dtype)
        mask[y_pos:y_pos+h, x_pos:x_pos+w] = img[:h, :w]
      else:
        mask = np.zeros((dif, dif, c), dtype=img.dtype)
        mask[y_pos:y_pos+h, x_pos:x_pos+w, :] = img[:h, :w, :]
      return cv2.resize(mask, (size, size), interpolation)
    

    The code resizes an image making it square and keeping aspect ration at the same time. Also the code is suitable for 3 channels (colored) images as well. Example of usage:

    resized = resize2SquareKeepingAspectRation(img, size, cv2.INTER_AREA)
    
    0 讨论(0)
  • 2020-12-07 13:23

    I have a dataset of hand drawings and i needed to create small square images from asymmetric drawings.

    Thanks to @vijay jha i created square images while maintaining the aspect ratio of the original image. One issue though was that the more you downscaled the more information was lost.

    512x256 to 64x64 would look like this:

    I modified a bit the original code to smoothly downscale the image.

    from skimage.transform import resize, pyramid_reduce
    
    
    def get_square(image, square_size):
    
        height, width = image.shape    
        if(height > width):
          differ = height
        else:
          differ = width
        differ += 4
    
        # square filler
        mask = np.zeros((differ, differ), dtype = "uint8")
    
        x_pos = int((differ - width) / 2)
        y_pos = int((differ - height) / 2)
    
        # center image inside the square
        mask[y_pos: y_pos + height, x_pos: x_pos + width] = image[0: height, 0: width]
    
        # downscale if needed
        if differ / square_size > 1:
          mask = pyramid_reduce(mask, differ / square_size)
        else:
          mask = cv2.resize(mask, (square_size, square_size), interpolation = cv2.INTER_AREA)
        return mask
    

    512x256 -> 64x64

    512x256 -> 28x28

    0 讨论(0)
  • 2020-12-07 13:26

    You may try below. The function will keep the aspect rate of the original image.

    def image_resize(image, width = None, height = None, inter = cv2.INTER_AREA):
        # initialize the dimensions of the image to be resized and
        # grab the image size
        dim = None
        (h, w) = image.shape[:2]
    
        # if both the width and height are None, then return the
        # original image
        if width is None and height is None:
            return image
    
        # check to see if the width is None
        if width is None:
            # calculate the ratio of the height and construct the
            # dimensions
            r = height / float(h)
            dim = (int(w * r), height)
    
        # otherwise, the height is None
        else:
            # calculate the ratio of the width and construct the
            # dimensions
            r = width / float(w)
            dim = (width, int(h * r))
    
        # resize the image
        resized = cv2.resize(image, dim, interpolation = inter)
    
        # return the resized image
        return resized
    

    Here is an example usage.

    image = image_resize(image, height = 800)
    

    Hope this helps.

    0 讨论(0)
提交回复
热议问题