用不同的QR Code識別庫實現二維碼的識別(第一篇:opencv 和BoofCV)

最近有個項目需要實現二維碼的識別和攝像頭的數據採集。在開始正式項目之前,我決定用python寫幾行簡單的代碼來測試每個庫的識別效果。這次沒有連續測量,也沒有使用多線程識別。只是簡單的測試了每個二維碼的測試效果。這次測試的有opencv 4.2的QRCodeDetector庫,BoofCV的庫,Quirc,Zbar和ZXing。視頻的採集統一使用cv的VideoCapture,視頻的存儲統一使用cv的VideoWriter。我的硬件環境是orange pi 3 的2G內存版,系統是armbian的Debian GNU/Linux 10 (buster)。事先已經配置好了opencv、java和PyBoof等必備條件。

1、首先測試的是opencv

代碼如下(附件test_qr.py):

import numpy as np
import cv2
import os
import time

video_path = '~/Downloads/'

# VideoCapture
cap = cv2.VideoCapture(0, cv2.CAP_V4L2)
cap.set(3, 1280)
cap.set(4, 720)
cap.set(5, 30)

# VideoWriter
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
outVideo = cv2.VideoWriter()
outVideo.open('output.mp4',fourcc,30.0,(1280,720), True )

# QRCodeDetector
findQR = False
qrResult = ''
qrDetector = cv2.QRCodeDetector()




print('Demo will work')
cnt = 0

while(cap.isOpened()):
    ret, frame = cap.read()
    if ret==True:
        #frame = cv2.flip(frame,-1)
        outVideo.write(frame)
        
        # QR Code Detector
        if not findQR :
            frame_mono = cv2.cvtColor(np.uint8(frame), cv2.COLOR_BGR2GRAY) 
            start = time.time_ns()
            qrDone, points = qrDetector.detect(frame_mono)
            if qrDone:
                #print("find QR Code. Frame counter is ", cnt )
                qrString, straight = qrDetector.decode(frame_mono, points)
                if len(qrString) >1:
                    end = time.time_ns()
                    print("Running time is ",str(end - start))
                    findQR = True
                    qrResult = qrString
                    print("find QR Code")

    else:
        print('fail to open camera')
        break
    cnt += 1
    if cnt > 300 :
        print('Have created output.avi')
        break

if findQR:
    print("QR Code  is: {}".format(qrResult))
else:
    print("Didn't find QR Code!")

cap.release()
outVideo.release()
cv2.destroyAllWindows()


    

評測結果是detect的效果很差,總有誤動作。需要對decode的結果判斷一下是否是空字符串。

用草料二維碼生成的文本或者網址都可以很好識別,但很難識別微信和支付寶的二維碼。可能需要提前對圖片做一定的旋轉和銳化處理。也可能與識別的光線有關係。

2、BoofCV(PyBoof)

這個庫在該網站的分析報告中評價最高,無論是識別效果還是識別速率。本身是java編寫的。但我們使用python版本的PyBoof。

代碼如下(附件中test_boof.py):

import numpy as np
import pyboof as pb
import cv2
import os
import time


video_path = '~/Downloads/'

# VideoCapture
cap = cv2.VideoCapture(0, cv2.CAP_V4L2)
cap.set(3, 1280)
cap.set(4, 720)
cap.set(5, 30)

# VideoWriter
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
outVideo = cv2.VideoWriter()
outVideo.open('output.mp4',fourcc,10.0,(1280,720), True )

# QRCodeDetector
findQR = False
qrResult = ''
pb.init_memmap()
detector = pb.FactoryFiducial(np.uint8).qrcode()



print('Demo will work')
cnt = 0

while(cap.isOpened()):
    ret, frame = cap.read()
    if ret==True:
        #frame = cv2.flip(frame,-1)
        outVideo.write(frame)
        
        # QR Code Detector
        if not findQR :
            frame_mono = cv2.cvtColor(np.uint8(frame), cv2.COLOR_BGR2GRAY)
            boof_img = pb.ndarray_to_boof(frame_mono)
            #boof_img = pb.load_single_band( 'path to image', np.uint8)
            start = time.time_ns()
            detector.detect(boof_img)
            if len(detector.detections)>0:
                end = time.time_ns()
                print("running time is ", str(end - start))
                print("find QR Code " )
                findQR = True
                qrResult = detector.detections[0].message

    else:
        print('fail to open camera')
        break
    cnt += 1
    if cnt > 100 :
        print('Have created output.mp4')
        break

if findQR:
    print("QR Code  is: {}".format(qrResult))
else:
    print("Didn't find QR Code!")

cap.release()
outVideo.release()
cv2.destroyAllWindows()


    

這個庫可以識別多個二維碼,總體來說識別準確率還是挺高的。但是昨晚測試時發現和opencv一樣很難識別手機展示的微信和支付寶二維碼。需要嘗試很多次。但今天白天的測試發現和opencv一樣都能正常測試。讓人疑惑。總體上識別需要花費的時間也比opencv短。

3、測試

第一項測試是微信二維碼截圖:

opencv和boofcv二維碼識別比較

可以看出識別速率都不高,都需要幾百毫秒時間。可能與我使用的嵌入式板卡性能有關。後面將繼續測試zbar,zxing和quirc的效果。

第二項測試是使用草料二維碼生成的二維碼字符串

字符串測試

可以看出來兩者都很慢,需要600ms以上。可能與python有關係,因爲opencv的原生環境是c++而boofcv的是java。也可能與硬件本身的性能有關係。

 

(後面一篇將繼續測試另外幾個library)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章