Resize an image without distortion OpenCV

前端 未结 9 1947
日久生厌
日久生厌 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:00

    Does not quite align with what the original question is asking, but I landed here searching for an answer to a similar question.

    import cv2
    def resize_and_letter_box(image, rows, cols):
        """
        Letter box (black bars) a color image (think pan & scan movie shown 
        on widescreen) if not same aspect ratio as specified rows and cols. 
        :param image: numpy.ndarray((image_rows, image_cols, channels), dtype=numpy.uint8)
        :param rows: int rows of letter boxed image returned  
        :param cols: int cols of letter boxed image returned
        :return: numpy.ndarray((rows, cols, channels), dtype=numpy.uint8)
        """
        image_rows, image_cols = image.shape[:2]
        row_ratio = rows / float(image_rows)
        col_ratio = cols / float(image_cols)
        ratio = min(row_ratio, col_ratio)
        image_resized = cv2.resize(image, dsize=(0, 0), fx=ratio, fy=ratio)
        letter_box = np.zeros((int(rows), int(cols), 3))
        row_start = int((letter_box.shape[0] - image_resized.shape[0]) / 2)
        col_start = int((letter_box.shape[1] - image_resized.shape[1]) / 2)
        letter_box[row_start:row_start + image_resized.shape[0], col_start:col_start + image_resized.shape[1]] = image_resized
        return letter_box
    
    0 讨论(0)
  • 2020-12-07 13:10
    img = cv2.resize(img, (int(img.shape[1]/2), int(img.shape[0]/2)))
    

    will resize the image to half the original size. You can modify it for any other ratio. Note that the first argument passed to resize() is img.shape[1], and not img.shape[0]. This may be counter-intuitive. It is easy to overlook this reversal and get a very distorted picture.

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

    Try this simple function in python that uses OpenCV. just pass the image and mention the size of square you want.

    def resize_image(img, size=(28,28)):
    
        h, w = img.shape[:2]
        c = img.shape[2] if len(img.shape)>2 else 1
    
        if h == w: 
            return cv2.resize(img, size, cv2.INTER_AREA)
    
        dif = h if h > w else w
    
        interpolation = cv2.INTER_AREA if dif > (size[0]+size[1])//2 else 
                        cv2.INTER_CUBIC
    
        x_pos = (dif - w)//2
        y_pos = (dif - h)//2
    
        if len(img.shape) == 2:
            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, interpolation)
    

    usage: squared_image=get_square(image, size=(28,28))

    explanation: function takes input of any size and it creates a squared shape blank image of size image's height or width whichever is bigger. it then places the original image at the center of the blank image. and then it resizes this square image into desired size so the shape of original image content gets preserved.

    hope , this will help you

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

    The code is given a window_height by which it calculates the window_width variable while maintaining the aspect ratio of the image. In order to prevent it from any distortion.

    import cv2
    
    def resize(self,image,window_height = 500):
        aspect_ratio = float(image.shape[1])/float(image.shape[0])
        window_width = window_height/aspect_ratio
        image = cv2.resize(image, (int(window_height),int(window_width)))
        return image
    
    img = cv2.imread(img_source)         #image location
    img_resized = resize(img,window_height = 800)
    cv2.imshow("Resized",img_resized)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    
    0 讨论(0)
  • 2020-12-07 13:14

    If you need to modify the image resolution and keep your aspect ratio use the function imutils (check documentation). something like this:

    img = cv2.imread(file , 0)
    img = imutils.resize(img, width=1280)
    cv2.imshow('image' , img)
    

    hope that helps, good luck !

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

    I've just run into the same issue while preparing a dataset for a neural net, and in order to avoid having to distort the image, I've made a function which resizes and crops the image minimally to fit the destination size. It works by first choosing whether to crop in the y or x by comparing the input image aspect ratio to the destination aspect ratio. Then it resizes the input image to the destination width or height, and then cropping in the x or y (each depending on if ratio of aspect ratios).

        def crop_and_resize(img, w, h):
            im_h, im_w, channels = img.shape
            res_aspect_ratio = w/h
            input_aspect_ratio = im_w/im_h
    
            if input_aspect_ratio > res_aspect_ratio:
                im_w_r = int(input_aspect_ratio*h)
                im_h_r = h
                img = cv2.resize(img, (im_w_r , im_h_r))
                x1 = int((im_w_r - w)/2)
                x2 = x1 + w
                img = img[:, x1:x2, :]
            if input_aspect_ratio < res_aspect_ratio:
                im_w_r = w
                im_h_r = int(w/input_aspect_ratio)
                img = cv2.resize(img, (im_w_r , im_h_r))
                y1 = int((im_h_r - h)/2)
                y2 = y1 + h
                img = img[y1:y2, :, :]
            if input_aspect_ratio == res_aspect_ratio:
                img = cv2.resize(img, (w, h))
    
            return img
    
    0 讨论(0)
提交回复
热议问题