• 广告图片过滤


    为一个信息流产品作数据抓取,其中数据清洗时必不可少的。其中有一个步骤就是清洗掉其中与内容无关的广告。文本通过语料库积累和NLP相关技术进行过滤,有些文字广告不过滤对产品影响也不大。有点儿麻烦的是其中的有些图片广告如果不过滤掉,在感官上会对产品造成很大的印象,为了解决这个问题,用了一些杂七杂八的方法,始终没有一个唯一的解决方案。最终采用多级判断进行组合check(漏斗式缩小范围),在这里简单记录一下。

    主要处理步骤如下图:

    第一步:检查是否为二维码

    文章开始和末尾的二维码一般都是广告(可以说至今没有发现不是的),由于二维码是编码良好的图片,可以不依赖材料库就可以判断,所以第一步先判断图片是否为二维码。

    二维码判断Demo代码如下:

    # coding:utf-8
    
    import sys
    from PIL import Image
    import zbarlight
    
    def is_qr_code(img):
        try:
            scan_result = zbarlight.scan_codes("qrcode", img)
        except Exception:
            return False
        else:
            #  打印QRCODE信息
            return True if scan_result else False
    
    if __name__ == "__main__":
        img_name = sys.argv[1]
        ig = Image.open(img_name)
        print is_qr_code(ig)
    
    

    若怕二维码中有重要信息,可以将从二维码图片中识别的文本信息做进一步的NLP处理,从而决定是否判定为广告

    第二步:检查来源URL

    有些广告图片都来同一个URL,比如某些自媒体/资讯平台会在每篇文章下面带有相同的广告图片,有的不是同一家产品的,但是采用了同一个广告平台都会出现这种情况。具体实现就是文本比对,代码就不用说了。

    第三步:检查图片Hash-MD5(绝对指纹)

    某些广告图片完全相同,但却来自不同的URL(比如,某些网站静态资源URI变更),用第二步的URL比对就不行了。在本步骤中采用图片内容的完全比对进行广告图片识别。若采用像素点比对那效率就太低了,所以采用MD5哈希值比对。MD5一般用于校验文件是否损坏、被修改,在这一步正好合适。

    获取图片MD5哈希值的简单Demo代码:
    Demo代码:

    # coding:utf-8
    
    import sys
    from hashlib import md5
    
    if __name__ == "__main__":
        img_name = sys.argv[1]
        img_body = open(img_name).read()
        fingerprint = md5(img_body).hexdigest()
        print fingerprint
    

    第四步:检测图片感知哈希

    参考:https://realpython.com/blog/python/fingerprinting-images-for-near-duplicate-detection/

    在第三步中采用的MD5哈希比对对于内容完全相同的广告图片是适用的,但是一旦两张图片稍有差异,MD5就完全不同了,也就造成第三步的检测失效。所以在这里采用感知哈希进行相似图片的匹配(和广告图片相似的也是广告图片)。感知哈希是一类哈希算法。这里实验两种
    DHash——均值感知哈希,
    pHash——余弦变换感知哈希
    均值哈希Demo代码:

    # coding:utf-8
    
    import sys
    from PIL import Image
    
    
    def dhash(image, hash_size=8):
        image = image.convert('L').resize(
            (hash_size + 1, hash_size),
            Image.ANTIALIAS,
        )
    
        difference = []
        for row in xrange(hash_size):
            for col in xrange(hash_size):
                pixel_left = image.getpixel((col, row))
                pixel_right = image.getpixel((col + 1, row))
                difference.append(pixel_left > pixel_right)
    
        decimal_value = 0
        hex_string = []
        for index, value in enumerate(difference):
            if value:
                decimal_value += 2 ** (index % 8)
            if (index % 8) == 7:
                hex_string.append(hex(decimal_value)[2:].rjust(2, '0'))
                decimal_value = 0
    
        return ''.join(hex_string)
    
    
    if __name__ == "__main__":
        img_name = sys.argv[1]
        img = Image.open(img_name)
        print dhash(img)
    
    

    第五步:人为定义特征

    还可以通过其他人为定义特征进行过滤,以下特征可以考虑:

    • 色彩分布
    • 整体轮廓
    • ......

    结束

    本文只介绍了整个流程的实现demo。当然,在真正的业务项目中还牵涉到其他的组件。其中主要的时广告图片url、md5、指纹的存储和比对,就不介绍了,这和其他服务中的数据库的检索没什么区别,就是根据实际数据量进行设计&调整持久化、索引、缓存、备份、排序等相关策略。


    后记:很早之前写的,写的不好,一直躺在草稿箱。现在发布出来,虽然已经不在进行这项工作了,还是希望有朋友提出改进的建议,谢谢!

  • 相关阅读:
    Delphi cxGrid –--> RecordIndex out of Range
    局域网共享需要密码
    提高AdoQuery的速度
    string literals may have at most 255 elements
    delphi控件属性大全-详解-简介
    Cxgrid获取选中行列,排序规则,当前正在编辑的单元格内的值
    FastReport 使用说明
    delphi的取整函数round、trunc、ceil和floor
    cxGrid 速度
    SQL Server 无法在服务器上访问指定的路径或文件解决方法
  • 原文地址:https://www.cnblogs.com/taceywong/p/7650536.html
Copyright © 2020-2023  润新知