標籤:

Python如何識別二維碼

最近呢,知乎發表了一個報告說,安全防護系統全面升級了(是小管家說的)。

現在內容中的二維碼會被自動替換為相應的鏈接,並綴以「(二維碼自動識別)」字樣。

今天就來看,如何用Python自動識別二維碼。

01. 編碼

首先要熟悉一套理論:什麼是二維碼?

條形碼我們都見過,這就是一種「一維碼」。豎直方向上,條碼是均勻的,長短也不影響,信息只在水平方向上存儲。

二維碼的信息則在整個平面上存儲,當下常見的二維碼叫QR碼(Quick Response Code)。實際上廣義的二維碼有很多形式,比如以前機器編程用的打孔帶,還有考試的答題卡也是一個原理。

二維碼的一大優勢在於容錯率高,即使遮擋一部分,也不影響解碼。這就是為什麼很多QR code會在中間放一個圖標,本質上來說,這個圖標就相當於給二維碼又打了個碼。

如果把太極圖看作二進位,那麼這也是個二維碼,白的是0,黑的是1。

QR code存儲信息的基本套路就跟「陰陽」類似,白0黑1。特別顯眼的那幾個方塊和虛線,則是輔助定位用的。

>>>這裡本來有個二維碼圖樣,展示各個區域的作用,但是被自動識別了。<<<

Mr. Watson, come here - I want to see you. (二維碼自動識別)

邊邊角角上的特定區域都按照標準存儲固定的信息,就像一張卷子上不可能全是題,總有寫班級姓名的地方。

需要編碼的目標字元首先轉換為二進位數,這個數的位數與QR code的尺寸有關。二級制數字就可以映射為非黑即白的色塊,再依照標準套路填充到數據區域。

雖然被編碼的內容各不相同,但是我們生活中所見到的QR code似乎長得都差不多,看起來都比較「均勻」,這是「掩碼」的作用。

掩碼就像Photoshop里的「蒙版」,與原始數據做「異或」計算後,出來的碼看起來就勻和了。

02. 解碼

解碼是編碼的逆過程,就是還原出原本的信息。在Python中,用到一個庫,叫zbar。

說起來這個庫彆扭的很(因為本來並不是用Python寫的,外部依賴較多),首先官網上的包最高只支持Python 2.6,不姿慈2.7;其次,2.6就2.6吧,但是安裝卻一直失敗,不論Linux,Win10還是Mac;最後發現只支持32位系統,我又裝了一個XP虛擬機。

當那熟悉的開機音樂隨著藍天綠地出現的時候,我彷彿回到了家裡剛買電腦的那個下午。

一個姿慈Python 2.7的zbar安裝包:

GitHub - jacobvalenta/zbar-py27-msi: Zbar for Python 2.7 (Windows MSI)

除zbar庫之外,還需要PIL庫以進行圖片操作。

03. 微小的示例

#-*- coding: utf-8 -*-nimport zbarnfrom PIL import Imagenn#創建圖片掃描對象nscanner = zbar.ImageScanner()n#設置對象屬性nscanner.parse_config(enable)nn#打開含有二維碼的圖片nimg = Image.open(<你的圖片路徑>).convert(L)n#獲取圖片的尺寸nwidth, height = img.sizenn#建立zbar圖片對象並掃描轉換為位元組信息nqrCode = zbar.Image(width, height, Y800, img.tobytes())nscanner.scan(qrCode)nndata = nfor s in qrCode:n data += s.datann# 刪除圖片對象ndel imgnn# 輸出解碼結果nprint datan

運行結果:

解碼成功之後會得到一個URL地址。當我們在用手機掃描QR code的時候,其過程就是在解析得到二維碼之後,通過微信向該URL發送請求,然後訪問。

以上案例中,所用的是本文的題圖,QR code不是整張圖片的主體,而是融入在背景當中,這仍然不影響識別。(而本文題圖沒有被知乎強制識別,我推測是因為題圖的位置問題)

題圖中石榴姐手中的二維碼是我的 [分答] 主頁鏈接,之前已經回答了幾個問題,歡迎感興趣的朋友們關注、提問。

除微信掃描二維碼以外,也可以直接搜索「Kaiser」,頭像是一樣的,謝謝大家。

推薦閱讀:

爬取豆瓣有關張國榮日記(二)—— 策略源碼知識點
20170403Python控制流if、while、for語句學習
TensorFlow初步(3)
Python資料庫起航篇|零基礎起步
Sublime Text 3中怎麼更換python的版本?

TAG:Python |