Русский
Русский
English
Статистика
Реклама

OpenCV в Python. Часть 2

Привет, Хабр! Продолжаем туториал по библиотеке opencv в python. Для тех кто не читал первую часть, сюда: Часть 1, а всем остальным увлекательного чтения!


part_2_logo


Введение


Теперь, когда вы ознакомились с основами данной библиотеки, пора приступить к базовым преобразованиям изображений: изменение размера, смещение вдоль осей, кадрирование(обрезка), поворот.


Изменение размера изображения


Первый метод, который мы изучим это как поменять высоту и ширину у изображения. Для этого в opencv есть такая функция как resize():


def resizing():    res_img = cv2.resize(img, (500, 900), cv2.INTER_NEAREST)

Данная функция первым аргументом принимает изображение, размер которого мы хотим изменить, вторым кортеж, который должен содержать в себе ширину и высоту для нового изображения, третьим метод интерполяции(необязательный). Интерполяция это алгоритм, который находит неизвестные промежуточные значения по имеющемуся набору известных значений. Фактически, это то, как будут заполняться новые пиксели при модификации размера изображения. К примеру, интерполяция методом ближайшего соседа (cv2.INTER_NEAREST) просто берёт для каждого пикселя итогового изображения один пиксель исходного, который наиболее близкий к его положению это самый простой и быстрый способ. Кроме этого метода в opencv существуют следующие: cv2.INTER_AREA, cv2.INTER_LINEAR( используется по умолчанию), cv2.INTER_CUBIC и cv2.INTER_LANCZOS4. Наиболее предпочтительным методом интерполяции для сжатия изображения является cv2.INTER_AREA, для увелечения cv2.INTER_LINEAR. От данного метода зависит качество конечного изображения, но как показывает практика, если мы уменьшаем/увеличиваем изображение меньше, чем в 1.5 раза, то не важно каким методом интерполяции мы воспользовались качество будет схожим. Данное утверждение можно проверить на практике. Напишем следующий код:


res_img_nearest = cv2.resize(img, (int(w / 1.4), int(h / 1.4)),                                  cv2.INTER_NEAREST)res_img_linear = cv2.resize(img, (int(w / 1.4), int(h / 1.4)),                                 cv2.INTER_LINEAR)

Слева изображение с интерполяцией методом ближайшего соседа, справа изображение с билинейной интерполяцией:


conc_girl


Очень важно при изменении размера изображения учитывать соотношение сторон. Соотношение сторон это пропорциональное соотношение ширины и высоты изображения.Если мы забудем о данном понятии, то получим изображение такого плана:


res_girl


Поэтому текущую функцию для изменения размера необходимо модифицировать:


def resizing(new_width=None, new_height=None, interp=cv2.INTER_LINEAR):    h, w = img.shape[:2]    if new_width is None and new_height is None:        return img    if new_width is None:        ratio = new_height / h        dimension = (int(w * ratio), new_height)    else:        ratio = new_width / w        dimension = (new_width, int(h * ratio))    res_img = cv2.resize(img, dimension, interpolation=interp)

Соотношение сторон мы вычисляем в переменной ratio. В зависимости от того, какой параметр не равен None, мы берём установленную нами новую высоту/ширину и делим на старую высоту/ширину. Далее, в переменной dimension мы определяем новые размеры изображения и передаём в функцию cv2.resize().


Смещение изображения вдоль осей


С помощью функции cv2.warpAffine() мы можем перемещать изображение влево и вправо, вниз и вверх, а также любую комбинацию из перечисленного:


def shifting():    h, w = img.shape[:2]    translation_matrix = np.float32([[1, 0, 200], [0, 1, 300]])    dst = cv2.warpAffine(img, translation_matrix, (w, h))    cv2.imshow('Изображение, сдвинутое вправо и вниз', dst)    cv2.waitKey(0)

Сначала, в переменной translation_matrix мы создаём матрицу преобразований как показано ниже:


1


Первая строка матрицы [1, 0, tx ], где tx количество пикселей, на которые мы будем сдвигать изображение влево или вправо. Отрицательное значения tx будет сдвигать изображение влево, положительное вправо.
Вторая строка матрицы [ 0, 1, ty], где ty количество пикселей, на которые мы будем сдвигать изображение вверх или вниз. Отрицательное значения ty будет сдвигать изображение вверх, положительное вниз. Важно помнить, что данная матрица определяется как массив с плавающей точкой.
На следующей строчке и происходит сдвиг изображения вдоль осей, с помощью, как я писал выше, функции cv2.warpAffine(), которая первым аргументом принимает изображение, вторым матрицу, третьим размеры нашего изображения. Если вы запустите данный код, то увидите следующее:


girl_right_and_down


Вырез фрагмента изображения


Для того, чтобы вырезать интересующий вас фрагмент из изображения, достаточно воспользоваться следующим кодом:


def cropping():    crop_img = img[10:450, 300:750]

В данной строчке мы предоставляем массив numpy для извлечения прямоугольной области изображения, начиная с (300, 10) и заканчивая (750, 450), где 10 это начальная координата по y, 300 начальная координата по x, 450 конечная координата по y и 750 конечная координата по x.Выполнив код выше, мы увидим, что обрезали лицо девочке:


crop_face


Поворот изображения


И, последнее, что мы на сегодня рассмотрим это как повернуть изображение на некоторый угол:


def rotation():    (h, w) = img.shape[:2]    center = (int(w / 2), int(h / 2))    rotation_matrix = cv2.getRotationMatrix2D(center, -45, 0.6)    rotated = cv2.warpAffine(img, rotation_matrix, (w, h))

Когда мы поворачиваем изображение, нам нужно указать, вокруг какой точки мы будем вращаться, именно это принимает первым аргументом функция cv2.getRotationMatrix2D(). В данном случае я указал центр изображения, однако opencv позволяет указать любую произвольную точку, вокруг которой вы захотите вращаться. Следующим аргументом данная функция принимает угол, на который мы хотим повернуть наше изображение, а последним аргументом коэффициент масштабирования. Мы используем 0.6, то есть уменьшаем изображение на 40%, для того, чтобы оно поместилось в кадр. Данная функция возвращает массив numpy, который мы передаём вторым аргументом в функцию cv2.warpAffine(). В итоге, у вас на экране должно отобразиться следующее изображение:


rotated_girl


Вот и вторая часть подошла к концу, исходный код доступен на github. Спасибо за уделённое внимание! До скорой встречи!

Источник: habr.com
К списку статей
Опубликовано: 15.11.2020 22:16:27
0

Сейчас читают

Комментариев (0)
Имя
Электронная почта

Python

Обработка изображений

Opencv

Туториал

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru