python - 如何在python中为uint16图像添加透明度(在opencv中使用connectedcomponents的上下文中)?
问题描述
使用 uint8、3 通道图像和 uint8 二进制掩码,我在 opencv 和 python 中完成了以下操作,以便将黑色背景上的对象更改为透明背景上的对象:
# Separate image into its 3 channels
b, g, r = cv2.split(img)
# Merge channels back with mask (resulting in a 4-channel image)
imgBGRA = cv2.merge((b, g, r, mask))
但是,当我尝试使用 uint16、3 通道图像和 uint16 二进制掩码执行此操作时,保存的结果是 4 通道,但背景仍然是黑色。(我将其保存为 .tiff 文件并在 Photoshop 中查看。)
如何使背景透明,保持输出图像 uint16?
更新
看到@Shamshirsaz.Navid 和@fmw42 的评论,我试过了
imgBGRA=cv2.cvtColor(imgBGR, cv2.COLOR_BGR2BGRA)
。然后使用 Numpy 从掩码中添加 alpha 通道:imgBGRA[:,:,3]=mask
. (我没有尝试过,因为我认为 cvtColor 操作需要 8 位图像。)尽管如此,我的结果是一样的。
我认为问题是我的面具。当我运行时numpy.amin(mask)
,我得到 0,而对于numpy.amax(mask)
,我得到 1。它们应该是什么?在使用拆分/合并技术之前,我尝试将蒙版乘以 255,但背景仍然是黑色。然后我尝试了 mask*65535,但背景又是黑色的。
我曾试图缩小我最初帖子的范围。但似乎我的问题确实存在于我正在做的事情以及如何创建这个 uint16 掩码的更大范围内。
我正在使用connectedComponentsWithStats
(CC) 剪切 uint16 图像上的组件。CC 需要一个 8 位掩码,我将其用作 CC 的输入。但是剪切结果需要来自我的 uint16 原件。这需要对我学习在 uint8 图像上使用 CC 的方式进行一些更改。请注意,每个组件的掩码(我最终用来尝试使背景透明)被创建为 uint16。这是精简版:
# img is original image, dtype=uint16
# bin is binary mask, dtype=uint8
cc = cv2.connectedComponentsWithStats(bin, connectivity, cv2.CV_32S)
num_labels = cc[0]
labels = cc[1]
for i in range(1, num_labels):
maskg = (labels == i).astype(np.uint16) # with uint8: maskg = (labels == i).astype(np.uint8) * 255
# NOTE: I don't understand why removing the `* 255` works; but after hours of experimenting, it's the only way I could get the original to appear correctly when saving 'glyph'; for all other methods I tried the colors were off in some significant way -- either grayish blue whereas the object in my original is variations of brown, or else a pixelated rainbow of colors)
glyph = img * maskg[..., np.newaxis] # with uint8: glyph = cv2.bitwise_and(img, img, mask=maskg)
b, g, r = cv2.split(glyph)
glyphBGRA = cv2.merge((b, g, r, maskg))
示例(我的真实原始图像很大,而且我无法分享它;所以我把这个例子放在一起)
img(原始 uint16 图像)
bin(输入 uint8 掩码)
maskg(在循环中创建的 uint16 组件掩码) (这是截图——直接上传时显示为全黑)
字形(应用了 maskg 的 img)
glyphBGRA(尝试添加透明度的拆分和合并方法的结果) (这也是一个屏幕截图——直接添加时这个屏幕显示为全白/空白)
我希望这个添加的信息为我的问题提供足够的背景。
解决方案
我检查了你最后的评论。我认为一个例子可能会更好。您的代码是正确的;问题是,你是如何使用它的?我附上了一张图片和一个面具来测试它们。
import sys,cv2
main = cv2.imread(sys.path[0]+'/main.png')
mask = cv2.imread(sys.path[0]+'/mask.png', cv2.IMREAD_GRAYSCALE)
mask = cv2.threshold(mask, 127, 255, cv2.THRESH_BINARY)[1]
b, g, r = cv2.split(main)
bgra = cv2.merge((b, g, r, mask))
cv2.imwrite(sys.path[0]+'/out_split_merge.png',bgra)
推荐阅读
- python - 运行 Prophet()、ds 和 y 时如何解决 ValueError
- shell - Shell:无法从 ssh 连接获取返回值
- macos - 如果不执行以下步骤,brew 命令行 mac 将无法工作
- java - FileNotFoundException Android 文件未找到
- javascript - 在代码后面使用用 axios 收集的数据
- r - 用 LaTeX 在 Rmarkdown 中编写方程的“系统”
- spring-boot - 我应该如何为实体设计状态字段
- npm-install - 编译失败错误
- c# - 每 X 秒读取一次串口
- python - 代码中的错误(只有整数标量数组可以转换为标量索引)