Использование многопоточности для быстрой обработки изображения на python? - PullRequest
4 голосов
/ 10 января 2012

В скрипте Python + Python Image Library есть функция processPixel (image, pos), которая вычисляет математический индекс в зависимости от изображения и позиции на нем. Этот индекс рассчитывается для каждого пикселя с использованием простого цикла for:

for x in range(image.size[0)):
    for y in range(image.size[1)):
        myIndex[x,y] = processPixel(image,[x,y])

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

Ответы [ 3 ]

6 голосов
/ 10 января 2012

Вы не можете ускорить его, используя многопоточность из-за Глобальной блокировки интерпретатора .Определенное внутреннее состояние интерпретатора Python защищено этой блокировкой, которая предотвращает одновременную работу разных потоков, которым необходимо изменить это состояние.

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

В зависимости от вашей задачи вы можете распараллелить обработку одного изображения, разделив его, или выМожно распараллелить обработку списка изображений (последнее легко сделать с помощью pool).Если вы хотите использовать первое, вы можете сохранить изображение в Array, к которому можно обращаться как к общей памяти, но вам все равно придется решить проблему, где записывать результаты(запись в общую память может сильно ухудшить производительность).Также обратите внимание, что определенные виды связи между процессами (очереди, каналы или передача параметра / возвращаемого значения некоторой функции в модуле) требуют сериализации данных с использованием Pickle .Это накладывает определенные ограничения на данные и может привести к значительному снижению производительности (особенно если у вас много небольших задач).

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

1 голос
/ 11 января 2012

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

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

PyOpenCL позволяет получать доступ к графическим процессорам и другим массово параллельным вычислительным устройствам из Python.

PyCUDA является дочерним проектом для PyOpenCL

NumPy и SciPy являются фундаментальными пакетами для выполнения научных вычислений, которые могут быть полезны с вышеуказанными пакетами для эффективной обработки изображений и массивов.

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

0 голосов
/ 10 января 2012

Взгляните на учебник Дуга Хеллмана по многопроцессорности.Как указывает Бьёрн, есть несколько проблем, связанных с параллельной обработкой, которые вам необходимо освоить, но это может стоить усилий.

Совет: вы можете использовать multiprocessing.cpu_count () чтобы проверить количество доступных вам ядер.

...