10 行代碼判定色*情*圖片——Python 也可以系列之二
作者:賴勇浩(http://blog.csdn.net/lanphaday)
致編輯:我已經給圖片打上馬賽克了,別再刪除了啊,我這是純技術貼!
聲明:本文因科學研究需要,包含部分色*情*圖片,不可作為傳播色*情*資訊的證據。
今天先是在 CSDN 看到《大學生髮明依據皮膚比例過濾色*情*圖片軟體》(http://news.csdn.net/n/20081028/120298.html),後來發現這條新聞竟然已經上了網易新聞頻道了(http://news.163.com/08/1028/05/4PAORMQB00011229.html),著實令人吃驚。
來自網易新聞的圖片
根據作者的話說:“這個軟體的原理在於通過計算面部、四肢映像地區,與整個膚色地區的面積比例和具體的分布,來判斷網站中是否含有色*情*圖片。”我估計他用的就是普通的膚色模型對圖片的像素進行檢測和統計,最多加上一些色塊的分布、形狀等資料進行一些條件過濾。於是我就寫了段代碼來分析映像,把映像中非膚色的像素去除,效果如下(聲明:程式計算的資料是根據未打馬賽克的圖片計算的,因為保持 CSDN 部落格的需要,故打上馬賽克再發表):
x
相應的圖片處理後的結果是:
可見簡單的膚色模型已經能夠工作得很好。
接下來就可以寫統計膚色像素的代碼了,很短,只有 10 行,充實體現了 Python 語言的強大,以及李濟民同學的研究並不深入:
import sys, Imageimg = Image.open(sys.argv[1]).convert('YCbCr')w, h = img.sizedata = img.getdata()cnt = 0for i, ycbcr in enumerate(data): y, cb, cr = ycbcr if 86 <= cb <= 117 and 140 <= cr <= 168: cnt += 1print '%s %s a porn image.'%(sys.argv[1], 'is' if cnt > w * h * 0.3 else 'is not')
下面簡單講解一下代碼:
1) Image 是 PIL 庫,我曾經寫過一篇《用Python做影像處理》(http://blog.csdn.net/lanphaday/archive/2007/10/28/1852726.aspx),基本用法可以參考此文。
2) img = Image.open(fn).convert('YCbCr'),這一行開啟從命令列傳入的檔案名稱,然後轉換到 YCbCr 色彩空間,關於 YCbCr 的理論知識,可以參考http://baike.baidu.com/view/564370.htm。
3) data = img.getdata(),這一句是為了方便快速控制項目像素而擷取映像資料
4) if 86 <= cb <= 117 and 140 <= cr <= 168:,這一句最為重要,是本文的精髓所在。根據 YCbCr 膚色模型,許多論文推薦用 86 <= cb <= 127,130 <= cr < 168,但經實驗,這個數值並不好,所以我把 cb 的上限改為 117,cr 的下限改為 140,過濾掉太白和太黑的部分。
最後本程式的執行結果是這樣的:
E:/>c:/python25/python test_skin.py 114.jpeg114.jpeg is a porn image.
其中 114.jpeg 就是上例中的第三幅圖片。
綜上所述,重慶郵電大學的大四學生李濟民,只不過是利用了一個非常成熟的理論(膚色檢測是Face Service等電腦視覺學科的基礎知識),寫了一點點代碼(也許他用 C++ 寫的代碼比我用 python 寫的多一些,但最多也就多三兩百行),並沒有實質性的科研突破,產品也不夠成熟(按他的話就是比*基*尼美女都識別不了),記者和網站對他進行宣傳,實為捧殺。
另,許多 CSDN 的網友對他用的“嵌入瀏覽器內,很難刪除”的說法很好奇,在這裡順便提一下李同學應該是用 Browser Helper Object,又稱 BHO 技術來完成這件事的,這是一個很簡單的技術,查查 MSDN,用 VC/VB/C# 都能很方便地寫出來,當然,也可以很方便地刪除。哈哈。