Python制作二維碼和條形碼掃描器 (pyzbar)


條碼在生活中隨處可見,其可分為三類:一維條碼、二維條碼、三維條碼

一維條碼:

       我們平時習慣稱為條形碼。條形碼是將寬度不等的多個黑條和空白,按照一定的編碼規則排列,用以表達一組信息的圖形標識符。常見的條形碼是由反射率相差很大的黑條(簡稱條)和白條(簡稱空)排成的平行線圖案。

二維條碼:

      二維條碼簡稱為二維碼,常見的二維碼為QR Code,QR全稱Quick Response,是一個近幾年來移動設備上超流行的一種編碼方式,它比傳統的Bar Code條形碼能存更多的信息,也能表示更多的數據類型。

三維條碼:

    三維條碼具有更大的信息容量、相同的識別便易性和較好的安全性。三維碼的主要特征在於利用色彩或灰度(或稱黑密度)表示不同的數據並進行編碼。

 

一、實現效果

           

 

二、安裝所需的庫

2.1、安裝掃描庫

安裝命令:pip3 install pyzbar

其實Python的條碼掃描庫,一直都有一個很是出名,那就是zbar,但此庫雖然牛,卻已經停止維護了,如果是python3,則不能使用zbar庫了,python2.7還是可以用的。忙活了一下午才發現我的python3.5不能用zbara庫,哈哈藍瘦

 

2.2、安裝其他必要庫

后續功能需要用到PIL和OpenCV-Python相關庫,可參考以下鏈接進行簡單認識和庫的安裝

玩轉Python圖片處理(OpenCV-Python)

Python的GUI編程(TK)

 

三、系統環境准備

3.1、Windows環境

 如果是Windows電腦則可以跳過。*  0  *

 

3.2、樹莓派環境

第一步:插入並打開CSI攝像頭(參考:https://www.cnblogs.com/dongxiaodong/p/9814119.html)

第二步:配置系統啟動之后加載bcm2835-v4l2這個模塊,原因是樹莓派中的camera module是放在/boot/目錄中以固件形式加載的,不是一個標准的V4L2的攝像頭驅動,所以用opencv的(cv2.VideoCapture(0)會無視頻數據),加上這句之后就可以解決以上問題。

命令:sudo vi /etc/modules

加入:bcm2835-v4l2

 

四、實現簡單的圖識別

 使用pyzbar和PIL 進行圖片的二維碼識別,並輸出識別結果

識別結果:

 

找到一張二維碼圖片,並下載其中二維碼:

基本代碼:

 1 import pyzbar.pyzbar as pyzbar
 2 from PIL import Image,ImageEnhance
 3 
 4 image = "imgx\dongxiao.png"
 5 
 6 img = Image.open(image)
 7 #處理圖片
 8 #img = ImageEnhance.Brightness(img).enhance(2.0)#增加亮度
 9 
10 #img = ImageEnhance.Sharpness(img).enhance(17.0)#銳利化
11 
12 #img = ImageEnhance.Contrast(img).enhance(4.0)#增加對比度
13 
14 #img = img.convert('L')#灰度化
15 
16 #顯示原圖,調用系統默認的圖片顯示器
17 img.show()
18 
19 texts = pyzbar.decode(img)
20 #輸出結果
21 for text in texts:
22     tt = text.data.decode("utf-8")
23     print(tt)

五、圖識別進階

使用pyzbar和PIL 及OpenCV-Python,實現二維碼圖片框選和在圖片上印字體

識別結果:

基本代碼:

 1 import cv2
 2 import pyzbar.pyzbar as pyzbar
 3 import numpy
 4 from PIL import Image, ImageDraw, ImageFont
 5 
 6 def decodeDisplay(imagex1):
 7     # 轉為灰度圖像
 8     gray = cv2.cvtColor(imagex1, cv2.COLOR_BGR2GRAY)
 9     barcodes = pyzbar.decode(gray)
10 
11     for barcode in barcodes:
12 
13         # 提取條形碼的邊界框的位置
14         # 畫出圖像中條形碼的邊界框
15         (x, y, w, h) = barcode.rect
16         cv2.rectangle(imagex1, (x, y), (x + w, y + h), (255, 255, 0), 2)
17 
18         # 條形碼數據為字節對象,所以如果我們想在輸出圖像上
19         # 畫出來,就需要先將它轉換成字符串
20         barcodeData = barcode.data.decode("utf-8")
21         barcodeType = barcode.type
22 
23         #不能顯示中文
24         # 繪出圖像上條形碼的數據和條形碼類型
25         #text = "{} ({})".format(barcodeData, barcodeType)
26         #cv2.putText(imagex1, text, (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX,5, (0, 0, 125), 2)
27 
28         #更換為:
29         img_PIL = Image.fromarray(cv2.cvtColor(imagex1, cv2.COLOR_BGR2RGB))
30 
31         # 參數(字體,默認大小)
32         font = ImageFont.truetype('fontx/hwst.ttf', 25)
33         # 字體顏色(rgb)
34         fillColor = (255,0,0)
35         # 文字輸出位置
36         position = (x, y-10)
37         # 輸出內容
38         str = barcodeData
39 
40         # 需要先把輸出的中文字符轉換成Unicode編碼形式(  str.decode("utf-8)   )
41 
42         draw = ImageDraw.Draw(img_PIL)
43         draw.text(position, str, font=font, fill=fillColor)
44         # 使用PIL中的save方法保存圖片到本地
45         # img_PIL.save('02.jpg', 'jpeg')
46 
47         # 轉換回OpenCV格式
48         imagex1 = cv2.cvtColor(numpy.asarray(img_PIL), cv2.COLOR_RGB2BGR)
49 
50 
51         # 向終端打印條形碼數據和條形碼類型
52         print("掃描結果==》 類別: {0} 內容: {1}".format(barcodeType, barcodeData))
53     cv2.imshow("camera", imagex1)
54     # 窗口等待任意鍵盤按鍵輸入,0為一直等待,其他數字為毫秒數
55     cv2.waitKey(0)
56 
57     # 銷毀窗口,退出程序
58     cv2.destroyAllWindows()
59 
60 def detect():
61     cv2.namedWindow("camera",cv2.WINDOW_NORMAL)
62     frame=cv2.imread("imgx\dongxiao2.png")
63     decodeDisplay(frame)
64 
65 
66 if __name__ == '__main__':
67     detect()

六、實現視頻實時讀取

 OpenCV-Python視頻讀取,並幀處理視頻,實現條碼的動態框選和識別

識別結果:

基本代碼:

 1 import cv2
 2 import pyzbar.pyzbar as pyzbar
 3 import numpy
 4 from PIL import Image, ImageDraw, ImageFont
 5 
 6 def decodeDisplay(imagex1):
 7     # 轉為灰度圖像
 8     gray = cv2.cvtColor(imagex1, cv2.COLOR_BGR2GRAY)
 9     barcodes = pyzbar.decode(gray)
10 
11     for barcode in barcodes:
12 
13         # 提取條形碼的邊界框的位置
14         # 畫出圖像中條形碼的邊界框
15         (x, y, w, h) = barcode.rect
16         cv2.rectangle(imagex1, (x, y), (x + w, y + h), (0, 255, 0), 2)
17 
18         # 條形碼數據為字節對象,所以如果我們想在輸出圖像上
19         # 畫出來,就需要先將它轉換成字符串
20         barcodeData = barcode.data.decode("utf-8")
21         barcodeType = barcode.type
22 
23         #不能顯示中文
24         # 繪出圖像上條形碼的數據和條形碼類型
25         #text = "{} ({})".format(barcodeData, barcodeType)
26         #cv2.putText(imagex1, text, (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX,5, (0, 0, 125), 2)
27 
28 
29         #更換為:
30         img_PIL = Image.fromarray(cv2.cvtColor(imagex1, cv2.COLOR_BGR2RGB))
31 
32         # 參數(字體,默認大小)
33         font = ImageFont.truetype('fontx/hwst.ttf', 35)
34         # 字體顏色(rgb)
35         fillColor = (0,255,255)
36         # 文字輸出位置
37         position = (x, y-10)
38         # 輸出內容
39         str = barcodeData
40 
41         # 需要先把輸出的中文字符轉換成Unicode編碼形式(  str.decode("utf-8)   )
42 
43 
44         draw = ImageDraw.Draw(img_PIL)
45         draw.text(position, str, font=font, fill=fillColor)
46         # 使用PIL中的save方法保存圖片到本地
47         # img_PIL.save('02.jpg', 'jpeg')
48 
49         # 轉換回OpenCV格式
50         imagex1 = cv2.cvtColor(numpy.asarray(img_PIL), cv2.COLOR_RGB2BGR)
51 
52 
53         # 向終端打印條形碼數據和條形碼類型
54         print("掃描結果==》 類別: {0} 內容: {1}".format(barcodeType, barcodeData))
55     cv2.imshow("camera", imagex1)
56 
57 
58 def detect():
59     cv2.namedWindow("camera",cv2.WINDOW_NORMAL)
60     camera = cv2.VideoCapture(0)
61 
62     while True:
63         # 讀取當前幀
64         ret, frame = camera.read()
65         #print(ret.shape)
66         decodeDisplay(frame)
67 
68         if(cv2.waitKey(5)==27):
69             break
70     camera.release()
71     cv2.destroyAllWindows()
72 
73 
74 if __name__ == '__main__':
75     detect()

  


參考:

http://www.cnblogs.com/xushengming/p/9872061.html

https://blog.csdn.net/zx66zx/article/details/82785334

https://blog.csdn.net/x115104/article/details/78878599

https://blog.csdn.net/shanzhizi/article/details/50755168


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM