Наложение изображений разного размера и количества каналов - PullRequest
0 голосов
/ 23 ноября 2018

Я пытаюсь наложить случайные изображения (естественные изображения сцены должны быть наложены на изображения знаков), используя OpenCV и Python.Они могут различаться по размеру, расширению файла и нет.каналов (и многое другое, я думаю).Поэтому я изменяю размеры изображений знаков в соответствии с размером естественного изображения сцены и помещаю их в последнее.

Я реализовал код Fireant, найденный здесь: наложение меньшего изображения на Python большего изображенияOpenCv

Но это работает только для изображений с 4 каналами.

Использование cv2.addWeighted () всегда обрезает большое изображение (изображение сцены) до размера меньшего изображения (изображение знака).Кто-нибудь знает, как это сделать?Помощь высоко ценится.

РЕДАКТИРОВАТЬ: см. Ожидаемый результат ниже.Сначала знак пути эвакуации и фон являются отдельными изображениями.Expected output

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

import cv2
import time
import math
import os

pathSigns = "/home/moritz/Schreibtisch/Signs"
pathScenes = "/home/moritz/Schreibtisch/Scenes"
i = 0

for fSigns in os.listdir(pathSigns):
    fSigns = os.path.join(pathSigns, fSigns)
    s_img = cv2.imread(fSigns, -1)

    for fScenes in os.listdir(pathScenes):
        try:
            l_img = cv2.imread(os.path.join(pathScenes, fScenes))
            l_height, l_width, l_channels = l_img.shape

            TARGET_PIXEL_AREA = (l_height * l_width) * 0.05

            ratio = float(s_img.shape[1]) / float(s_img.shape[0])
            s_new_h = int(math.sqrt(TARGET_PIXEL_AREA / ratio) + 0.5)
            s_new_w = int((s_new_h * ratio) + 0.5)

            s_img = cv2.resize(s_img,(s_new_w, s_new_h))

            x_offset=y_offset=50
            # l_img[y_offset:y_offset+s_img.shape[0], 
               x_offset:x_offset+s_img.shape[1]] = s_img

            y1, y2 = y_offset, y_offset + s_img.shape[0]
            x1, x2 = x_offset, x_offset + s_img.shape[1]

            height, width, channels = s_img.shape

            if channels <= 3:
                alpha_s = s_img[:, :, 2] / 255.0
                alpha_l = 1.0 - alpha_s
            else:
                alpha_s = s_img[:, :, 3] / 255.0
                alpha_l = 1.0 - alpha_s

            for c in range(0, 3):
                l_img[y1:y2, x1:x2, c] = (alpha_s * s_img[:, :, c] +
                  alpha_l * l_img[y1:y2, x1:x2, c])

            fResult = "/home/moritz/Schreibtisch/results/data_" + str(i) + 
                   ".png"
            i += 1
            cv2.imwrite(fResult, l_img)
        except IndexError:
            pass

1 Ответ

0 голосов
/ 26 ноября 2018

благодаря подсказке @ DanMašek и Как обрезать или удалить белый фон с изображения , я разработал решение.Следующий код сначала удалит белый фон с меньшего изображения, затем установит все изображения на 4 канала и затем наложит большее изображение на меньшее.У меня работает.

import cv2
import time
import math
import os
import numpy as np

pathSigns = "/home/moritz/Schreibtisch/Signs"
pathScenes = "/home/moritz/Schreibtisch/Scenes"
i = 0

for fSigns in os.listdir(pathSigns):
    fSigns = os.path.join(pathSigns, fSigns)
    s_img = cv2.imread(fSigns, -1)
    s_height, s_width, s_channels = s_img.shape

    # crop image
    gray = cv2.cvtColor(s_img, cv2.COLOR_BGR2GRAY)
    th, threshed = cv2.threshold(gray, 240, 255, cv2.THRESH_BINARY_INV)

    kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (11,11))
    morphed = cv2.morphologyEx(threshed, cv2.MORPH_CLOSE, kernel)

    _, cnts, _ = cv2.findContours(morphed, cv2.RETR_EXTERNAL, 
    cv2.CHAIN_APPROX_SIMPLE)
    cnt = sorted(cnts, key=cv2.contourArea)[-1]
    x,y,w,h = cv2.boundingRect(cnt)
    s_img = s_img[y:y+h, x:x+w]

    # set channels to 4
    if s_channels < 4:
        s_img = cv2.cvtColor(s_img, cv2.COLOR_BGR2BGRA)

    for fScenes in os.listdir(pathScenes):
        try:
            l_img = cv2.imread(os.path.join(pathScenes, fScenes))
            l_height, l_width, l_channels = l_img.shape

            if l_channels < 4:
                l_img = cv2.cvtColor(l_img, cv2.COLOR_BGR2BGRA)

            TARGET_PIXEL_AREA = (l_height * l_width) * 0.05

            ratio = float(s_img.shape[1]) / float(s_img.shape[0])
            s_new_h = int(math.sqrt(TARGET_PIXEL_AREA / ratio) + 0.5)
            s_new_w = int((s_new_h * ratio) + 0.5)

            s_img = cv2.resize(s_img,(s_new_w, s_new_h))

            x_offset=y_offset=50

            y1, y2 = y_offset, y_offset + s_img.shape[0]
            x1, x2 = x_offset, x_offset + s_img.shape[1]

            alpha_s = s_img[:, :, 3] / 255.0
            alpha_l = 1.0 - alpha_s

            for c in range(0, 3):
                l_img[y1:y2, x1:x2, c] = (alpha_s * s_img[:, :, c] + alpha_l * 
                 l_img[y1:y2, x1:x2, c])

            fResult = "/home/moritz/Schreibtisch/results/data_" + str(i) + ".png"
            i += 1
            cv2.imwrite(fResult, l_img)
        except IndexError:
            pass
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...