條碼在生活中隨處可見,其可分為三類:一維條碼、二維條碼、三維條碼
一維條碼:
我們平時習慣稱為條形碼。條形碼是將寬度不等的多個黑條和空白,按照一定的編碼規則排列,用以表達一組信息的圖形標識符。常見的條形碼是由反射率相差很大的黑條(簡稱條)和白條(簡稱空)排成的平行線圖案。
二維條碼:
二維條碼簡稱為二維碼,常見的二維碼為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相關庫,可參考以下鏈接進行簡單認識和庫的安裝
三、系統環境准備
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