- A+
一、机器视觉之QRcode
问:什么是QRcode呢?
答:二维码(2-dimensional bar code),是用某种特定的几何图形按一定规律在平面(二维方向上)分布的黑白相间的图形记录数据符号信息的。它能将数字、英文字母、汉字、日文字母、特殊符号(如空格,%,/ 等)、二进制等信息记录到一个正方形的图片中。
因此,在转换的过程中,离不开编码压缩方式。在许多种类的二维条码中,常用的码制有:Data Matrix,Maxi Code,Aztec,QR Code,Vericode,PDF417,Ultracode,Code 49,Code 16K等。
二维码在现实生活中的应用越来与普遍,归功于 QR code 码制的流行。我们常说的二维码就是它,所以,二维码又被称为 QR code。
QR code 是一种矩阵式二维条码(又称棋盘式二维条码)。它是在一个矩形空间通过黑、白像素在矩阵中的不同分布进行编码。在矩阵相应元素位置上,用点(方点、圆点或其他形状)的出现表示二进制“1”,点的不出现表示二进制的“0”,点的排列组合确定了矩阵式二维条码所代表的意义。
我们的目的是要使用 Python 生成 QR 码
,那我们需要先了解二维码(QR 码)的结构。根据标准(ISO/IEC 18004),我们可以了解到 QR 码结构如下:
二维码的绘制大概过程如下:
在二维码的左上角、左下角、右上角绘制位置探测图形,位置探测图形一定是一个 7x7 的矩阵;
(1)绘制校正图形,校正图形一定是一个 5x5 的矩阵;
(2)绘制两条连接三个位置探测图形的定位图形;
(3)在上述图片的基础上,继续绘制格式信息;
(4)接着绘制版本信息;
(5)填充数据码和纠错码到二维码图中;
(6)最后绘制蒙版图案。因为按照上述方式填充内容,可能会出现大面积空白或黑块的情况,导致扫描识别十分困难。所以需要对整个图像与蒙版进行蒙版操作(Masking),蒙版操作即为异或 XOR 操作。在这一步,我们可以将数据排列成各种图片。
问:主要运用qrcode库文件、这是个什么东东呢?
答: 这里给一篇博客有详细叙述:Python生成二维码
开源库import qrcode
具体使用方法:
编码:
import qrcode
img = qrcode.make('helloworld')
qr = qrcode.QRCode(
version=5,
error_correction=qrcode.constants.ERROR_CORRECT_H,
box_size=8,
border=4)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
解码:
def decode_qr_code(code_img_path):
if not os.path.exists(code_img_path):
raise FileExistsError(code_img_path)
return pyzbar.decode(Image.open(code_img_path), symbols=[pyzbar.ZBarSymbol.QRCODE])
- 1
- 2
- 3
- 4
- 5
- 6
二、基于Python的QRcodetest
环境:
python3.7+zbar+qrcode
(一)配置环境
打开cmd、pip分别安装以下库文件:(zxing
也是一个强大的二维码开源库文件,建议安装)
pip install opencv-python
pip install numpy
pip install pillow
pip install myqr
pip install qrcode
pip install zxing
- 1
- 2
- 3
- 4
- 5
- 6
tips:记得安装完成后,如果是eclipse要重新启动一次才能加载进来
(二)生成自己的二维码
1 MyQr制作gif二维码:
同目录下放置一张gif格式图片
源码:
from MyQR import myqr
myqr.run(
words='helloworld',
version=1,
level='H',
picture='test.gif',
colorized=True,
contrast=1.0,
brightness=1.0,
)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
2 qrcode制作带图片的二维码:
新建工程QRcodeTest
;新建PyDev包,命名为MakeMyQRcode
:
因为我想做出一个漂亮简单一点的code,所以首先在目录文件下贴入一张图片,命名为
QRcodeCenter
,like this(左:成果图,右:准备中心图片):
源码:
'''
==============================
test1:生成二维码及查看
==============================
'''
from PIL import Image
import qrcode
qr = qrcode.QRCode(
version=5, error_correction=qrcode.constants.ERROR_CORRECT_H, box_size=8, border=4)
qr.add_data("这里是二维码信息!")
qr.make(fit=True)
img = qr.make_image()
img = img.convert("RGBA")
icon = Image.open("QRcodeCenter.jpg")
img_w, img_h = img.size
factor = 4
size_w = int(img_w / factor)
size_h = int(img_h / factor)
icon_w, icon_h = icon.size
if icon_w > size_w:
icon_w = size_w
if icon_h > size_h:
icon_h = size_h
icon = icon.resize((icon_w, icon_h), Image.ANTIALIAS)
w = int((img_w - icon_w) / 2)
h = int((img_h - icon_h) / 2)
icon = icon.convert("RGBA")
img.paste(icon, (w, h), icon)
img.show()
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
(三)识别二维码
在工程QRcodeTest
;新建PyDev包,命名为ScanQRcode
:
运行结果:
源码:
'''
====================================
test2:生成二维码保存及对二维码解码输出
====================================
'''
import os
import qrcode
from PIL import Image
from pyzbar import pyzbar
def make_qr_code(content, save_path=None):
qr_code_maker = qrcode.QRCode(version=5,
error_correction=qrcode.constants.ERROR_CORRECT_M,
box_size=8,
border=4,
)
qr_code_maker.add_data(data=content)
qr_code_maker.make(fit=True)
img = qr_code_maker.make_image(fill_color="black", back_color="white")
if save_path:
img.save(save_path)
else:
img.show()
def make_qr_code_with_icon(content, icon_path, save_path=None):
if not os.path.exists(icon_path):
raise FileExistsError(icon_path)
qr_code_maker = qrcode.QRCode(version=5,
error_correction=qrcode.constants.ERROR_CORRECT_H,
box_size=8,
border=4,
)
qr_code_maker.add_data(data=content)
qr_code_maker.make(fit=True)
qr_code_img = qr_code_maker.make_image(
fill_color="black", back_color="white").convert('RGBA')
icon_img = Image.open(icon_path)
code_width, code_height = qr_code_img.size
icon_img = icon_img.resize(
(code_width // 4, code_height // 4), Image.ANTIALIAS)
qr_code_img.paste(icon_img, (code_width * 3 // 8, code_width * 3 // 8))
if save_path:
qr_code_img.save(save_path)
qr_code_img.show()
else:
print("save error!")
def decode_qr_code(code_img_path):
if not os.path.exists(code_img_path):
raise FileExistsError(code_img_path)
return pyzbar.decode(Image.open(code_img_path), symbols=[pyzbar.ZBarSymbol.QRCODE])
if __name__ == "__main__":
print("============QRcodetest===============")
print(" 1、Make a QRcode ")
print(" 2、Scan a QRcode ")
print("=====================================")
print("1、请输入编码信息:")
code_Data = input('>>:').strip()
print("正在编码:")
make_qr_code_with_icon(
code_Data, "QRcodeCenter.jpg", "qrcode.png")
print("图片已保存,名称为:qrcode.png")
results = decode_qr_code("qrcode.png")
print("2、正在解码:")
if len(results):
print("解码结果是:")
print(results[0].data.decode("utf-8"))
else:
print("Can not recognize.")
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
三、调用opencv库摄像头识别图像
(一)用opencv找出(条形码&二维码)位置
opencv抠图教程
按照教程一步步调试运行(这里用一张条形码和一张二维码进行测试):
- 在
QRcodetest
项目下新建ScanQRcode.py
- 并保存两张图片在项目目录下:分别为
qrcode.png
和test2.jpg
运行测试:(不支持二维码)
qrcode.png:
test2.jpg:
遇到问题:
都只识别了部分条码,抠图也不是很成功!而且不能识别二维码!
源码:
'''
==============================
test3:找出图片中的条形码或二维码
(ps.仅识别条形码成功)
==============================
'''
import numpy as np
import argparse
import cv2
print("请输入解码图片完整名称:")
code_name = input('>>:').strip()
print("正在识别:")
image = cv2.imread(code_name)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
gradX = cv2.Sobel(gray, ddepth=cv2.cv2.CV_32F, dx=1, dy=0, ksize=-1)
gradY = cv2.Sobel(gray, ddepth=cv2.cv2.CV_32F, dx=0, dy=1, ksize=-1)
gradient = cv2.subtract(gradX, gradY)
gradient = cv2.convertScaleAbs(gradient)
blurred = cv2.blur(gradient, (9, 9))
(_, thresh) = cv2.threshold(blurred, 225, 255, cv2.THRESH_BINARY)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (21, 7))
closed = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)
closed = cv2.erode(closed, None, iterations=4)
closed = cv2.dilate(closed, None, iterations=4)
(_, cnts, _) = cv2.findContours(closed.copy(),
cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
c = sorted(cnts, key=cv2.contourArea, reverse=True)[0]
rect = cv2.minAreaRect(c)
box = np.int0(cv2.boxPoints(rect))
cv2.drawContours(image, [box], -1, (0, 255, 0), 3)
cv2.imshow("ScanQRcodeTest", image)
cv2.waitKey(0)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
(二)调用解码函数进行解码
- 在
QRcodetest
项目下新建ScanInvedio.py
运行测试:(不支持条形码)
因为我自身电脑摄像头设置,颜色有点问题,请忽略
源码:
'''
================================
test4:识别摄像头中的条形码或二维码
(ps.仅识别二维码码成功)
================================
'''
import cv2
import pyzbar.pyzbar as pyzbar
def decodeDisplay(image):
barcodes = pyzbar.decode(image)
for barcode in barcodes:
(x, y, w, h) = barcode.rect
cv2.rectangle(image, (x, y), (x + w, y + h), (225, 225, 225), 2)
barcodeData = barcode.data.decode("utf-8")
barcodeType = barcode.type
text = "{} ({})".format(barcodeData, barcodeType)
cv2.putText(image, text, (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX,
.5, (225, 225, 225), 2)
print("[INFO] Found {} barcode: {}".format(barcodeType, barcodeData))
return image
def detect():
camera = cv2.VideoCapture(0)
while True:
ret, frame = camera.read()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
im = decodeDisplay(gray)
cv2.waitKey(5)
cv2.imshow("camera", im)
if cv2.waitKey(10) & 0xFF == ord('q'):
break
camera.release()
cv2.destroyAllWindows()
if __name__ == '__main__':
detect()
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
大功告成!
- 我的微信
- 这是我的微信扫一扫
- 我的微信公众号
- 我的微信公众号扫一扫