Функция изменения исходного изображения - PullRequest
0 голосов
/ 12 июля 2020

Я использую OpenCV с Python и пытаюсь использовать многопроцессорную обработку изображения. Изображение 100x100, и я запустил 4 процесса. Все изображение было разделено на четыре части. Это один процесс:

processes = []
_ = mp.Process(target=kill, args=[blue[0:40, 0:47],0, 2])
_.start()
processes.append(_)

После этого я просто присоединяюсь ко всем процессам.

Это моя функция:

def kill(sliced, idx, perc):
    for i in range (0, sliced.shape[0]):
        for j in range (0, sliced.shape[1]):
            if perc* sliced[i][j][0] - sliced[i][j][1] - sliced[i][j][2] < 0:
                for k in range(0, 3):
                    sliced[i][j][k] = 0  #I am expecting this to alter my "blue" image

Итак, я ожидал следующего , если бы я должен был cv2.imshow("blue", blue) увидеть изображение с затемненными пикселями. Проблема в том, что это, кажется, не изменяет исходное изображение blue.

Я передаю каждому процессу нарезанное изображение. После завершения процессов я ожидал, что мое исходное изображение будет изменено, вместо этого оно не изменилось. Передача нарезанного изображения и его изменение не должны изменять исходное изображение? Есть ли что-нибудь для копирования / буфера?

1 Ответ

2 голосов
/ 12 июля 2020

Многопроцессорность - IMO действительно не подходит для подобных вещей, ее лучше всего использовать для одновременной обработки нескольких независимых изображений. Он порождает отдельные процессы, что означает отсутствие общей памяти и необходимость «пересылки» данных от одного процесса к другому, что влечет за собой накладные расходы. Поэтому лучше всего использовать его для полностью независимых операций обработки. Кроме того, создание процессов требует времени, которое не оправдывается очень простой операцией, которую вы реализуете.

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

Предполагая, что image - это массив NumPy, считанный через OpenCV:

mask = perc * image[:,:,0] - image[:,:,1] - image[:,:,2] < 0
image[np.broadcast_to(mask[:,:,np.newaxis], image.shape)] = 0

Вторая строка довольно сложна, потому что mask - это 2D-матрица, а image - 3D-матрица. Поэтому нам нужно расширить mask до 3D и того же размера, что и image, реплицируя его в новом, третьем измерении. mask[:,:,np.newaxis] - это 3D-версия 2D-матрицы, добавляющая 3-е измерение размера 1. np.broadcast_to() затем копирует размеры размера 1 в запрошенную форму, image.shape. Эту расширенную маску теперь можно использовать для индексации в image. Путем индексации с использованием маски (логической матрицы) мы выбираем только те элементы матрицы image, где mask равно True. Таким образом, назначение изменяет только выбранные пиксели.

Другой важный инструмент для ускорения циклов в Python с помощью NumPy - Numba . Если операция не может быть легко векторизована, попробуйте этот подход.

...