Я хотел бы взять изображение и изменить масштаб изображения, пока это массив numpy.
Например, у меня есть это изображение бутылки кока-колы: bottle-1
Что переводится в массив формы, (528, 203, 3)
и я хочу изменить его размер, чтобы сказать размер этого второго изображения:
бутылка-2
Которая имеет форму (140, 54, 3)
.
Как изменить размер изображения до определенной формы, сохранив исходное изображение? В других ответах предлагается удалить каждую вторую или третью строку, но я хочу в основном сжать изображение, как вы это делаете с помощью редактора изображений, но в коде python. Есть ли библиотеки для этого в numpy / SciPy?
Ответы:
Да, вы можете установить
opencv
(это библиотека, используемая для обработки изображений и компьютерного зрения) и использовать этуcv2.resize
функцию. И, например, используйте:import cv2 import numpy as np img = cv2.imread('your_image.jpg') res = cv2.resize(img, dsize=(54, 140), interpolation=cv2.INTER_CUBIC)
Здесь
img
, таким образом, NumPy массив , содержащий исходное изображение, в то время какres
это NumPy массив , содержащий уменьшенное изображение. Важным аспектом являетсяinterpolation
параметр: есть несколько способов изменить размер изображения. Тем более, что вы уменьшаете масштаб изображения, а размер исходного изображения не кратен размеру измененного изображения. Возможные схемы интерполяции:Как и в случае с большинством вариантов, не существует «наилучшего» варианта в том смысле, что для каждой схемы изменения размера существуют сценарии, в которых одна стратегия может быть предпочтительнее другой.
источник
dsize
должно быть таким,dsize=(54, 140)
как если бы он принимает x, затем y, где массив numpy показывает форму как y, затем x (y - количество строк, а x - количество столбцов),skimage.io.imread('image.jpg')
иskimage.transform.resize(img)
. scikit-image.org/docs/dev/install.htmlХотя для этого можно использовать только numpy, эта операция не является встроенной. Тем не менее, вы можете использовать
scikit-image
(который построен на numpy) для такого рода манипуляций с изображениями.Документация по изменению масштаба Scikit-Image находится здесь .
Например, вы можете сделать со своим изображением следующее:
from skimage.transform import resize bottle_resized = resize(bottle, (140, 54))
Это позаботится о таких вещах, как интерполяция, сглаживание и т. Д.
источник
anti_aliasing
флагом, похоже, что он был удален из последней версии 0.13.1Для людей, приезжающих сюда из Google и ищущих быстрый способ уменьшить разрешение изображений в
numpy
массивах для использования в приложениях машинного обучения, вот супербыстрый метод (адаптированный отсюда ). Этот метод работает, только если входные размеры кратны выходным размерам.Следующие ниже примеры уменьшают разрешение 128x128 до 64x64 (это можно легко изменить).
Каналы последний заказ
# large image is shape (128, 128, 3) # small image is shape (64, 64, 3) input_size = 128 output_size = 64 bin_size = input_size // output_size small_image = large_image.reshape((output_size, bin_size, output_size, bin_size, 3)).max(3).max(1)
Первый заказ каналов
# large image is shape (3, 128, 128) # small image is shape (3, 64, 64) input_size = 128 output_size = 64 bin_size = input_size // output_size small_image = large_image.reshape((3, output_size, bin_size, output_size, bin_size)).max(4).max(2)
Для изображений в градациях серого просто измените значение
3
на1
следующее:Первый заказ каналов
# large image is shape (1, 128, 128) # small image is shape (1, 64, 64) input_size = 128 output_size = 64 bin_size = input_size // output_size small_image = large_image.reshape((1, output_size, bin_size, output_size, bin_size)).max(4).max(2)
В этом методе используется эквивалент максимального пула. Это самый быстрый способ сделать это, который я нашел.
источник
np.repeat(np.repeat(a, 2, axis=0), 2, axis=1)
Если кто-то пришел сюда в поисках простого метода масштабирования / изменения размера изображения в Python без использования дополнительных библиотек, вот очень простая функция изменения размера изображения:
#simple image scaling to (nR x nC) size def scale(im, nR, nC): nR0 = len(im) # source number of rows nC0 = len(im[0]) # source number of columns return [[ im[int(nR0 * r / nR)][int(nC0 * c / nC)] for c in range(nC)] for r in range(nR)]
Пример использования: изменение размера изображения (30 x 30) до (100 x 200):
import matplotlib.pyplot as plt def sqr(x): return x*x def f(r, c, nR, nC): return 1.0 if sqr(c - nC/2) + sqr(r - nR/2) < sqr(nC/4) else 0.0 # a red circle on a canvas of size (nR x nC) def circ(nR, nC): return [[ [f(r, c, nR, nC), 0, 0] for c in range(nC)] for r in range(nR)] plt.imshow(scale(circ(30, 30), 100, 200))
Выход:
Это работает для сжатия / масштабирования изображений и отлично работает с массивами numpy.
источник
imresize()
Метод SciPy был другим методом изменения размера, но он будет удален, начиная с SciPy v 1.3.0. SciPy относится к методу изменения размера изображения PIL :Image.resize(size, resample=0)
size - требуемый размер в пикселях в виде кортежа из двух элементов: (ширина, высота).
resample - необязательный фильтр передискретизации. Это может быть один из PIL.Image.NEAREST (использовать ближайшего соседа), PIL.Image.BILINEAR (линейная интерполяция), PIL.Image.BICUBIC (кубическая сплайн-интерполяция) или PIL.Image.LANCZOS (высококачественный фильтр понижающей дискретизации). ). Если опущено, или если изображение имеет режим «1» или «P», устанавливается PIL.Image.NEAREST.
Ссылка здесь: https://pillow.readthedocs.io/en/3.1.x/reference/Image.html#PIL.Image.Image.resize
источник
Конечно. Вы можете сделать это без OpenCV, scikit-image или PIL.
Изменение размера изображения в основном сопоставляет координаты каждого пикселя исходного изображения с его измененным положением.
Поскольку координаты изображения должны быть целыми числами (представьте его как матрицу), если отображаемая координата имеет десятичные значения, вы должны интерполировать значение пикселя, чтобы приблизить его к целочисленной позиции (например, получение ближайшего пикселя к этой позиции известно как интерполяция ближайшего соседа ).
Все, что вам нужно, это функция, которая выполняет эту интерполяцию за вас. SciPy имеет
interpolate.interp2d
.Вы можете использовать его для изменения размера изображения в массиве numpy, например
arr
, следующим образом:W, H = arr.shape[:2] new_W, new_H = (600,300) xrange = lambda x: np.linspace(0, 1, x) f = interp2d(xrange(W), xrange(H), arr, kind="linear") new_arr = f(xrange(new_W), xrange(new_H))
Конечно, если у вас изображение в формате RGB, вы должны выполнить интерполяцию для каждого канала.
Если вы хотите понять больше, я предлагаю посмотреть Resizing Images - Computerphile .
источник
import cv2 import numpy as np image_read = cv2.imread('filename.jpg',0) original_image = np.asarray(image_read) width , height = 452,452 resize_image = np.zeros(shape=(width,height)) for W in range(width): for H in range(height): new_width = int( W * original_image.shape[0] / width ) new_height = int( H * original_image.shape[1] / height ) resize_image[W][H] = original_image[new_width][new_height] print("Resized image size : " , resize_image.shape) cv2.imshow(resize_image) cv2.waitKey(0)
источник
cv2
и использует правильную функцию изменения размера вместо повторной реализации «субоптимальной» функции изменения размера, которая работает хуже, чем интерполяция ближайшего соседа.