圆点点二维码的识别

2020-06-22 11:33:56 浏览数 (1)

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

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

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

最后填充边界并放大后保存图像,给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)

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

0 人点赞