Як змінити розмір зображення за допомогою OpenCV2.0 та Python2.6


163

Я хочу використовувати OpenCV2.0 і Python2.6 для показу розмірів розміру. Я використав і прийняв приклад на http://opencv.willowgarage.com/documentation/python/cookbook.html, але, на жаль, цей код призначений для OpenCV2.1 і, здається, не працює на 2.0. Ось мій код:

import os, glob
import cv

ulpath = "exampleshq/"

for infile in glob.glob( os.path.join(ulpath, "*.jpg") ):
    im = cv.LoadImage(infile)
    thumbnail = cv.CreateMat(im.rows/10, im.cols/10, cv.CV_8UC3)
    cv.Resize(im, thumbnail)
    cv.NamedWindow(infile)
    cv.ShowImage(infile, thumbnail)
    cv.WaitKey(0)
    cv.DestroyWindow(name)

Оскільки я не можу використовувати

cv.LoadImageM

я використав

cv.LoadImage

натомість, що не було проблем в інших додатках. Тим не менш, cv.iplimage не має атрибутних рядків, знаків чи розмірів. Хтось може дати мені підказку, як вирішити цю проблему? Дякую.


4
Якщо будь-яка з відповідей була правильною, зазначте, що вона допоможе іншим.
Michał

Відповіді:


342

Якщо ви хочете використовувати CV2, вам потрібно скористатися resizeфункцією.

Наприклад, це змінить розмір обох осей удвічі:

small = cv2.resize(image, (0,0), fx=0.5, fy=0.5) 

і це дозволить змінити розмір зображення в розмірі 100 ліній (ширина) і 50 рядків (висота):

resized_image = cv2.resize(image, (100, 50)) 

Інший варіант - використовувати scipyмодуль, використовуючи:

small = scipy.misc.imresize(image, 0.5)

Очевидно є більше варіантів, які ви можете прочитати в документації цих функцій ( cv2.resize , scipy.misc.imresize ).


Оновлення:
Відповідно до документації SciPy :

imresizeє застарілим в SciPy 1.0.0, і треба увійти на сайт 1.2.0.
Використовуйте skimage.transform.resizeзамість цього.

Зауважте, що якщо ви хочете змінити розмір за фактором , ви, можливо, захочете skimage.transform.rescale.


1
чи не функція resize () не робить зображення, що втрачає інформацію про себе?

8
Так, ви не можете зменшити розмір зображення, не втрачаючи інформації.
Rafael_Espericueta

1
Реалізація opencv (0,05 мс на зображення) здається набагато швидшою, ніж реалізація scipy (зображення 0,33 мс). Я змінив розмір зображень від 210x160x1 до 84x84x1 з білінеарною інтерполяцією.
gizzmole

@gizzmole Цікаве розуміння. Я не перевіряв ефективність реалізації, ні порівнював результати - тому кінцевий результат також може незначно відрізнятися. Ви перевірили, чи не змінюються розміри зображень збігаються побіжно?
emem

Дякує за вказівку, що функція зміни розміру приймає (Ш * В), тоді як cv2 друкується як (H * W)
Шивам Котвалія

59

Приклад подвоєння розміру зображення

Існує два способи змінити розмір зображення. Новий розмір можна вказати:

  1. Вручну;

    height, width = src.shape[:2]

    dst = cv2.resize(src, (2*width, 2*height), interpolation = cv2.INTER_CUBIC)

  2. За коефіцієнтом масштабування.

    dst = cv2.resize(src, None, fx = 2, fy = 2, interpolation = cv2.INTER_CUBIC), де fx - коефіцієнт масштабування вздовж горизонтальної осі, а fy - по вертикальній осі.

Щоб зменшити зображення, воно, як правило, найкраще виглядає з інтерполяцією INTER_AREA, тоді як для збільшення зображення воно, як правило, найкраще виглядає за допомогою INTER_CUBIC (повільно) або INTER_LINEAR (швидше, але все-таки виглядає нормально).

Приклад зменшення зображення, щоб відповідати максимальній висоті / ширині (зберігаючи співвідношення сторін)

import cv2

img = cv2.imread('YOUR_PATH_TO_IMG')

height, width = img.shape[:2]
max_height = 300
max_width = 300

# only shrink if img is bigger than required
if max_height < height or max_width < width:
    # get scaling factor
    scaling_factor = max_height / float(height)
    if max_width/float(width) < scaling_factor:
        scaling_factor = max_width / float(width)
    # resize image
    img = cv2.resize(img, None, fx=scaling_factor, fy=scaling_factor, interpolation=cv2.INTER_AREA)

cv2.imshow("Shrinked image", img)
key = cv2.waitKey()

Використання коду з cv2

import cv2 as cv

im = cv.imread(path)

height, width = im.shape[:2]

thumbnail = cv.resize(im, (round(width / 10), round(height / 10)), interpolation=cv.INTER_AREA)

cv.imshow('exampleshq', thumbnail)
cv.waitKey(0)
cv.destroyAllWindows()

ваше рішення, використовуючи коефіцієнти масштабування, повертає помилку на cv2.resize (), кажучи: "src - не масивний масив, а не скаляр". Порадьте, будь ласка?
БенП

ви зробили: src = cv2.imread('YOUR_PATH_TO_IMG')і редагували "YOUR_PATH_TO_IMG" на шлях вашого власного зображення?
Жоао Картучо

робить cv2.resizeавтоматично використовує оббивку? який розмір вікна, яке створюється з використанням потрібного розміру виводу (width/10, height/10)?
seralouk

@makaros ви отримуєте зображення, яке на 10 разів менше як по ширині, так і по висоті
João Cartucho

@ JoãoCartucho так, я розумію це. Але коли використовується найближчий_сусед, то за кадром слід застосувати вікно. Це я прошу ..
seralouk

8

Ви можете використовувати функцію GetSize для отримання цієї інформації, cv.GetSize (im) поверне кортеж із шириною та висотою зображення. Ви також можете використовувати im.depth та img.nChan, щоб отримати більше інформації.

І щоб змінити розмір зображення, я використовував би трохи інший процес, а інше зображення замість матриці. Краще спробувати працювати з однотипними даними:

size = cv.GetSize(im)
thumbnail = cv.CreateImage( ( size[0] / 10, size[1] / 10), im.depth, im.nChannels)
cv.Resize(im, thumbnail)

Сподіваюся, це допомагає;)

Жульєн


6
def rescale_by_height(image, target_height, method=cv2.INTER_LANCZOS4):
    """Rescale `image` to `target_height` (preserving aspect ratio)."""
    w = int(round(target_height * image.shape[1] / image.shape[0]))
    return cv2.resize(image, (w, target_height), interpolation=method)

def rescale_by_width(image, target_width, method=cv2.INTER_LANCZOS4):
    """Rescale `image` to `target_width` (preserving aspect ratio)."""
    h = int(round(target_width * image.shape[0] / image.shape[1]))
    return cv2.resize(image, (target_width, h), interpolation=method)

робить cv2.resizeавтоматично використовує оббивку? який розмір вікна, яке створюється за допомогою (w, target_height)аргументів?
seralouk

4

Ось функція збільшити або зменшити масштаб зображення на потрібну ширину або висоту, зберігаючи співвідношення сторін

# Resizes a image and maintains aspect ratio
def maintain_aspect_ratio_resize(image, width=None, height=None, inter=cv2.INTER_AREA):
    # Grab the image size and initialize dimensions
    dim = None
    (h, w) = image.shape[:2]

    # Return original image if no need to resize
    if width is None and height is None:
        return image

    # We are resizing height if 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)
    # We are resizing width if height is none
    else:
        # Calculate the ratio of the width and construct the dimensions
        r = width / float(w)
        dim = (width, int(h * r))

    # Return the resized image
    return cv2.resize(image, dim, interpolation=inter)

Використання

import cv2

image = cv2.imread('1.png')
cv2.imshow('width_100', maintain_aspect_ratio_resize(image, width=100))
cv2.imshow('width_300', maintain_aspect_ratio_resize(image, width=300))
cv2.waitKey()

Використовуючи цей приклад зображення

введіть тут опис зображення

Просто зменшити масштаб width=100(ліворуч) або підвищити шкалу width=300(праворуч)

введіть тут опис зображення введіть тут опис зображення

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.