Объединенные вычисления когда-нибудь без причины - PullRequest
1 голос
/ 16 октября 2019

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

Я могу выполнить свою функцию пула один раз. Это работает.

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

Время выполнения всегда одинаково, около секунды,и так же поведение загрузки процессора. 4 ядра загружаются до 100%, и они падают через секунду.

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

При вызовеЦП не загружается, а функция пула в конечном итоге отключается через 100 секунд.

Вот код функции пула:

def compute_pooled(source, img1, img2, img3, n_features, scale_factor, n_levels, lowe_ratio):

    pool = Pool()

    image_same        = same
    image_similar     = similar
    image_different   = different
    #confidence = get_match_confidence(image, img2)

    args_same = [image_same,source, n_features, scale_factor, n_levels, lowe_ratio]
    args_similar = [image_similar,source, n_features, scale_factor, n_levels, lowe_ratio]
    args_different = [image_different,source, n_features, scale_factor, n_levels, lowe_ratio]

    result_same = pool.apply_async(match_with_orb, args_same)
    result_similar = pool.apply_async(match_with_orb, args_similar)
    result_different = pool.apply_async(match_with_orb, args_different)

    good_same = result_same.get(timeout=100)
    good_similar = result_similar.get(timeout=100)
    good_different = result_different.get(timeout=100)

    values = [good_same, good_similar, good_different]

    ## I tried closing, terminating, not doing anything..
    pool.close()
    return values

А вот код вызываемой функции внутри каждого пула:

def match_with_orb(img1, img2, n_features, scale_factor, n_levels, lowe_ratio):
    orb = cv2.ORB_create(nfeatures=n_features, scaleFactor=scale_factor, nlevels=n_levels)
    keypoints_orb1, descriptors1 = orb.detectAndCompute(img1, None)
    keypoints_orb2, descriptors2 = orb.detectAndCompute(img2, None)

    bf = cv2.BFMatcher()

    matches = bf.knnMatch(descriptors1,descriptors2, k=2)
    method='orb'

    good = []

    for m,n in matches:
        if m.distance < lowe_ratio*n.distance:
            good.append([m])

    return len(good)

Если я выполнюСледующие инструкции все работает нормально:

import numpy as np
import cv2
from matplotlib import pyplot as plt
from pathlib import Path
from multiprocessing import Pool, cpu_count

imgname_source = 'source.jpg'
img1 = 'img1.jpg'
img2 = 'img2.jpg'
img3 = 'img3.jpg'

dirPath = '/home/path/to/imgs/'

source     = cv2.imread(dirPath+imgname_source,0)
_img1       = cv2.imread(dirPath+img1,0)
_img2    = cv2.imread(dirPath+img2,0)
_img3  = cv2.imread(dirPath+img3,0)

compute_pooled(source, _img1, _img2, _img3, 5000, 1.15, 16, 0.67)

Он выполняется менее чем за секунду при загрузке процессора 100%. Если я снова вызываю функцию compute_pooled, она работает таким же образом.

Теперь со следующей функцией:

def rotate(image, angle, center=None, scale=1.0):
    (h, w) = image.shape[:2]
    if center is None:
        center = (w // 2, h // 2)
    M = cv2.getRotationMatrix2D(center, angle, scale)
    rotated = cv2.warpAffine(image, M, (w, h))
    return rotated

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

## First call works
compute_pooled(source, _img1, _img2, _img3, 5000, 1.15, 16, 0.67) 
_img4 = rotate(_img1, 90)
## Second call times out
compute_pooled(source, _img1, _img2, _img3, 5000, 1.15, 16, 0.67) 

В чем здесь проблема? Я абсолютно не понимаю, почему второй вызов истекает без запуска каких-либо расчетов.

Вот ошибка. Время ожидания не удается получить какие-либо результаты от первого вызова .get ().

--> 223     good_same = result_same.get(timeout=100)
    224     good_similar = result_similar.get(timeout=100)
    225     good_different = result_different.get(timeout=100)

~/anaconda3/lib/python3.7/multiprocessing/pool.py in get(self, timeout)
    651         self.wait(timeout)
    652         if not self.ready():
--> 653             raise TimeoutError
    654         if self._success:
    655             return self._value

TimeoutError: 

...