1. 程式人生 > >android端使用openCV與深度學習實現車牌識別

android端使用openCV與深度學習實現車牌識別

車牌識別的應用場景隨處可見:高速公路上超速抓拍、小區門口關卡、車庫入口關卡,甚至出現在車載裝置上。它的工作原理大致這樣:使用攝像頭充當“眼睛”,使用openCV與深度學習充當“大腦”。實時車牌識別工作步驟:攝像頭抓拍—>openCV初步定位車牌位置—>二次確認車牌位置的左右上下邊界—>車牌傾斜校正—>車牌字元切割—>車牌字元識別。其中,車牌檢測是車牌識別的前提條件和重要基礎。

在上篇部落格介紹過使用openCV實現車牌檢測,大家感興趣可以看下:android端使用openCV實現車牌檢測

關於openCV的初始化,與車牌檢測一樣(可以參考上篇部落格)。呼叫車牌識別JNI介面時,首先進行初始化,載入caffe訓練模型相關檔案:

        plateRecognition = new PlateRecognition(this, mHandler);
        //init plate recognizer
        new Thread(new Runnable() {
            @Override
            public void run() {
                plateRecognition.initRecognizer("pr");
            }
        }).start();

攝像頭實時抓拍,回撥每幀資料給車牌識別執行緒。需要注意的是,車牌識別中openCV操作物件是Mat,而不是Bitmap:

    public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
        //每次進行車牌識別間隔3s
        long currentTime = System.currentTimeMillis();
        if((currentTime - lastRecognizeTime) > 3000){
            lastRecognizeTime = currentTime;
            //回撥給車牌識別執行緒處理
            if(onNewFrameListener != null){
                onNewFrameListener.onNewFrame(inputFrame.rgba());
            }
        }
        return inputFrame.rgba();
    }
    public void onNewFrame(Mat newFrame) {
        if(dstMat == null){
            dstMat = new Mat(newFrame.rows(), newFrame.cols(), CvType.CV_8UC4);
        }
        //mat格式轉換
        newFrame.copyTo(dstMat);
        //新增到車牌識別執行緒的佇列中
        if(recognizeThread != null){
            recognizeThread.addMat(dstMat);
        }
    }

其中,車牌識別執行緒呼叫native層執行,最終把識別結果返回給java層:

    public void run() {
        while (isRunning){
            Mat mat = null;
            synchronized (lock){
                //從佇列取出mat物件
                if(matQueue != null && matQueue.size() > 0){
                    mat = matQueue.poll();
                }
            }
            //呼叫native層,執行車牌識別
            if(mat != null && plateRecognition != null){
                plateRecognition.doPlateRecognize(mat);
            }
        }
    }

使用openCV的級聯分類器CascadeClassifier去檢測,得到車牌所在整個影象的矩形區域,然後二次確認車牌的左右、上下邊界,判斷車牌是否發生傾斜,如果有傾斜則進行校正。通過滑動視窗來切割車牌字元,使用CNN深度學習對每個字元進行識別。最終得到識別結果與識別置信度,如果置信度大於一定閾值,那麼該輪識別結果可靠。這裡涉及到的caffe深度學習訓練框架,是賈揚清博士開源的一套框架,如果需要詳細瞭解可訪問官網:caffe深度學習框架

整個識別過程,單個車牌耗時300ms左右,準確率達到95%,看下單個車牌識別結果:





        一張影象包含兩個車牌的識別結果:


        實時的車牌識別如下圖: