Возвращение значений из многопроцессорной функции - PullRequest
0 голосов
/ 12 декабря 2018

Я столкнулся с проблемой при использовании многопроцессорного модуля в Python.Моя цель - создать m * n процессов (где m * n - размеры изображения) и изменить все значения пикселя (в приведенном ниже коде измените значение с 0 на 255).Внутри функции я могу видеть значения пикселей, меняющихся с помощью функции печати.Но когда я отображаю выводимое изображение в конце, содержимое изображения не изменяется.Может кто-нибудь сообщить мне, в чем проблема?

import cv2
import numpy
import multiprocessing

def func(i,j,img_op):
    #print("For pixel",i,j)
    img_op[i][j]=255
    print("For pixel", i, j,"\t",img_op[i][j])
    return img_op[i][j]

img=cv2.imread('pokemon.png',0)
height = numpy.size(img, 0)
width = numpy.size(img, 1)
img_op=numpy.zeros((height,width,1),numpy.uint8)

print(height,width)

processes=[]
for i in range(0,height-2):
    for j in range(0,width-2):
        p=multiprocessing.Process(target=func,args=(i,j,img_op,))
        processes.append(p)
        p.start()

for p in processes:
    p.join()

cv2.imshow('Original image',img)
cv2.imshow('White IMage',img_op)
cv2.waitKey(0)
cv2.destroyAllWindows()

1 Ответ

0 голосов
/ 12 декабря 2018

Это на самом деле сложная проблема, связанная с низкоуровневыми системными примитивами, такими как fork и mmap

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

много обходных путей, но самым простым будет использование отображения памяти.Отображение памяти - это объект, созданный системным вызовом mmap, который отображает часть диска в ОЗУ и доступен как дескриптор файла.Поскольку файловые дескрипторы на самом деле не копируются в fork, они фактически будут общими для всех процессов.

К счастью, numpy определяет абстракцию традиционного объекта mmap, который имеет интерфейс массива: np.memmap,Как я уже говорил, отображение памяти поддерживается файлом на диске, поэтому вам необходимо указать ему путь и режим доступа.

Вы можете определить свой глобальный образ следующим образом:

img_op = np.memmap(
    "/tmp/shared_image", dtype=np.uint8, mode='w+', shape=(height, width, 1)
)

Поскольку объект np.memmap имеет интерфейс массива, его можно использовать где угодно, так же как и обычный массив.

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