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

OpenCV в Python. Часть 3

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



Введение


В данной части мы рассмотрим арифметику изображений, разделение и слияние каналов, различные методы размытия.


Арифметика изображений


Надеюсь, что все знают такие арифметические операции как сложение и вычитание, но при работе с изображениями мы не должны забывать о типе данных.
К примеру, у нас есть RGB изображение, пиксели которого попадают в диапазон [0,255]. Итак, что же произойдёт, если мы попытаемся к пикселю с интенсивностью 250 прибавить 30 или от 70 отнять 100? Если бы мы пользовались стандартными арифметическими правилами, то получили бы 280 и -30 соответственно. Однако, если мы работаем с RGB изображениями, где значения пикселей представлены в виде 8-битного целого беззнакового числа, то 280 и -30 не является допустимыми значениями. Для того, чтобы разобраться, что же произойдёт, давайте посмотрим на строчки кода ниже:


print("opencv addition: {}".format(cv2.add(np.uint8([250]),                                                    np.uint8([30]))))print("opencv subtract: {}".format(cv2.subtract(np.uint8([70]),                                                     np.uint8([100]))))print("numpy addition: {}".format(np.uint8([250]) + np.uint8([30])))print("numpy subtract: {}".format(np.uint8([70]) - np.uint8([71])))

Как мы видим, сложение и вычитание можно осуществить с помощью функций opencv add и subtract соответственно, а также с помощью numpy. И результаты будут отличаться:


opencv addition: 255opencv subtract: 0numpy addition: 24numpy subtract: 255

OpenCV выполняет обрезку и гарантирует, что значения пикселей никогда не выйдут за пределы диапазона [0,255]. В numpy же всё происходит немного иначе. Представьте себе обычные настенные часы, где вместо 60 находится 255. Получается, что после достижение 255 следующим числом будет идти 0, а когда мы отнимаем от меньшего числа большее, то после 0 ( против часовой стрелки) будет идти 255.


Разбиение и слияние каналов


Как мы знаем, RGB изображение состоит из красной, зелёной и синих компонент. И что, если мы захотим разделить изображение на соответствующие компоненты? Для этого в opencv есть специальная функция split():


image = cv2.imread('rectangles.png')b, g, r = cv2.split(image)cv2.imshow('blue', b)cv2.imshow('green', g)cv2.imshow('red', r)

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



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



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



Как можно увидеть, красный канал очень светлый. Это происходит потому, что оттенки красного очень сильно представлены в нашем изображении. Синий и зелёный каналы, наоборот, очень тёмные. Это случается потому, что на данном изображении очень мало данных цветов.
Для того, чтобы объединить каналы воедино, достаточно воспользоваться функцией merge(), которая принимает значения каналов:


merge_image = cv2.merge([g,b,r])cv2.imshow('merge_image', merge_image)cv2.imshow('original', image)cv2.waitKey(0)


Таким образом, мы получаем такое же изображение как оригинальное, за исключением того, что я поменял местами синий с зелёным каналом.


Размытие


Размытие это когда более резкие области на изображении теряют свою детализацию, в результате чего изображение становится менее чётким. В opencv имеются следующие основные методы размытия: averaging(усреднённое), gaussian(гауссово) и median(медианное).


Averaging


Данный фильтр делает операцию свёртки на изображении с неким ядром, где свёртка это вычисление нового значения пикселя, при котором учитываются значения соседних пикселей. Ядро свёртки это квадратная матрица, где пиксель в центре этой матрицы затем устанавливается как среднее значение всех других пикселей, окружающих его. Для того, чтобы воспользоваться данным размытием достаточно вызвать метод blur(), который принимает изображение и кортеж, с указанием размера ядра:


def averaging_blurring():    image = cv2.imread('girl.jpg')    img_blur_3 = cv2.blur(image, (3, 3))    img_blur_7 = cv2.blur(image, (7, 7))    img_blur_11 = cv2.blur(image, (11, 11))

Чем больше размер ядра, тем более размытым будет становиться изображение:



Gaussian


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



Это размытие реализуется в opencv с помощью функции GaussianBlur(), которая принимает первые два аргумента такие же как и предыдущая функция, а третьим аргументом указываем стандартное отклонение ядра Гаусса. Установив это значение в 0, мы тем самым говорим opencv автоматически вычислять его, в зависимости от размера нашего ядра:


def gaussian_blurring():    image = cv2.imread('girl.jpg')    img_blur_3 = cv2.GaussianBlur(image, (3, 3), 0)    img_blur_7 = cv2.GaussianBlur(image, (7, 7), 0)    img_blur_11 = cv2.GaussianBlur(image, (11, 11), 0)

Median


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


def median_blurring():    image = cv2.imread('girl.jpg')    img_blur_3 = cv2.medianBlur(image, 3)    img_blur_7 = cv2.medianBlur(image, 7)    img_blur_11 = cv2.medianBlur(image, 11)

В результате у нас получится следующее:



На этом данная часть подошла к концу. Код, как всегда, доступен на github. До скорой встречи:)

Источник: habr.com
К списку статей
Опубликовано: 26.01.2021 00:16:12
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