一維、二維、三維條碼
一維二維都很常見了,三維條碼還是第一次聽說,不知是不是量子雲碼一類的。
網上摘抄了三維條碼簡介:
三維條碼具有更大的信息容量、相同的識別便易性和較好的安全性。
三維碼的主要特征在於利用色彩或灰度(或稱黑密度)表示不同的數據並進行編碼。
其實Python有條碼掃描庫,Python2一直都有一個很是出名,那就是zbar,但此庫。雖然牛,卻已經停止維護了,如果是python3,不能使用zbar庫。
現在對於Python3來說使用比較多的是:pyzbar
pip install pyzbar
使用opencv2,初始化攝像頭信息,調整攝像頭識別圖像的width和height。
import cv2
capture = cv2.VideoCapture(0)
# 攝像頭設置,
capture.set(cv2.CAP_PROP_FRAME_WIDTH, 1024)
capture.set(cv2.CAP_PROP_FRAME_HEIGHT, 1024)
capture.set(cv2.CAP_PROP_EXPOSURE, 0.1)
測試cv2是否可以,調用攝像頭識別圖像,按esc退出
while True:
# 讀取攝像頭中的圖像,ok為是否讀取成功的判斷參數
ret,img = capture.read()
cv2.imshow('frame', img)
k = cv2.waitKey(1)
if k == 27: # 'ESC'關閉
break
識讀條碼
import cv2
import csv
import pyzbar.pyzbar as pyzbar #條碼識讀模塊
barcodeData1 = ''
found = set()
capture = cv2.VideoCapture(0)
# 攝像頭設置
capture.set(cv2.CAP_PROP_FRAME_WIDTH, 1024)
capture.set(cv2.CAP_PROP_FRAME_HEIGHT, 1024)
capture.set(cv2.CAP_PROP_EXPOSURE, 0.1)
while True:
# 讀取攝像頭中的圖像,ok為是否讀取成功的判斷參數
ret, frame = capture.read()
# 轉為灰度圖像
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
barcodes = pyzbar.decode(gray) # 識讀條碼
print(barcodes)
如果識別出來條形碼信息則打印如下:(為了方便觀察添加了換行)
[
Decoded(
data=b’9787545152210’,
type=‘EAN13’,
rect=Rect(left=677, top=116, width=195, height=136),
polygon=[
Point(x=677, y=239),
Point(x=677, y=249),
Point(x=771, y=251),
Point(x=871, y=252),
Point(x=872, y=118),
Point(x=872, y=116),
Point(x=678, y=117)]
)]
上面的信息包含了data即條形碼的值,還有就是Rect矩形區域即識別出的條形碼的區域,以及識別的一些像素點。
如果沒有識別出條形碼信息,則打印出來的是空列表[ ]。
上面代碼中的barcodes返回的是一個列表信息,我們可以對列表信息進行遍歷。獲取條形碼值,type類型和矩形區域。並使用cv2將上圖所示的矩形繪制出來。
for barcode in barcodes:
# 提取條形碼的邊界框的位置
(x, y, w, h) = barcode.rect
# 畫出圖像中條形碼的邊界框
cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 255, 0), 2)
data=b’9787545152210’是字節對象,此時我們需要將字節對象轉成字符串。
# 條形碼數據為字節對象,所以如果我們想在輸出圖像上
# 畫出來,就需要先將它轉換成字符串
barcodeData = barcode.data.decode("utf-8") # utf-8編碼
barcodeType = barcode.type
讀取商品信息表,判斷識別出的條形碼信息,是否在商品表中,為了避免掃描重復多次識別。使用了集合去重復條形碼信息。
code_set = set() # 存放條形碼的集合 # 避免重復讀取
if barcodeData not in code_set:
with open('shopping.csv', 'r') as rs:
reader = csv.reader(rs) # 遍歷超市庫存文件
for line in reader:
if barcodeData in line: # 說明超市有這個商品
print(f'本超市存在此商品,名稱:{
line[1]},價格:{
line[3]}')
break
else:
pass
else:
pass
code_set.add(barcodeData)
打開攝像頭,如果按鍵是ESC則退出,識別系統
cv2.imshow('qrcode+barcode', frame)
k = cv2.waitKey(1)
if k == 27:
breakcv2.destroyAllWindows()
完整代碼:
import cv2import csvimport pyzbar.pyzbar as pyzbarbarcodeData1 = ''code_set = set()capture = cv2.VideoCapture(0)# 攝像頭設置capture.set(cv2.CAP_PROP_FRAME_WIDTH, 1024)capture.set(cv2.CAP_PROP_FRAME_HEIGHT, 1024)capture.set(cv2.CAP_PROP_EXPOSURE, 0.1)while True: # 讀取攝像頭中的圖像,ok為是否讀取成功的判斷參數 ret, frame = capture.read() # 轉為灰度圖像 gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) barcodes = pyzbar.decode(gray) print(barcodes) for barcode in barcodes: # 提取條形碼的邊界框的位置 # 畫出圖像中條形碼的邊界框 (x, y, w, h) = barcode.rect cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 255, 0), 2) # 條形碼數據為字節對象,所以如果我們想在輸出圖像上 # 畫出來,就需要先將它轉換成字符串 barcodeData = barcode.data.decode("utf-8") barcodeType = barcode.type # print(barcodeData) # 判斷多次掃描一個條形碼,只打印一次 if barcodeData == '' or barcodeData != barcodeData1: barcodeData1 = barcodeData print("Recognize result>>> type: {0} content: {1}".format(barcodeType, barcodeData)) else: pass # 避免重復讀取 if barcodeData not in code_set: with open('shopping.csv', 'r') as rs: reader = csv.reader(rs) # 遍歷超市庫存文件 for line in reader: if barcodeData in line: # 說明超市有這個商品 print(f'本超市存在此商品,名稱:{line[1]},價格:{line[3]}') break else: pass else: pass code_set.add(barcodeData) cv2.imshow('qrcode+barcode', frame) k = cv2.waitKey(1) if k == 27: breakcv2.destroyAllWindows()