前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >圆点点二维码的识别

圆点点二维码的识别

作者头像
用户6021899
发布2020-06-22 11:33:56
4.4K1
发布2020-06-22 11:33:56
举报
文章被收录于专栏:Python编程 pyqt matplotlib

如图所示,二维码由不规则的圆点阵列而成,用手机扫描也很难识别。

先进行图像预处理,再识别出斑点:

根据斑点的相对位置生成方阵:

最后填充边界并放大后保存图像,给zxing模块(python调用java)识别。

识别结果如下:

附上源代码:

代码语言:javascript
复制
import cv2
import numpy as np
from matplotlib import pyplot as plt
from PIL import Image
import zxing  # 导入解析包
class BlobDetector(object):
    def __init__(self,thresholdStep = 100,minArea = 200,maxArea= 1000):
        self.params = cv2.SimpleBlobDetector_Params()
        self.params.thresholdStep = thresholdStep #亮度阈值的步长控制,越小检测出来的斑点越多       
        self.params.filterByArea = True #像素面积大小控制
        self.params.minArea = minArea
        self.params.maxArea= maxArea
        self.detector = cv2.SimpleBlobDetector_create(self.params)#创建斑点检测器
    def detect(self,img):
        keypoints = self.detector.detect(img) #在哪个图上检测斑点
        print("共检测出%d个斑点" %len(keypoints))
        im_with_keypoints=cv2.drawKeypoints(thresh, keypoints, np.array([]), (0, 0, 255),cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
        blobs = []
        for (x,y) in keypoints[0].convert(keypoints):
            blobs.append((x,y))
 
        plt.subplot(1,1,1)
        plt.imshow(cv2.cvtColor(im_with_keypoints, cv2.COLOR_BGR2RGB))
        plt.title("OpenCV 斑点检测",fontSize =16, color="b")
        plt.show()
        return blobs
def ocr_qrcode_zxing(filename):
    zx = zxing.BarCodeReader()  # 调用zxing二维码读取包
    zxdata = zx.decode(filename)  # 图片解码
    return zxdata.parsed  # 返回记录的内容

#图像预处理
threshold = 128
img0 = cv2.imread("2.jpg")
gray =cv2.cvtColor(img0, cv2.COLOR_BGR2GRAY)
gauss = cv2.GaussianBlur(gray, (13,13), 0) #高斯模糊,X,Y 方向的Ksiez分别
ret, thresh = cv2.threshold( gauss, threshold, 255,cv2.THRESH_BINARY) #转二值图

#斑点识别
blobDetector = BlobDetector()
blobs = blobDetector.detect(thresh)
#根据各斑点之间的相对位置,将斑点阵列 转换为 值为 0(0代表斑点)和 1 的矩阵
blobs.sort(key = lambda L: L[1])#按行sort
blob_X = [x for (x,y) in blobs]
blob_Y = [y for (x,y) in blobs]
# 18行* 18列 的二维码
index_ychange = []
last_y =blob_Y[0]
for i,y in enumerate(blob_Y):
    #print(y, y-last_y)
    if  y - last_y > 20:#pix
        index_ychange.append(i)
    last_y = y
index_xchange = []
blob_X.sort()
last_x =blob_X[0]
for i,x in enumerate(blob_X):
    if  x - last_x > 20:#pix
        index_xchange.append(i)
    last_x = x      
A = np.ones((18,18),dtype = np.uint8)
j = 0
start = 0
index_ychange.append(len(blobs))
index_xchange.append(len(blobs))
for _ in index_ychange:
    for k in range(start,_):
        x = blobs[k][0] # pix
        x_index  = blob_X.index(x)
        
        for i,m in enumerate(index_xchange):
            #print(i,m)
            if x_index < m:
                break
        #print("x_index,i:",x_index,i)
        A[j, i] = 0 # has dot. 零代表斑点
    start = _
    j += 1
    #print("j:",j)
   
for row in A:
     print(row)
A *= 255 # 变成黑白图像数组
#周围填充白色方便识别
N = 20
B = np.ones((N,N),dtype = np.uint8)
B *= 255
B[ (N-18)//2:N-(N-18)//2 , (N-18)//2:N-(N-18)//2] =A
plt.subplot(1,1,1)
plt.imshow(B,cmap ="gray")
plt.title("OpenCV 斑点检测",fontSize =16, color="b")
plt.show()

# 放大图像,提高识别率
rows,cols = B.shape
k =2
C = np.zeros((rows*k,cols*k))
for i in range(rows):
    for j in range(cols):
        C[k*i:k*(i+1),k*j:k*(j+1)] = B[i,j]
cv2.imwrite('test.bmp',C)

result = ocr_qrcode_zxing("test.bmp")
print(result)

程序还需改进以提高健壮性。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-06-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Python可视化编程机器学习OpenCV 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档