dlib / cv2 Работа с сотнями тысяч картинок

1

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

Я должен:

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

На компьютере, который мне дал университет, я мог делать около 40 изображений каждую минуту, около 57 тысяч изображений каждые 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). Есть ли более быстрый способ добиться этого?

Теги:
python-3.x
dlib
image
cv2

1 ответ

0

Прежде всего, прости меня, потому что я знаком только с 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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню