1. 程式人生 > >廣告圖片過濾

廣告圖片過濾

ear source def 發現 效率 謝謝 兩張 python 設計

為一個信息流產品作數據抓取,其中數據清洗時必不可少的。其中有一個步驟就是清洗掉其中與內容無關的廣告。文本通過語料庫積累和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、指紋的存儲和比對,就不介紹了,這和其他服務中的數據庫的檢索沒什麽區別,就是根據實際數據量進行設計&調整持久化、索引、緩存、備份、排序等相關策略。


後記:很早之前寫的,寫的不好,一直躺在草稿箱。現在發布出來,雖然已經不在進行這項工作了,還是希望有朋友提出改進的建議,謝謝!

廣告圖片過濾