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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了具有alpha层的PNG图像上的OpenCV边缘检测相关的知识,希望对你有一定的参考价值。

我有一个徽标的图像,这是一个带有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仍然会在徽标周围拾取隐藏的“框”。)

有没有一种预处理图像的方法来避免这个问题?

答案

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

 mask = source[:,:,3]

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

另一答案

问题解决了,使用在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

以上是关于具有alpha层的PNG图像上的OpenCV边缘检测的主要内容,如果未能解决你的问题,请参考以下文章

OpenCV2马拉松第15圈——边缘检測(Laplace算子,LOG算子)

OpenCV基础(11)基于OpenCV的边缘检测

如何在opencv python中调整PNG图像的大小? [复制]

OpenCV2马拉松第17圈——边缘检測(Canny边缘检測)

OpenCV - 计算图像的边缘强度

如何检查加载到 FMX.TBitmap 的 PNG 图像是不是具有 alpha 通道?