You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python OpenCV2为16位2D图像数组添加透明Logo时透明度丢失问题

解决透明Logo添加后变为黑色背景的问题

你的问题核心在于没有正确处理Logo的透明通道(Alpha通道),同时代码里还有几个关键的错误点,我来一步步帮你梳理并修正:

问题分析

  1. Logo读取方式错误:你用cv2.imread("resources/logo/logo.png", 0)读取的是灰度图,直接丢弃了PNG的Alpha透明通道,导致原本透明的区域变成了黑色(灰度值0)。
  2. 未初始化的变量:scale_percent在使用前没有定义,这会直接导致报错,你应该先设置一个缩放比例(比如50代表缩放至50%)。
  3. 错误的类型转换:把Logo转成uint16后乘以256,这会破坏像素值的正常范围,而且完全没必要——我们应该让Logo的像素格式和原始图像(单通道uint16)匹配,而不是强行转换。
  4. 直接覆盖像素:你直接用Logo像素替换原始图像的区域,没有根据Alpha通道做混合,所以透明区域也被黑色覆盖了。

修正方案

下面是符合你需求的代码,保证原始数组的形状和数据类型完全不变,只添加Logo:

import cv2
import numpy as np

def add_logo(array):
    # 1. 读取带Alpha通道的Logo(4通道:BGR+Alpha)
    logo = cv2.imread("resources/logo/logo.png", cv2.IMREAD_UNCHANGED)
    if logo is None:
        raise ValueError("无法读取Logo文件,请检查路径")
    
    # 2. 定义缩放比例(根据你的需求调整,比如50就是缩小到50%)
    scale_percent = 50
    # 计算缩放后的尺寸
    width = int(logo.shape[1] * scale_percent / 100)
    height = int(logo.shape[0] * scale_percent / 100)
    dim = (width, height)
    
    # 3. 缩放Logo的BGR通道和Alpha通道
    # 先分离BGR和Alpha
    logo_bgr = logo[:, :, :3]
    logo_alpha = logo[:, :, 3]
    # 缩放BGR到目标尺寸,转成灰度图(匹配原始单通道图像)
    logo_gray = cv2.cvtColor(cv2.resize(logo_bgr, dim, interpolation=cv2.INTER_AREA), cv2.COLOR_BGR2GRAY)
    # 缩放Alpha通道,保持尺寸一致
    logo_alpha_resized = cv2.resize(logo_alpha, dim, interpolation=cv2.INTER_AREA)
    
    # 4. 转换格式,匹配原始图像的uint16类型
    logo_gray_16 = np.array(logo_gray, dtype=np.uint16) * 256  # 8位转16位,映射到0-65535范围
    logo_alpha_16 = np.array(logo_alpha_resized, dtype=np.uint16)  # Alpha转16位
    # 归一化Alpha到0-1范围,用于混合计算
    alpha = logo_alpha_16 / 65535.0
    
    # 5. 获取原始图像中要替换的区域
    x_offset = y_offset = 50
    roi = array[y_offset:y_offset+height, x_offset:x_offset+width]
    
    # 6. Alpha混合:原始像素*(1-alpha) + Logo像素*alpha
    blended = (roi * (1 - alpha)).astype(np.uint16) + (logo_gray_16 * alpha).astype(np.uint16)
    
    # 7. 将混合后的区域赋值回原始数组
    array[y_offset:y_offset+height, x_offset:x_offset+width] = blended
    
    return array

# 假设get_images_from_xxxx()是你的图像获取函数
imgs = get_images_from_xxxx()
edited = add_logo(imgs[0])
cv2.imwrite('01.png', edited)

关键细节说明

  • Alpha通道处理:我们通过cv2.IMREAD_UNCHANGED读取Logo的Alpha通道,然后用它来控制混合比例——Alpha值越高,Logo越不透明;Alpha值为0时,完全显示原始图像。
  • 格式匹配:原始图像是uint16类型(值范围0-65535),所以我们把8位的Logo灰度图乘以256,映射到相同的16位范围,保证像素值的一致性。
  • 区域混合:没有直接覆盖像素,而是通过加权混合的方式,既保留了Logo的内容,又在透明区域保留了原始图像的像素。

内容的提问来源于stack exchange,提问作者toing_toing

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 03:51:08