爬蟲敏感圖片的識別與過濾,瞭解一下?

子竹聆風發表於2019-03-01

需求

我們需要識別出敏感作者的avatar頭像,把”皮卡丘“換成”優雅的python“。

敏感圖片樣本屬性:

爬蟲敏感圖片的識別與過濾,瞭解一下?

爬蟲獲取的圖片屬性:

爬蟲敏感圖片的識別與過濾,瞭解一下?

替換成:

爬蟲敏感圖片的識別與過濾,瞭解一下?

原理

檢查兩個圖片的相似度,一個簡單而快速的演算法:感知雜湊演算法(Perceptual Hash),通過某種提取特徵的方式為每個圖片計算一個指紋(雜湊),這樣對比兩個圖片相似與否就變成了對比兩個指紋異同的問題。

實現

Step1.縮小尺寸

將圖片縮小到8*8的大小,這樣做可以去除圖片的細節,只保留結構和明暗等基本資訊,同時摒棄不同尺寸和比例帶來的圖片差異。

Step2.灰度處理

把縮小後的圖片轉化為64級灰度圖(每個畫素只有64種顏色)。

Step3.計算平均值

計算所有64個畫素的灰度平均值。

Step4.計算雜湊

這裡雜湊的計算方法是:上面說的64個畫素的灰度與平均值進行比較,大於或等於平均值記為1,小於記為0。

將每個畫素的比較結果組合在一起成為一個64位的二進位制整數,這個整數就是此圖片的指紋。

Step5.對比雜湊

不同圖片對比的方法,就是對比它們的64位雜湊中,有多少位不一樣(漢明距離)。一般來說如果不同的位數不超過5,就說明兩張圖片很相似,如果大於10,就很可能是兩張不同的圖片。

程式碼(python3)

先來安裝pillow、requests:

pip3 install pillow requests
複製程式碼

匯入包:

from functools import reduce
from PIL import Image
import requests
複製程式碼

實現圖片相似度演算法:

# 計算pHash(只需要三行):
def phash(img):
    img = img.resize((8, 8), Image.ANTIALIAS).convert('L')
    avg = reduce(lambda x, y: x + y, img.getdata()) / 64.
    return reduce(
        lambda x, y: x | (y[1] << y[0]),
        enumerate(map(lambda i: 0 if i < avg else 1, img.getdata())),
        0
    )

# 計算漢明距離:
def hamming_distance(a, b):
    return bin(a^b).count('1')

# 計算兩個圖片是否相似:
def is_imgs_similar(img1,img2):
	return True if hamming_distance(phash(img1),phash(img2)) <= 5 else False
複製程式碼

結合爬蟲:

# 開啟本地存放一張敏感圖片;
# 本次為了方便演示,從新浪圖床拉下一張1024X1024的圖片,儲存命名為sensitive.jpg
sensitive_url="https://ws4.sinaimg.cn/large/006tNbRwgy1fwttj7bi36j30sg0sgwm0.jpg"
headers = {
        "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/532.5 (KHTML, like Gecko) Chrome/4.0.249.0 Safari/532.5"}
pic = requests.get(sensitive_url, headers=headers, timeout=300)
if pic.status_code == 200:
    with open("sensitive.jpg", 'wb') as f:
        f.write(pic.content)
sensitive_pic = Image.open("sensitive.jpg")

# 爬蟲獲取的圖片
target_url="https://ws3.sinaimg.cn/large/006tNbRwgy1fwttsauo6jj30h80han0y.jpg"
pic = requests.get(target_url, headers=headers, timeout=300)
if pic.status_code == 200:
    with open("target.jpg", 'wb') as f:
        f.write(pic.content)
target_pic = Image.open("target.jpg")

# 判斷爬蟲獲取的圖片和敏感圖片是否相似
if is_imgs_similar(target_pic, sensitive_pic):
    print("2張圖片相似,替換敏感圖片為”優雅的python“:{}".format("https://user-gold-cdn.xitu.io/2018/11/3/166d7edc954875ac?w=1230&h=1230&f=jpeg&s=119846"))
else:
    print("不相似")
複製程式碼

執行結果:

爬蟲敏感圖片的識別與過濾,瞭解一下?

github原始碼

gist.github.com/luzihang123…

參考文章

  • 相似圖片檢測?三行程式碼就夠了 - 掘金
  • 此 Python2 指令碼怎麼修改為 Python3 執行 - V2EX

相關文章