Перейти к содержимому

Как разделить изображение python

  • автор:

Разделение изображений на равные части с использованием OpenCV Python

Библиотека Python OpenCV позволяет нам использовать различные инструменты обработки изображений, такие как классификация изображений, обнаружение лиц/объектов, отслеживание и многое другое.

В этой статье мы будем использовать методы нарезки списка Python или нарезки массива numpy, чтобы разделить изображение на равные части, поскольку OpenCV-python использует массив Numpy для хранения данных изображения/значений пикселей.

Сценарии ввода-вывода

Предполагая, что у нас есть входное изображение, а на выходе мы увидим поровну разделенные части данного изображения.

Подход

Мы выполним следующие шаги, чтобы разделить изображения на равные части.

  • Загрузите изображение.
  • Извлеките размеры изображения и сохраните их в переменной.
  • Разделите массив изображений, используя технику нарезки Python.
  • Наконец, сохраните отдельные части.

Пример

В этом примере мы разделим входное изображение «cat.jpg» по горизонтали на 2 части.

import cv2 image= cv2.imread('Images/cat.jpg') height, width, channels = image.shape half_height = height//2 top_section = image[:half_height, :] bottom_section = image[half_height:, :] cv2.imshow('Top', top_section) cv2.imshow('Bottom', bottom_section) cv2.waitKey(0) 

Входное изображение

Вывод изображений

Пример

В этом примере мы разделим входное изображение «logo.png» на 4 равные части.

import cv2 import numpy as np def divide_img_blocks(img, n_blocks=(2,2)): horizontal = np.array_split(img, n_blocks[0]) splitted_img = [np.array_split(block, n_blocks[1], axis=1) for block in horizontal] return np.asarray(splitted_img, dtype=np.ndarray).reshape(n_blocks) result = divide_img_blocks(cv2.imread('Images/logo.png')) for i in range(result.shape[0]): for j in range(result.shape[1]): cv2.imwrite(f"Output Images/my_block__.jpg", result[i,j]) 

Входное изображение

Вывод изображений

Пример

При таком подходе мы разделим входное изображение «Lenna.png» на 9 равных частей.

import cv2,time img = cv2.imread('Images/Lenna.png') img2 = img height, width, channels = img.shape # Number of pieces Horizontally W_SIZE = 3 # Number of pieces Vertically to each Horizontal H_SIZE = 3 for ih in range(H_SIZE ): for iw in range(W_SIZE ): x = width/W_SIZE * iw y = height/H_SIZE * ih h = (height / H_SIZE) w = (width / W_SIZE ) print(x,y,h,w) img = img[int(y):int(y+h), int(x):int(x+w)] NAME = str(time.time()) cv2.imwrite("Output Images/" + str(ih)+str(iw) + ".png",img) img = img2 

Выход

0.0 0.0 124.0 223.0 223.0 0.0 124.0 223.0 446.0 0.0 124.0 223.0 0.0 124.0 124.0 223.0 223.0 124.0 124.0 223.0 446.0 124.0 124.0 223.0 0.0 248.0 124.0 223.0 223.0 248.0 124.0 223.0 446.0 248.0 124.0 223.0 

Входное изображение

Вывод изображений

В приведенном выше примере изображение сначала разделится на 3 горизонтальные части, а затем для каждой из этих 3 частей будет обрезано еще 3 изображения, в результате чего останется всего 9 частей. Измените значения W_SIZE и H_SIZE , чтобы указать, сколько равных частей нам нужно, чтобы разделить изображение.

Во всех приведенных выше примерах мы успешно разделили входные изображения на равные части.

Все права защищены. © Linux-Console.net • 2019-2023

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: 255 opencv subtract: 0 numpy addition: 24 numpy 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. До скорой встречи:)

Разделение и объединение каналов с помощью OpenCV Python

Стандартное цифровое цветное изображение представлено пикселями, каждый пиксель представляет собой комбинацию основных цветов. А канал — это изображение в оттенках серого, состоящее только из одного из основных цветов цветного изображения. Например, изображение RGB имеет три канала: красный, зеленый и синий.

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

Ниже изображений в оттенках серого представлен каждый канал изображения RGB.

В этой статье мы обсудим, как разделить и объединить каналы изображения с помощью библиотеки Python openCV.

Разделение каналов

Модуль Python OpenCV предоставляет функцию cv2.split() для разделения многоканального/цветного массива на отдельные одноканальные массивы. Он вернет массив с тремя каналами, каждый из которых соответствует синему, зеленому и красному каналам, представленным в виде двухмерного массива ndarray.

Синтаксис

cv2.split(m[, mv]) 
  • src – входной многоканальный массив.
  • mv – выходной массив или вектор массивов

Пример

В этом примере мы возьмем цветное изображение «OpenCV_logo.png» и разделим его на 3 канала.

import cv2 image = cv2.imread('Images/OpenCV_logo.png') #split the image into its three channels (b_channel, g_channel, r_channel) = cv2.split(image) #display the images cv2.imshow('blue channel',b_channel) cv2.imshow('green channel',g_channel) cv2.imshow('red channel',r_channel) cv2.waitKey(0) cv2.destroyAllWindows() 

Входное изображение

Вывод изображений

Цветное изображение «OpenCV_logo.png» было разделено на три изображения в оттенках серого: r_channel («Красный канал»), g_channel (Зеленый), b_channel (Синий).

Объединение каналов

Функция cv2.merge() принимает одноканальные массивы и объединяет их в многоканальный массив/изображение. Возвращает массив конкатенации элементов входных массивов. Ниже приведен синтаксис функции merge():

cv2.merge(mv[, dst]) 

Параметры

  • mv: входной вектор объединяемых матриц. все матрицы должны иметь одинаковый размер и одинаковую глубину.
  • count: должно быть больше нуля. Задает количество входных матриц, если входной вектор представляет собой простой массив C.
  • dst: выходной массив того же размера и той же глубины, что и входной массив.

Пример

Давайте объединим отдельные синий, зеленый и красный каналы в изображение BGR.

import cv2 image = cv2.imread('Images/OpenCV_logo.png') #split the image into its three channels (b_channel, g_channel, r_channel) = cv2.split(image) #display the images cv2.imshow('blue channel',b_channel) cv2.imshow('green channel',g_channel) cv2.imshow('red channel',r_channel) # merge the image image_merged = cv2.merge((b_channel,g_channel,r_channel)) cv2.imshow('merged image',image_merged) cv2.waitKey(0) cv2.destroyAllWindows() 

Входное изображение

Выходное изображение

Пример

В этом примере мы преобразуем изображение в CMYK, а затем разделим каналы.

import cv2 import numpy as np rgb = cv2.imread('Images/Tajmahal.jpg') rgbdash = rgb.astype(np.float)/255. K = 1 -np.max(rgbdash, axis=2) C = (1-rgbdash [. 2] - K)/(1-K) M = (1-rgbdash [. 1] - K)/(1-K) Y = (1-rgbdash [. 0] - K)/(1-K) # Convert the input BGR image to CMYK colorspace CMYK = (np.dstack((C,M,Y,K)) * 255).astype(np.uint8) # Split CMYK channels Y, M, C, K = cv2.split(CMYK) # display the images cv2.imshow("Cyan",C) cv2.imshow("Magenta", M) cv2.imshow("Yellow", Y) cv2.imshow("Key", K) if cv2.waitKey(0): cv2.destroyAllWindows() 

Входное изображение

Выходное изображение Голубой

Выходное изображение Пурпурный

Выходное изображение Желтый

Ключ выходного изображения

В приведенном выше примере изображение RGB было преобразовано в CMYK и разделено на четыре канала: голубой, пурпурный, желтый и ключевой.

Все права защищены. © Linux-Console.net • 2019-2023

Как разделить картинку на блоки?

Пример картинки
5f524ee340405864867217.jpeg
блоки
5f524ef53ca72877116576.png
5f524efd4c978140211944.png
5f524f0476d04587879790.png
5f524f0bd5e75585424228.png
5f524f1367731414184943.png
Код

from PIL import Image import pytesseract import cv2 import os pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files (x86)\Tesseract-OCR\tesseract.exe' base_dir = os.path.dirname(os.path.abspath(__file__)) image = base_dir + r'\tmp\test2 (5).PNG' d = Image.open(image) preprocess = "thresh" # загрузить образ и преобразовать его в оттенки серого image = cv2.imread(image) gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # проверьте, следует ли применять пороговое значение для предварительной обработки изображения if preprocess == "thresh": gray = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1] # если нужно медианное размытие, чтобы удалить шум elif preprocess == "blur": gray = cv2.medianBlur(gray, 3) # сохраним временную картинку в оттенках серого, чтобы можно было применить к ней OCR filename_dir = base_dir +"\gray\<>.png".format(os.getpid()) cv2.imwrite(filename_dir, gray) # загрузка изображения в виде объекта image Pillow, применение OCR, а затем удаление временного файла text = pytesseract.image_to_string(Image.open(filename_dir)) print(text) #os.remove(filename_dir) # показать выходные изображения cv2.imshow("Image", image) cv2.imshow("Output", gray)
  • Вопрос задан более трёх лет назад
  • 401 просмотр

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *