OpenCV-拆分和合并Alpha通道的速度很慢

时间:2019-07-15 09:46:12

标签: python opencv

我正在使用Python OpenCV拆分通道并像这样删除黑色背景...

    b_channel, g_channel, r_channel = cv2.split(image_1)
    alpha_channel = np.zeros_like(gray)

    for p in range(alpha_channel.shape[0]):
        for q in range(alpha_channel.shape[1]):
            if b_channel[p][q]!=0 or g_channel[p][q]!=0 or r_channel[p][q]!=0:
                alpha_channel[p][q] = 255

    merged = cv2.merge((b_channel, g_channel, r_channel, alpha_channel))

这是可行的,但是大约200kb的图像大约需要10秒钟才能完成

是否有更有效的方法来执行此操作,或者使用我拥有的代码可以提高速度?

2 个答案:

答案 0 :(得分:1)

使用for循环遍历像素实际上非常缓慢且效率低下。另外,根据文档here

  

cv2.split()是一项昂贵的操作(就时间而言)。所以只有在   你需要它。否则,请进行Numpy索引编制。

您可以尝试使用numpy进行矢量化和索引编制,如下所示:

# create the image with alpha channel
img_rgba = cv2.cvtColor(img, cv2.COLOR_RGB2RGBA)

# mask: elements are True any of the pixel value is 0         
mask = (img[:, :, 0:3] != [0,0,0]).any(2) 
#assign the mask to the last channel of the image
img_rgba[:,:,3]  = (mask*255).astype(np.uint8)

答案 1 :(得分:1)

对于您正在做的事情,使用cv2.bitwise_or似乎是最快的方法:

image_1 = img
# your method
start_time = time.time()
b_channel, g_channel, r_channel = cv2.split(image_1)
alpha_channel = np.zeros_like(gray)
for p in range(alpha_channel.shape[0]):
    for q in range(alpha_channel.shape[1]):
        if b_channel[p][q]!=0 or g_channel[p][q]!=0 or r_channel[p][q]!=0:
            alpha_channel[p][q] = 255
elapsed_time = time.time() - start_time
print('for cycles:  ' + str(elapsed_time*1000.0) + ' milliseconds')

# my method
start_time = time.time()
b_channel, g_channel, r_channel = cv2.split(image_1)
alpha_channel2 = cv2.bitwise_or(g_channel,r_channel)
alpha_channel2 =  cv2.bitwise_or(alpha_channel2, b_channel)
_,alpha_channel2 = cv2.threshold(alpha_channel2,0,255,cv2.THRESH_BINARY)
elapsed_time2 = time.time() - start_time
print('bitwise + threshold:  '+ str(elapsed_time2*1000.0) + ' milliseconds')

# annubhav's method
start_time = time.time()
img_rgba = cv2.cvtColor(image_1, cv2.COLOR_RGB2RGBA)
# mask: elements are True any of the pixel value is 0         
mask = (img[:, :, 0:3] != [0,0,0]).any(2) 
#assign the mask to the last channel of the image
img_rgba[:,:,3]  = (mask*255).astype(np.uint8)
elapsed_time3 = time.time() - start_time
print('annubhav:  ' + str(elapsed_time3*1000.0) + ' milliseconds')
  

周期:2146.300792694092毫秒

     

按位+阈值:4.959583282470703毫秒

     

annubhav:27.924776077270508毫秒