起因
今天 rockets 问我, 是否能够将二维码里面的色块用 0 和 1 表示出来.
分析
我脑海里分析了一下,不知道是不是可以用 opencv 实现,就打开电脑尝试了一下,似乎是可以的.
思路, 首先通过 qrcode 生成一个图片,然后保存一下,通过opencv 导入图片,然后再判断 10x10 大小的块中是否全是白色,如果是白色,就写一个 1
,如果是黑色,就写个 0. 然后遍历整个图片的 shape.
Talk is cheap, show me the code
import qrcode
import cv2
import numpy as np
url = 'https://www.dfrobot.com/product-2480.html'
file_name = 'qrcode.png'
def generate_image(url):
qr = qrcode.QRCode()
qr.add_data(url)
qr.make(fit=False)
img = qr.make_image(fill_color="black", back_color="white")
img.save(file_name)
generate_image(url)
img1 = cv2.imread(file_name)
scale_percent = 80
width = int(img1.shape[1] * scale_percent / 100)
height = int(img1.shape[0] * scale_percent / 100)
dim = (width, height)
resized_img = cv2.resize(img1, dim, interpolation=cv2.INTER_AREA)
# gray_img1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
for i in range(0, int(resized_img.shape[0]), 10):
for j in range(0, int(resized_img.shape[1]), 10):
if np.mean(resized_img[i:i+10, j:j+10]) == 255:
cv2.putText(resized_img, '0', (i, j), cv2.FONT_HERSHEY_SIMPLEX, .2, (255, 0, 0))
else:
cv2.putText(resized_img, '1', (i, j), cv2.FONT_HERSHEY_SIMPLEX, .2, (255, 0, 0))
cv2.imshow('resized_img', resized_img)
cv2.waitKey(0)
执行效果:
重点
np.mean(图片数组) == 255的判断部分,可以判断图片是不是白色.
重构了一下,优化后:
import qrcode
import cv2
import numpy as np
# 定义生成 qrcode 的 url 链接和生成的文件名
url = 'https://www.dfrobot.com/product-2480.html'
file_name = 'qrcode.png'
def generate_image(url):
""""
生成二维码并保存
"""
qr = qrcode.QRCode()
qr.add_data(url)
qr.make(fit=False)
img = qr.make_image(fill_color="black", back_color="white")
img.save(file_name)
def process_image(filename):
"""
:param filename: 放入生成的二维码
:return: 显示图
"""
img1 = cv2.imread(file_name)
scale_percent = 80
width = int(img1.shape[1] * scale_percent / 100)
height = int(img1.shape[0] * scale_percent / 100)
dim = (width, height)
resized_img = cv2.resize(img1, dim, interpolation=cv2.INTER_AREA)
for i in range(0, int(resized_img.shape[0]), 10):
for j in range(0, int(resized_img.shape[1]), 10):
if np.mean(resized_img[i:i+5, j:j+5]) == 255:
cv2.putText(resized_img, '0', (i+5, j+5), cv2.FONT_HERSHEY_SIMPLEX, .2, (255, 0, 0))
else:
cv2.putText(resized_img, '1', (i+5, j+5), cv2.FONT_HERSHEY_SIMPLEX, .2, (255, 0, 0))
cv2.imshow('resized_img', resized_img)
cv2.waitKey(0)
if __name__ == "__main__":
generate_image(url)
process_image(file_name)
优化后结果:
感觉还是不太对.
继续优化试试看.
import qrcode
import cv2
import numpy as np
# 定义生成 qrcode 的 url 链接和生成的文件名
url = 'https://www.dfrobot.com/product-2480.html'
file_name = 'qrcode.png'
def generate_image(url):
""""
生成二维码并保存
"""
qr = qrcode.QRCode()
qr.add_data(url)
qr.make(fit=False)
img = qr.make_image(fill_color="black", back_color="white")
img.save(file_name)
def process_image(filename):
"""
:param filename: 放入生成的二维码
:return: 显示图
"""
img1 = cv2.imread(file_name)
scale_percent = 200
width = int(img1.shape[1] * scale_percent / 100)
height = int(img1.shape[0] * scale_percent / 100)
dim = (width, height)
resized_img = cv2.resize(img1, dim, interpolation=cv2.INTER_AREA)
resized_img = cv2.cvtColor(resized_img, cv2.COLOR_BGR2GRAY)
for i in range(0, int(resized_img.shape[0]), 10):
for j in range(0, int(resized_img.shape[1]), 10):
if np.mean(resized_img[i:i+3, j:j+3]) == 255:
cv2.putText(resized_img, '1', (i + 5, j + 5), cv2.FONT_HERSHEY_SIMPLEX, .2, (0, 0, 255))
else:
cv2.putText(resized_img, '0', (i + 5, j + 5), cv2.FONT_HERSHEY_SIMPLEX, .2, (255, 0, 0))
cv2.imshow('img', resized_img)
cv2.waitKey(0)
if __name__ == "__main__":
generate_image(url)
process_image(file_name)