Cv2.resize: примеры (PYTHON)
cv2.resize(image: ndarray, dsize: tuple): ndarrayОсновная информация о функции cv2.resize
Функция cv2.resize из библиотеки OpenCV предназначена для изменения размеров изображения. Её используют в задачах компьютерного зрения, когда требуется привести изображения к единому размеру для обработки нейронными сетями, уменьшить объем данных для ускорения обработки или увеличить изображение для визуализации.
Подробное описание аргументов:
- src: Исходное изображение (объект numpy.ndarray). Обязательный аргумент.
- dsize: Кортеж (ширина, высота) желаемого размера выходного изображения. Если равен None, размер вычисляется с использованием параметров fx и fy.
- fx: Коэффициент масштабирования по горизонтальной оси. Используется, когда dsize равен None.
- fy: Коэффициент масштабирования по вертикальной оси. Используется, когда dsize равен None.
- interpolation: Метод интерполяции, определяющий, как вычисляются значения пикселей в новом изображении.
Основные методы интерполяции:
- cv2.INTER_NEAREST: Ближайший сосед. Быстрый, но низкое качество.
- cv2.INTER_LINEAR: Билинейная интерполяция (используется по умолчанию). Хорошее соотношение скорости и качества.
- cv2.INTER_CUBIC: Бикубическая интерполяция для увеличения. Медленнее, но качественнее.
- cv2.INTER_AREA: Пересчет пиксельной области. Рекомендуется для уменьшения.
- cv2.INTER_LANCZOS4: Интерполяция Ланцоша с окном 8x8. Высокое качество, но медленно.
Функция возвращает новое изображение (numpy.ndarray) заданного размера. Исходное изображение остается неизменным.
Примеры использования функции
Изменение до точного размера:
import cv2
image = cv2.imread('image.jpg')
resized = cv2.resize(image, (300, 200))
print(resized.shape) # (200, 300, 3) - Высота, Ширина, Каналы(200, 300, 3)
Масштабирование с использованием коэффициентов:
resized_f = cv2.resize(image, None, fx=0.5, fy=1.5, interpolation=cv2.INTER_CUBIC)
print(resized_f.shape)(original_height*1.5, original_width*0.5, 3)
Использование разных методов интерполяции:
nearest = cv2.resize(image, (100,100), interpolation=cv2.INTER_NEAREST)
area = cv2.resize(image, (100,100), interpolation=cv2.INTER_AREA)Альтернативные функции в Python
Библиотека scikit-image предлагает функцию skimage.transform.resize. Она работает с изображениями в формате с плавающей точкой в диапазоне [0, 1] и может сохранять или изменять количество цветовых каналов. Ее предпочтительно использовать в научных и исследовательских задачах из-за интеграции с другими инструментами scikit-image.
Библиотека PIL (Pillow) содержит метод Image.resize. Он прост в использовании, поддерживает различные фильтры ресэмплинга (например, Image.Resampling.LANCZOS) и хорошо подходит для задач веб-разработки и базовой обработки изображений. Для интеграции с конвейерами OpenCV может потребоваться конвертация форматов.
Аналоги функции в других языках
JavaScript (с использованием Canvas):
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
canvas.width = newWidth;
canvas.height = newHeight;
ctx.drawImage(sourceImage, 0, 0, newWidth, newHeight);
const resizedData = ctx.getImageData(0, 0, newWidth, newHeight);Java (с использованием OpenCV для Java): API практически идентично Python.
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.Size;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
...
Mat src = Imgcodecs.imread("image.jpg");
Mat dst = new Mat();
Imgproc.resize(src, dst, new Size(300, 200));PHP (с использованием библиотеки GD):
$srcImage = imagecreatefromjpeg('image.jpg');
$dstImage = imagescale($srcImage, 300, 200);
imagejpeg($dstImage, 'resized.jpg');Основное отличие в синтаксисе и используемых библиотеках, но принцип задания нового размера и метода интерполяции сохраняется.
Типичные ошибки при работе с функцией
Передача размера в неверном порядке. Функция ожидает (ширина, высота), а размер изображения (numpy.shape) возвращается как (высота, ширина).
# Ошибка: перепутаны местами высота и ширина.
resized_wrong = cv2.resize(image, (image.shape[0], image.shape[1]))
print(resized_wrong.shape) # Может привести к неожиданному результату.Попытка изменить размер изображения, которое не загружено (равно None).
image = cv2.imread('non_existent_file.jpg')
if image is None:
print('Изображение не загружено')
else:
resized = cv2.resize(image, (100, 100)) # Без проверки упадёт ошибка.Несоответствие типа данных или количества каналов при использовании некоторых методов интерполяции с масками или одноканальными изображениями.
Изменения в новых версиях OpenCV
Начиная с версии OpenCV 4.x, серьезных изменений в сигнатуре функции cv2.resize не было. Основные обновления касаются оптимизации внутренних алгоритмов интерполяции для повышения быстродействия, особенно при работе с большими изображениями и использованием аппаратного ускорения. Рекомендуется всегда использовать актуальную стабильную версию библиотеки.
Расширенные примеры применения
Изменение размера с сохранением пропорций (масштабирование по большей стороне):
def resize_with_aspect_ratio(image, width=None, height=None):
h, w = image.shape[:2]
if width is None and height is None:
return image
if width is None:
ratio = height / float(h)
dim = (int(w * ratio), height)
else:
ratio = width / float(w)
dim = (width, int(h * ratio))
return cv2.resize(image, dim, interpolation=cv2.INTER_AREA)
resized_prop = resize_with_aspect_ratio(image, width=300)Пакетное изменение размера для набора изображений:
import os
input_dir = 'input_images/'
output_dir = 'resized_images/'
target_size = (224, 224)
for filename in os.listdir(input_dir):
img = cv2.imread(os.path.join(input_dir, filename))
if img is not None:
resized_img = cv2.resize(img, target_size)
cv2.imwrite(os.path.join(output_dir, filename), resized_img)Изменение размера только области интереса (ROI):
roi = image[50:200, 100:300] # Выделение области
resized_roi = cv2.resize(roi, (400, 100))
image[10:110, 10:410] = resized_roi # Вставка обратноСоздание пирамиды изображений (уменьшение в несколько раз):
layer = image.copy()
pyramid = [layer]
for i in range(3):
layer = cv2.resize(layer, None, fx=0.5, fy=0.5, interpolation=cv2.INTER_AREA)
pyramid.append(layer)