【问题标题】:When pasting an image on another image, how to keep the foreground image transparent?将图像粘贴到另一张图像上时,如何保持前景图像透明?
【发布时间】:2021-05-26 03:00:51
【问题描述】:

我正在尝试使用 OpenCV / Pillow 将图像放在另一个图像之上,同时保持前景图像透明。如果你看this image,你可以看到一切都很顺利,除了我不知道如何保持图像透明。

我尝试在我的程序中实现this StackOverflow solution by @fireant,但似乎没有任何效果。

如何正常执行index.py,但保持前景png透明?

图片

dot_transparent.png

image.jpg

index.py

​​>
import os
import numpy
import cv2
from PIL import Image
from os.path import join, dirname, realpath
import json

def upload_files():
    #https://github.com/Itseez/opencv/blob/master/data/haarcascades/haarcascade_frontalface_default.xml
    face_cascade = cv2.CascadeClassifier('/Users/matt/Python/LazerEyes/haarcascade_eye.xml')

    #https://github.com/Itseez/opencv/blob/master/data/haarcascades/haarcascade_eye.xml
    eye_cascade = cv2.CascadeClassifier('/Users/matt/Python/LazerEyes/haarcascade_eye.xml')

    img = cv2.imread('new.png')
    img_to_place = cv2.imread('dot_transparent.png')

    gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    gray_to_place = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    
    img_h, img_w = gray.shape
    img_to_place_h, img_to_place_w = gray_to_place.shape

    faces = face_cascade.detectMultiScale(gray, 1.3, 5)
    for (x,y,w,h) in faces:
        roi_gray = gray[y:y+h, x:x+w]
        roi_color = img[y:y+h, x:x+w]
        eyes = eye_cascade.detectMultiScale(roi_gray)
        for (ex,ey,ew,eh) in eyes:
            resized_img = cv2.resize(img_to_place, (eh, ew), interpolation = cv2.INTER_AREA)
            resized_img_h, resized_img_w, _ = resized_img.shape

            roi_color[ey:ey+resized_img_h, ex:ex+resized_img_w, :] = resized_img

【问题讨论】:

    标签: python arrays numpy opencv python-imaging-library


    【解决方案1】:

    由于每个像素都有特定的 alpha 值,我将采用另一种方法,并实现像素级alpha blending,忽略最终图像中的任何 alpha 通道。

    借用Quang Hoang's answer的一些台词:

    import cv2
    import matplotlib.pyplot as plt
    import numpy as np
    
    # Read images
    img = cv2.imread('image.jpg')
    dot = cv2.imread('dot_transparent.png', cv2.IMREAD_UNCHANGED)
    
    # Manual manipulating one eye
    ex, ey, ew, eh = 1430, 1490, 400, 400
    dot = cv2.resize(dot, (eh, ew))
    
    # Prepare pixel-wise alpha blending
    dot_alpha = dot[..., 3] / 255.0
    dot_alpha = np.repeat(dot_alpha[..., np.newaxis], 3, axis=2)
    dot = dot[..., :3]
    
    # Pixel-wise alpha blending
    img[ey:ey+eh, ex:ex+ew, :] = img[ey:ey+eh, ex:ex+ew, :] * (1 - dot_alpha) + dot * dot_alpha
    
    # Output
    plt.figure(figsize=(9, 9))
    plt.imshow(img[..., [2, 1, 0]])
    plt.tight_layout()
    plt.show()
    

    这就是输出:

    ----------------------------------------
    System information
    ----------------------------------------
    Platform:      Windows-10-10.0.16299-SP0
    Python:        3.9.1
    Matplotlib:    3.3.4
    NumPy:         1.20.1
    OpenCV:        4.5.1
    ----------------------------------------
    

    【讨论】:

    • 谢谢!看起来不错,但我尝试在我的代码中实现您的解决方案,但收到了ValueError: operands could not be broadcast together with shapes (22,22,3) (1000,1000,3) 如何在index.py 中实现您的解决方案?
    • 显然,您还没有调整“点”图像的大小,它的形状为 (1000, 1000, 3) 以适应找到的 ROI,它的形状似乎为 (22, 22, 3)。如果没有看到您更新的代码,就无法提供帮助。请edit您的问题,并将更新后的代码放在现有问题的下方。
    【解决方案2】:

    cv2.IMREAD_UNCHANGE 标志读取dot_transparent.png,然后你就有了alpha通道(否则你只有3个通道)

    img = cv2.imread('faces.jpg')
    to_replace = cv2.imread('dot_transparent.png', cv2.IMREAD_UNCHANGED)
    # sample eye dectection
    ex,ey,ew,eh = 1600, 1600,200,200
    
    resized_replace = cv2.resize(to_replace, (eh,ew))
    
    img[ey:ey+eh, ex:ex+ew] = np.where(resized_replace[...,-1:]<50, 
                                       img[ey:ey+eh, ex:ex+ew],
                                       resized_replace[...,:-1]
                                )
    
    # show with imshow
    plt.imshow(img[...,::-1])
    

    输出:

    【讨论】:

    • 是否可以保持所有透明度?不只是去除黑色吗? IE。 i.imgur.com/2Z01EJb.jpg
    • 尝试增加阈值,例如50. 查看更新的答案。
    猜你喜欢
    • 1970-01-01
    • 2021-07-29
    • 1970-01-01
    • 1970-01-01
    • 2011-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多