import cv2
import numpy as np
import pyzbar.pyzbar as pyzbar
def prethreatment(img):
# make img into gray
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# threshold
ret, thre = cv2.threshold(gray, 100, 255, cv2.THRESH_BINARY)
# cv2.imshow('thre',thre)
# erode
kernel = np.ones((5, 5), np.uint8)
erosion = cv2.erode(thre, kernel)
erosion = cv2.erode(erosion, kernel)
# cv2.imshow('erosion',erosion)
# findContours
contours, hier = cv2.findContours(erosion,
cv2.RETR_LIST,
cv2.CHAIN_APPROX_SIMPLE)
return contours, gray
def pick_rectangels(contours):
# choosecontours
rec = []
for c in contours:
x, y, w, h = cv2.boundingRect(c) # 计算出一个简单地边界框
if (abs(w - h) < 10) & (w > 50):
rec.append([x, y, w, h])
print(rec)
return rec
def decode_qrcodes(rec, gray):
for r in rec:
x1 = r[0]
x2 = r[0] + r[2]
y1 = r[1]
y2 = r[1] + r[3]
img = gray[y1:y2, x1:x2]
img = cv2.resize(img, (r[3] * 2, r[2] * 2))
message = decode_qrcode(img)
print(x1, x2, y1, y2, message)
def decode_qrcode(image):
barcodes = pyzbar.decode(image)
for barcode in barcodes:
# 条形码数据为字节对象,所以如果我们想在输出图像上
# 画出来,就需要先将它转换成字符串
barcodeData = barcode.data.decode("utf-8")
barcodeType = barcode.type
# 提取条形码的边界框的位置
# 画出图像中条形码的边界框
# (x, y, w, h) = barcode.rect
# cv2.rectangle(image, (x, y), (x + w, y + h), (0, 0, 255), 2)
# 向终端打印条形码数据和条形码类型
# print("[INFO] Found {} barcode: {}".format(barcodeType, barcodeData))
try:
return barcodeData
except:
return -1
if __name__ == '__main__':
imgpath = "n_2.jpg"
img0 = cv2.imread(imgpath)
h, w, _ = img0.shape
img0 = cv2.resize(img0, (w // 2, h // 2))
contours, gray = prethreatment(img0)
rec = pick_rectangels(contours)
decode_qrcodes(rec, gray)
for rect in rec:
cv2.rectangle(img0, (rect[0], rect[1]), (rect[0] + rect[2], rect[1] + rect[3]), (255, 0, 255), 3)
img0 = cv2.resize(img0, (w // 3, h // 3))
cv2.imshow('0', img0)
cv2.waitKey(0)
cv2.destroyAllWindows()
网友评论