具有alpha层的PNG图像上的OpenCV边缘检测

时间:2018-03-02 14:51:41

标签: python opencv image-processing png

我有一个徽标的图像,这是一个带有alpha(透明度)通道的PNG文件。非常常见的徽标格式,但这里以路透社徽标为例:

enter image description here

我在Python中使用OpenCV Canny边缘检测将其转换为单色边缘模板,可用于匹配更大的图像:

import matplotlib.pyplot as plt
import cv2
img = cv2.imread(filepath) # Save above image and add location here
img_edged = cv2.Canny(img, 100, 200)

不幸的是,这正在拾取徽标周围的矩形边框,该边框被Alpha通道屏蔽:

plt.imshow(img, cmap='gray')

enter image description here

我在回复this question时提到了以下建议,但它没有解决此问题:

img = cv2.imread(filepath, cv2.IMREAD_UNCHANGED)

(它确实使用imshow正确显示图像,但是cv2.Canny仍然会在徽标周围拾取隐藏的"框")

有没有办法预处理图像以避免这个问题?

2 个答案:

答案 0 :(得分:1)

对于示例中的简单徽标,其中所有值得寻找的边缘都在前景和背景之间,透明蒙版具有您需要的所有信息:

 mask = source[:,:,3]

您可以查找mask的边缘并查找路透社徽标中的所有边缘。我认为大多数徽标都是如此,但有些可能会更复杂。

答案 1 :(得分:0)

问题解决了,使用在StackOverflow上其他地方发现的这个功能(已经丢失了问题的链接 - 如果你找到它,请添加评论):

def remove_transparency(source, background_color):
    print(source.shape)
    source_img = cv2.cvtColor(source[:,:,:3], cv2.COLOR_BGR2GRAY)
    source_mask = source[:,:,3]  * (1 / 255.0)

    background_mask = 1.0 - source_mask

    bg_part = (background_color * (1 / 255.0)) * (background_mask)
    source_part = (source_img * (1 / 255.0)) * (source_mask)

    return np.uint8(cv2.addWeighted(bg_part, 255.0, source_part, 255.0, 0.0))

然后可以解决上述问题:

img = cv2.imread(filepath, cv2.IMREAD_UNCHANGED)
img = remove_transparency(img, 0)
img_edged = cv2.Canny(img, 100, 200)

,并提供:

enter image description here