使用 PIL.ImageGrab 和 cv2.imread 时如何强制执行 alpha 通道?

How to enforce alpha channel when using PIL.ImageGrab and cv2.imread?

我用PIL.ImageGrab截图:

screen = ImageGrab.grab(bbox=(869,657,955,714))
screen.save("PictureName.png")

后来,我用cv2.imread打开那张图片,想得到alpha通道:

template = cv2.imread('PictureName.png', cv2.IMREAD_UNCHANGED)
hh, ww = template.shape[:2]
alpha = template[:,:,3]
alpha = cv2.merge([alpha,alpha,alpha])
cv2.imshow('alpha',alpha)

这不起作用,我收到以下错误:

alpha = template[:,:,3] -> index 3 is out of bounds for axis 2 with size 3

如何解决此问题才能使此代码正常工作?

实际问题是,默认情况下 PIL.ImageGrab 使用模式 RGBImage 个对象。因此,保存的图像没有 alpha 通道。即使在使用 cv2.imread(..., cv2.IMREAD_UNCHANGED) 时,生成的 NumPy 数组也将具有 (height, width, 3) 的形状,这样访问 template[..., 3] 将导致给定的错误。

因此,似乎有两个选项可以在执行 alpha 通道方面改进您的代码。

  1. 抓取截图后,将Image对象转换为模式RGBA,然后保存。

  2. 打开图片时勾选template.shape[2] == 3,必要时使用cv2.cvtColor(template, cv2.COLOR_BGR2BGRA).

这是一些代码片段:

import cv2
from PIL import ImageGrab

# Force alpha channel in screenshot saving
screen = ImageGrab.grab((0, 0, 200, 200))
screen.save('image_rgb.png')
screen.convert('RGBA').save('image_rgba.png')


# If necessary, add alpha channel after reading the image
def force_alpha_read(filename):
    print('DEBUG:', filename)
    image = cv2.imread(filename, cv2.IMREAD_UNCHANGED)
    if image.shape[2] == 3:
        image = cv2.cvtColor(image, cv2.COLOR_BGR2BGRA)
        print('DEBUG: Added alpha channel')
    return image


template = force_alpha_read('image_rgb.png')
print(template.shape)

template = force_alpha_read('image_rgba.png')
print(template.shape)

这是输出:

DEBUG: image_rgb.png
DEBUG: Added alpha channel
(200, 200, 4)
DEBUG: image_rgba.png
(200, 200, 4)
----------------------------------------
System information
----------------------------------------
Platform:      Windows-10-10.0.16299-SP0
Python:        3.9.1
OpenCV:        4.5.1
Pillow:        8.1.0
----------------------------------------