Разделение изображений переднего и заднего плана для создания различных синтетических изображений. Субъективный анализ изображения для проверки реалистичности.

Вступление

Из эволюции архитектур глубокого обучения очевидно, что объект переднего плана или человека можно легко отделить от заднего плана. После того, как объект переднего плана сегментирован, его можно наложить на другое изображение. Но это требует времени и сложностей. Я говорю о подготовке набора данных, сетевой архитектуры и обучения. Сложности заключаются в подготовке данных и настройке модели.

До эволюции архитектур глубокого обучения и прорыва вычислительной мощности люди использовали минимальное количество изображений. Было использовано минимальное количество изображений, потому что не было прорыва в вычислительной мощности. Минимальное количество изображений было создано на основе синтетических данных с использованием переднего плана, разделения фона, а также синтетических данных, созданных из моделей 3D CAD. Давайте вернемся в прошлое и посмотрим, сможем ли мы увидеть реалистичность этих данных. Кроме того, давайте узнаем немного о open-cv, которое пригодится при обработке данных изображения.

Блок-схема:

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

Описание

Вот процесс, объясненный словами и рассуждениями:

Итак, сначала мы берем изображение переднего плана и делаем его прозрачным. Прозрачность важна, потому что она облегчит наложение на фоновое изображение. По сути, это процесс преобразования RGB в RGBA, добавления альфа-канала и представления его в виде кортежа. Затем прочтите фоновое изображение и убедитесь, что вместо 3 каналов присутствуют 4 канала.

Когда изображение переднего плана и фоновое изображение будут готовы, давайте объединим их вместе. Итак, теперь я должен подумать о размере изображения переднего плана, очевидно, он не может быть того же размера, что и фон. Измените размер изображения переднего плана и установите положение в фоновом изображении. Теперь смешайте изображение с этим смещением по осям x и y с фоном, используя методологии цикла for и нарезки.

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

Код

Давайте импортируем необходимые библиотеки

import cv2 
import math 
import numpy as np 
from PIL import Image

Укажите путь, преобразуйте изображение переднего плана в прозрачное

foregrnd_img = 'foreground.jpg'
backgrnd_img = 'background.jpg'
def convertTransparent(path):
    img = Image.open(path)
    img = img.convert("RGBA")
    datas = img.getdata()
newData = []
    for item in datas:
        if item[0] == 255 and item[1] == 255 and item[2] == 255:
            newData.append((255, 255, 255, 0))
        else:
            if item[0] > 255:
                newData.append((0, 0, 0, 255))
            else:
                newData.append(item)
    
    img.putdata(newData)
    return img
fore_img = np.array(convertTransparent(foregrnd_img))
fore_height, fore_width, fore_channels = fore_img.shape
fore_img = image_resize(fore_img, 100)

Изменение размера изображения переднего плана, установка смещения для того же самого фонового изображения и смешивание обоих изображений можно выполнить, как показано ниже.

# set channels to 4
if fore_channels < 4:
    fore_img = cv2.cvtColor(fore_img, cv2.COLOR_BGR2BGRA)
try:
    # read the background image
    backgrnd_img = cv2.imread(backgrnd_img)
    backgrnd_height, backgrnd_width, backgrnd_channels = backgrnd_img.shape
# check if backgrnd_img as same channels as foregrnd_img
    if backgrnd_channels < 4:
        backgrnd_img = cv2.cvtColor(backgrnd_img, cv2.COLOR_BGR2BGRA)
TARGET_PIXEL_AREA = (backgrnd_height * backgrnd_width) * 0.05
# resize the foregrnd based on backgrnd_img size
    ratio = float(fore_img.shape[1]) / float(fore_img.shape[0])
    fore_img_new_h = int(math.sqrt(TARGET_PIXEL_AREA / ratio) + 0.5)
    fore_img_new_w = int((fore_img_new_h * ratio) + 0.5)
fore_img = cv2.resize(fore_img,(fore_img_new_w, fore_img_new_h))
# set the x-y off-set 
    x_offset= 300
    y_offset= 135
y1, y2 = y_offset, y_offset + fore_img.shape[0]
    x1, x2 = x_offset, x_offset + fore_img.shape[1]
alpha_fore_img = fore_img[:, :, 3] / 255.0
    alpha_l = 1.0 - alpha_fore_img
# create RGBA image 
    for c in range(0, 3):
        backgrnd_img[y1:y2, x1:x2, c] = (alpha_fore_img * fore_img[:, :, c] + alpha_l * 
         backgrnd_img[y1:y2, x1:x2, c])
# save the image
    fResult = "synthetic_image.png"
cv2.imwrite(fResult, backgrnd_img)
except IndexError:
    pass

Результаты для следующего кода и эксперимента приведены ниже:

Изображение переднего плана

Фоновое изображение

Синтетическое изображение с передним и задним планами

Заключение

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

Но если мы будем использовать эти данные изображения для задач классификации, этого будет недостаточно для достижения цели. Так что реализм не выдержан. Возможно, стоит поискать методы глубокого обучения с использованием GAN для создания изображений с разным фоном для сохранения реализма. Это может быть следующий проект в разработке. 😉

Больше контента на plainenglish.io