Изменение размера изображения без искажений OpenCV

Вы можете P / INVOKE в функцию NtQuerySystemInformation запросить все дескрипторы, а затем перейти оттуда. Это обсуждение групп Google содержит сведения.

21
задан Tanmay Bhatnagar 20 June 2017 в 10:43
поделиться

8 ответов

Вы можете попробовать ниже. Функция сохранит пропорции исходного изображения.

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

Вот пример использования.

image = image_resize(image, height = 800)

Надеюсь, это поможет.

49
ответ дан thewaywewere 20 June 2017 в 10:43
поделиться

Если вам нужно изменить разрешение изображения и сохранить соотношение сторон, используйте функцию imutils (см. Документацию). как-то так:

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

надеюсь, что это помогает, удачи!

5
ответ дан Andres Mitre 20 June 2017 в 10:43
поделиться

Попробуйте эту простую функцию в python, которая использует opencv. просто передайте изображение и укажите желаемый размер квадрата.

def get_square(image,square_size):

    height,width=image.shape
    if(height>width):
      differ=height
    else:
      differ=width
    differ+=4

    mask = np.zeros((differ,differ), dtype="uint8")   
    x_pos=int((differ-width)/2)
    y_pos=int((differ-height)/2)
    mask[y_pos:y_pos+height,x_pos:x_pos+width]=image[0:height,0:width]
    mask=cv2.resize(mask,(square_size,square_size),interpolation=cv2.INTER_AREA)

    return mask 

использование: squared_image = get_square (image, 28)

объяснение: функция принимает ввод любого размера и создает пустое изображение в форме квадрата, превышающее высоту входного изображения и ширина. затем он помещает исходное изображение в центр пустого изображения. а затем он изменяет размер этого квадратного изображения до желаемого размера, чтобы сохранить форму исходного изображения.

надеюсь, это поможет тебе

4
ответ дан vijay jha 20 June 2017 в 10:43
поделиться

У меня есть набор данных рисунков от руки, и мне нужно было создать маленькие квадратные изображения из асимметричных рисунков.

enter image description here

Благодаря @vijay jha я создал квадратных изображений , сохраняя при этом соотношение сторон исходного изображения. Одна проблема заключалась в том, что чем больше вы уменьшали, тем больше информации было потеряно.

512x256 - 64x64 будут выглядеть так:

64x64

Я изменил бит исходного кода для плавного уменьшения изображения.

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

enter image description here

512x256 -> 28x28

enter image description here

3
ответ дан Arthur 20 June 2017 в 10:43
поделиться
img = cv2.resize(img, (int(img.shape[1]/2), int(img.shape[0]/2)))

изменит размер изображения до половины исходного размера. Вы можете изменить его для любого другого соотношения. Обратите внимание, что первый аргумент, переданный resize (), это img.shape [1], а не img.shape [0]. Это может быть нелогичным. Легко пропустить этот поворот и получить очень искаженную картину.

2
ответ дан Raja 20 June 2017 в 10:43
поделиться

Код получает значение window_height, с помощью которого он вычисляет переменную window_width, сохраняя при этом соотношение сторон изображения. Чтобы не допустить искажения.

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()
2
ответ дан double-beep 20 June 2017 в 10:43
поделиться

Не могу привести кавычки в соответствие с тем, что задает оригинальный вопрос, но я приземлился здесь в поисках ответа на аналогичный вопрос.

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
1
ответ дан orangepips 20 June 2017 в 10:43
поделиться

Я только что столкнулся с той же проблемой при подготовке набора данных к нейронной сети, и чтобы избежать необходимости искажать изображение, я сделал функцию, которая изменяет размеры и обрезки изображение минимально для установки целевому размеру. Это работает первым выбором, обрезать ли в y или x путем сравнения входной пропорции изображения с целевым соотношением сторон. Тогда это изменяет размеры входного изображения к целевой ширине или высоте, и затем обрезающий в x или y (каждый в зависимости от если отношение соотношений сторон).

    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
ответ дан 28 November 2019 в 02:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: