使用OpenCV掩码抠图生成带透明背景PNG时,cv2.imshow显示正常但cv2.imwrite保存为黑色图像的问题排查
解决OpenCV抠图后imshow正常但imwrite保存PNG为黑色的问题
我之前也碰到过一模一样的坑!你用位掩码从JPG中抠取目标物体生成4通道PNG时,cv2.imshow能正常显示结果,但cv2.imwrite保存出来却是黑图,核心原因其实很简单——你没给Alpha通道赋值。
先看看你的原始代码:
import cv2 import numpy as np # 读取原始jpg图像 image = cv2.imread(image_path, cv2.IMREAD_UNCHANGED) # 创建与原始图像尺寸一致的空二维零numpy数组 arraymask = np.zeros((image.shape[0], image.shape[1]), dtype=np.uint8) # poly_cords是掩码的多边形坐标列表 # 将多边形列表转换为numpy数组 polynumpy = np.array(poly_cords, dtype=np.int32) # 在零数组中填充多边形区域生成掩码 arraymask = cv2.fillPoly(arraymask, [polynumpy], color=255) # 创建4通道的空透明图像,初始值全为0 transparent_im = np.zeros((image.shape[0], image.shape[1], 4), dtype=np.uint8) # 将掩码区域的原始图像内容填充到透明图像的前3个通道 transparent_im[arraymask == 255, :3] = image[arraymask == 255] cv2.imshow("help", transparent_im) cv2.waitKey(0) cv2.imwrite("image.png", transparent_im)
问题分析
你创建的transparent_im是4通道图像,初始值全为0——前3个是RGB颜色通道,第4个是Alpha透明度通道。你只把掩码区域的RGB内容填充进去了,但Alpha通道全程保持0(代表完全透明)。cv2.imshow在显示时会自动忽略Alpha通道直接展示RGB内容,但cv2.imwrite会严格按照4通道格式保存,Alpha为0的区域会完全透明,打开时就会显示为黑色背景(透明区域默认渲染为黑色)。
解决方案
只需要在填充RGB通道后,给掩码区域的Alpha通道赋值为255(代表完全不透明),添加这一行代码即可:
transparent_im[arraymask == 255, 3] = 255
修改后的完整代码
import cv2 import numpy as np # 读取原始jpg图像 image = cv2.imread(image_path, cv2.IMREAD_UNCHANGED) # 创建与原始图像尺寸一致的空二维零numpy数组 arraymask = np.zeros((image.shape[0], image.shape[1]), dtype=np.uint8) # poly_cords是掩码的多边形坐标列表 # 将多边形列表转换为numpy数组 polynumpy = np.array(poly_cords, dtype=np.int32) # 在零数组中填充多边形区域生成掩码 arraymask = cv2.fillPoly(arraymask, [polynumpy], color=255) # 创建4通道的空透明图像,初始值全为0 transparent_im = np.zeros((image.shape[0], image.shape[1], 4), dtype=np.uint8) # 将掩码区域的原始图像内容填充到透明图像的前3个通道 transparent_im[arraymask == 255, :3] = image[arraymask == 255] # 给掩码区域的Alpha通道赋值255(完全不透明) transparent_im[arraymask == 255, 3] = 255 cv2.imshow("help", transparent_im) cv2.waitKey(0) cv2.imwrite("image.png", transparent_im)
这样保存出来的PNG就能正常显示抠取的物体,背景保持透明啦!
内容的提问来源于stack exchange,提问作者kranj doo
相关产品推荐
相关产品推荐

