Как эффективно перебирать разделенные изображения с помощью многопроцессорной обработки? - PullRequest
2 голосов
/ 24 июня 2019

enter image description hereenter image description here Я изучаю проектирование информационных систем и мне нужно внезапно использовать многопоточность / обработку в моей работе, но нас никогда не учили этому в университете так что я понятия не имею об этом. Я только прочитал некоторое введение за прошлые несколько дней. С этой помощью я даже получил несколько простых тестовых программ для улучшения производительности, но я не смог сделать это для этой задачи.

У меня есть картинка с краями объектов в виде белых точек (значение 255 в массиве). Теперь мне нужно узнать позицию в массиве этих точек.

Поскольку изображения представляют собой довольно большие массивы, и мне нужно оптимизировать это для Raspberry Pi, мне нужно запрограммировать это с учетом многопроцессорности, потому что в тесте я получил только 25% загрузки ЦП на pi над 1 ядром, и это не было достаточно для обработки видео в реальном времени.

def test_multi(self):
pool = mp.Pool(processes=4)
test_prep = self.test_prep.copy()
y, x = test_prep.shape
columns = []
for i in range(4):
    c = test_prep[0:y, 0:int(x/4)*(i+1)]
    c = copy(c)
    columns.append(c)
results = [pool.apply_async(search, args=(c,)) for c in columns]
for r in results:
    print(r.get())

def search(picture):
ys, xs = picture.shape
dots = []
for x in range(xs):
    for y in range(ys):
        if picture[y][x] == 255:
            dots.append((x, y))
return dots

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

Я попытался переключиться на многопоточность, но некоторые люди говорили, что GIL не разрешит распределение по отдельным ядрам.

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

Мне нужны 4 списка с координатами точек в 4 различных столбцах изображения, и я хочу, чтобы функция поиска выполнялась параллельно, распределенной по 4 ядрам. Или другой процесс, который позволяет искать изображение 1920 * 1080 быстрее, чем за полсекунды.

UPDATE:

Как отметил Марк Сетчелл, я сейчас использую cv2.findContour (), но, как я уже говорил, иногда он обнаруживает один контур как несколько, поэтому я добавил подпрограмму, которая комбинирует середину контура, которые очень похожи на это:

def search(image):
    ret, thresh = threshold(image, 0, 255, 0)
    contours, hierarchy = findContours(thresh, RETR_TREE, CHAIN_APPROX_SIMPLE)
    objects = []
    for c in contours:
        objects.append(middle(c))
    any_neighbors = False
    while not any_neighbors:
        objects, any_neighbors = combine(objects)
    return objects

def combine(objects):
    ret = objects
    any_neighbors = False
    for o1 in objects:
        for o2 in objects:
            if is_neighbor(o1, o2):
                ret.remove(o1)
                any_neighbors = True
    return ret, any_neighbors

def middle(contour):
    xs = 0
    ys = 0
    size = len(contour)
    for c in contour:
        xs += c[0][0]
        ys += c[0][1]
    xs = int(xs/size)
    ys = int(ys/size)
    return xs, ys

def is_neighbor(p1, p2):
    return p1[0] - th <= p2[0] <= p1[0] + th and p1[1] - th <= p2[1] <= p1[1] + th

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

1 Ответ

0 голосов
/ 25 июня 2019

Процесс стал таким же быстрым, как и другие части программы.Вот почему многопроцессорная обработка больше не нужна.

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