Создание прозрачного изображения с нуля с помощью cv2 и наложение других изображений

Вопрос или проблема

Когда вы начинаете с прозрачного холста, изображения, добавленные к нему, не будут видны при сохранении; они видны при использовании cv2.imshow, но изображение теряет прозрачность. Это не произойдет, если холст является существующим изображением (cv2.imread).

Мой код:

import cv2
import numpy as np

image = np.zeros((240, 320, 4), dtype=np.uint8)

overlay = cv2.imread("transparent.png", cv2.IMREAD_UNCHANGED)

x, y = (0,0)
h, w = overlay.shape[:2]

alpha_overlay = (overlay[:, :, 3]) / 255.0
alpha_background = 1.0 - alpha_overlay

for c in range(0, 3):
    image[y : y + h, x : x + w, c] = (
        alpha_overlay * overlay[:, :, c]
        + alpha_background * image[y : y + h, x : x + w, c]
    )

cv2.imwrite("output.png", image)
cv2.imshow("output", image)
cv2.waitKey(0)
cv2.destroyAllWindows()

transparent.png

output.png

вывод cv2.imshow

Ответ или решение

Создание прозрачного изображения с использованием OpenCV (cv2) и наложение на него других изображений может быть немного запутанным, особенно когда дело доходит до сохранения результирующего изображения с прозрачностью. Давайте разберем ваш код и предложим решение для правильного сохранения изображения с прозрачным фоном.

Проблема

Вы начали с создания пустого изображения с альфа-каналом, но когда вы сохраняете его с помощью cv2.imwrite, OpenCV не сохраняет прозрачность в PNG-файлах, так как в OpenCV нет прямой поддержки альфа-канала для нового изображения, созданного с использованием np.zeros.

Решение

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

import cv2
import numpy as np

# Создаем черный (прозрачный) холст с 4 каналами (RGBA)
image = np.zeros((240, 320, 4), dtype=np.uint8)

# Загружаем изображение с альфа-каналом
overlay = cv2.imread("transparent.png", cv2.IMREAD_UNCHANGED)

# Проверяем, что изображение загружено успешно
if overlay is None:
    print("Ошибка: не удалось загрузить изображение transparent.png")
    exit()

x, y = (0, 0)
h, w = overlay.shape[:2]

# Извлекаем альфа-канал
alpha_overlay = overlay[:, :, 3] / 255.0
alpha_background = 1.0 - alpha_overlay

# Накладываем изображение
for c in range(0, 3):
    image[y:y + h, x:x + w, c] = (
        alpha_overlay * overlay[:, :, c] +
        alpha_background * image[y:y + h, x:x + w, c]
    )

# Устанавливаем альфа-канал для результирующего изображения
image[:, :, 3] = np.clip(np.max(overlay[:, :, 3], axis=2), 0, 255)

# Сохраняем изображение с прозрачным фоном в формате PNG
cv2.imwrite("output.png", image)

# Отображаем результат
cv2.imshow("output", image)
cv2.waitKey(0)
cv2.destroyAllWindows()

Объяснение решения

  1. Инициализация изображения: Мы создаем пустое изображение с 4 каналами (RGBA), чтобы поддерживать прозрачность.

  2. Загрузка изображения: Убедитесь, что изображение загружается корректно, проверяя, не равно ли overlay None.

  3. Накладывание изображения: Используя альфа-канал overlay, мы смешиваем цвета из overlay с цветами из image, тем самым создавая эффект наложения.

  4. Установка альфа-канала: Мы устанавливаем альфа-канал результирующего изображения, чтобы сохранить прозрачные области корректно.

  5. Сохранение изображения: Теперь мы можем сохранить результирующее изображение в формате PNG, который поддерживает прозрачность.

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

Оцените материал
Добавить комментарий

Капча загружается...