dlib / cv2 Работа с сотнями тысяч картинок - PullRequest
0 голосов
/ 30 ноября 2018

Для моего следующего университетского проекта мне нужно будет научить Извилистую Нейронную Сеть, как обесценивать изображение лица, поэтому я начал копать нам наборы данных лиц.Я наткнулся на этот набор данных ( CelebA ) с 200k + фотографиями людей и обнаружил первые несколько проблем: слишком много картинок, чтобы выполнить базовые вычисления на них.

Я должен:

  1. Откройте каждое изображение и сделайте из него массивный массив (dlib.load_rgb_image в порядке)
  2. Найдите лицо, используйте 5-точечный предсказатель формы, чтобы найти глаза и выровнять их
  3. Поверните изображение так, чтобы глаза находились на прямой горизонтальной линии
  4. Обрежьте лицо и измените его размер до 256x256 (я мог бы выбрать 64x64, но это не сильно экономит время)
  5. Сделайте копию и добавьте к ней искусственный шум
  6. Сохраните их обе в две разные папки

На компьютере, который дал мне университет, я мог делать около 40 изображений каждую минуту, примерно57k изображений каждые 24 часа.

Чтобы ускорить процесс, я пробовал темы;одна нить для каждой картинки, но ускорение примерно на 2-3 картинки больше в минуту.

Это код, который я запускаю:

### Out of the threads, before running them ###
def img_crop(img, bounding_box):
    # some code using cv2.copyMakeBorder to crop the image

MODEL_5_LANDMARK = "5_point.dat"
shape_preditor = dlib.shape_predictor(MODEL_5_LANDMARK)
detector = dlib.get_frontal_face_detector()


### Inside each thread ###
img_in = dlib.load_rgb_image("img_in.jpg")
dets = detector(img_in, 1)
shape = shape_preditor(img_in, dets[0])

points = []
for i in range(0, shape.num_parts):
    point = shape.part(i)
    points.append((point.x, point.y))

eye_sx = points[1]
eye_dx = points[3]

dy = eye_dx[1] - eye_sx[1]
dx = eye_dx[0] - eye_sx[0]
angle = math.degrees(math.atan2(dy, dx))

center = (dets[0].center().x, dets[0].center().y)
h, w, _ = img_in.shape
M = cv2.getRotationMatrix2D(center, angle + 180, 1)
img_in = cv2.warpAffine(img_in, M, (w, h))

dets = detector(img_in, 1)
bbox = (dets[0].left(), dets[0].top(), dets[0].right(), dets[0].bottom())
img_out = cv2.resize(imcrop(img_in, bbox), (256, 256))
img_out = cv2.cvtColor(img_out, cv2.COLOR_BGR2RGB)

img_noisy = skimage.util.random_noise(img_out, ....)
cv2.imwrite('out.jpg', img_out)
cv2.imwrite('out_noise.jpg', img_noisy)

Мой язык программирования Python3.6Как я могу ускорить процесс?

Еще одной проблемой будет загрузка всех 200К изображений в память в виде массива, из моего первоначального тестирования 12К изображений займет около 80 секунд с окончательной формой (12000, 256, 256,3).Есть ли более быстрый способ добиться этого?

1 Ответ

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

Прежде всего, прости меня, потому что я знаком только с c ++.Ниже вы найдете мое предложение по ускорению работы dlib-функций и конвертации в вашу версию на python, если это полезно.

  1. Цвет не имеет значения для dlib.Поэтому перед тем, как сэкономить время, измените входное изображение на серое.

  2. Я видел, как вы дважды вызывали приведенную ниже функцию. Какова цель?это может удвоить время потребления.Если вам нужно получить новые ориентиры после выравнивания, попробуйте повернуть точки ориентиров непосредственно, а не заново обнаруживать. Как поворачивать точки

    dets = detector(img_in, 1)
    
  3. Поскольку вы просто хотите обнаружить только 1 лицо на изображение.Попробуйте установить pyramid_down на 6 (по умолчанию это 1 - разместить изображение на расстоянии, чтобы обнаружить больше лица).Вы можете проверить значение от 1 до 6

    dets = detector(img_in, 6)
    
  4. Включить инструкцию AVX.

Примечание: более подробную информацию можно найти здесь Dlib Github

...