廣告圖片過濾
為一個信息流產品作數據抓取,其中數據清洗時必不可少的。其中有一個步驟就是清洗掉其中與內容無關的廣告。文本通過語料庫積累和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、指紋的存儲和比對,就不介紹了,這和其他服務中的數據庫的檢索沒什麽區別,就是根據實際數據量進行設計&調整持久化、索引、緩存、備份、排序等相關策略。
後記:很早之前寫的,寫的不好,一直躺在草稿箱。現在發布出來,雖然已經不在進行這項工作了,還是希望有朋友提出改進的建議,謝謝!
廣告圖片過濾