android end use license plate detection openCV

        Now, the car disappeared everywhere, gallop on the road, the street while the provisional arrest, the cell stops, parked in the garage. Management and monitoring such a large number of cars is a headache. Smart people to look at the license plate, car license plates because of "identity." Therefore, license plate recognition has become the focus, license plate detecting license plate recognition is the basis and prerequisite. This article mainly discuss the use of openCV achieve license plate detection .

        openCV is an open source computer vision library, computer vision and machine learning, provides powerful image processing capabilities. We can quickly integrate into the android library openCV end, one way is mounted directly openCV Manager, on-demand: Start Services to dynamic loading. Such pre-configuration easier, but need to install an APK. I prefer another way: the dependent module and dynamic / static libraries are imported Project. Specific steps are as follows:

        1, the import module

        OpenCVForAndroid start official website to download the sdk, in order to 3.2.0 version, for example, find dependent libraries path, and then import the module.

        2, import dynamic and static libraries

        Lib directory in the sdk found inside, copy all the files .so and .a libs to correspond to the items under ABI path:


        3, configuration gradle

        We will rely on static library compiled to native-libs inside:

task nativeLibsToJar(type: Jar, description: 'create a jar archive of the native libs') {
    destinationDir file("$buildDir/native-libs")
    baseName 'native-libs'
    from fileTree(dir: 'libs', include: '**/*.so')
    into 'lib/'
}

tasks.withType(JavaCompile) {
    compileTask -> compileTask.dependsOn(nativeLibsToJar)
}
        
dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    compile fileTree(dir: "$buildDir/native-libs", include: 'native-libs.jar')
    ......
}

        Well, after configuration trilogy, we can happily use the openCV.

-------------------------------------------------- --- intermission -------------------------------------------- ---------------------

        Next is the call trilogy: Load openCV, initialize the license plate detectors and license plate detection execution

        1, load openCV

        Call openCVLoader to load, if successfully loaded the next step:

    private void initOpenCV(){
        boolean result = OpenCVLoader.initDebug();
        if(result){
            Log.i(TAG, "initOpenCV success...");
            //初始化车牌检测器
            mPlateDetector = new ObjectDetector(this, R.raw.haarcascade_license_plate,
                    3, new Scalar(255, 0, 0, 0));
            mObject = new MatOfRect();
        }else {
            Log.e(TAG, "initOpenCV fail...");
        }
    }
        2, the initialization detector

        Using license plate detection cascade classifier xml file to initialize:

    /**
     * 创建级联分类器
     * @param context 上下文
     * @param id      级联分类器ID
     * @return 级联分类器
     */
    private CascadeClassifier createDetector(Context context, int id) {
        CascadeClassifier javaDetector;
        InputStream is = null;
        FileOutputStream os = null;
        try {
            is = context.getResources().openRawResource(id);
            File cascadeDir = context.getDir(LICENSE_PLATE_MODEL, Context.MODE_PRIVATE);
            File cascadeFile = new File(cascadeDir, id + ".xml");
            os = new FileOutputStream(cascadeFile);

            byte[] buffer = new byte[4096];
            int bytesRead;
            while ((bytesRead = is.read(buffer)) != -1) {
                os.write(buffer, 0, bytesRead);
            }

            javaDetector = new CascadeClassifier(cascadeFile.getAbsolutePath());
            if (javaDetector.empty()) {
                javaDetector = null;
            }

            boolean delete = cascadeDir.delete();
            Log.i("ObjectDetector", "deleteResult=" + delete);
            return javaDetector;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        } finally {
            try {
                if (null != is) {
                    is.close();
                }
                if (null != os) {
                    os.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
        3, license plate detection performed

        Since the operation target is openCV Mat, so we have to turn into Bitmap Mat, grayscale and then converted into Gray to detect:

    /**
     * 执行车牌检测
     * @param bitmap bitmap
     * @return 车牌检测后的bitmap
     */
    private Bitmap doPlateDetecting(Bitmap bitmap){
        if(mPlateDetector != null && bitmap != null){
            Mat mRgba = new Mat();
            Mat mGray = new Mat();
            //bitmap转成map
            Utils.bitmapToMat(bitmap, mRgba);
            //rgba转成灰度图
            Imgproc.cvtColor(mRgba, mGray, Imgproc.COLOR_RGBA2GRAY);
            // 检测车牌
            Rect[] object = mPlateDetector.detectObject(mGray, mObject);
            if(object != null && object.length > 0){
                //检测到车牌区域
                Rect rect = object[0];
                //矩形标识
                Imgproc.rectangle(mRgba, rect.tl(), rect.br(), mPlateDetector.getRectColor(), 3);
            }
            //mat转回bitmap
            Utils.matToBitmap(mRgba, bitmap);
        }
        return bitmap;
    }
        Wherein, detectObject body is a method call to complete cascadeClassifier of detectMultiScale detected:

    public Rect[] detectObject(Mat gray, MatOfRect object) {
        mCascadeClassifier.detectMultiScale(
                gray, // 要检查的灰度图像
                object, // 检测到的车牌
                1.1, // 表示在前后两次相继的扫描中,搜索窗口的比例系数
                mMinNeighbors, // 默认是3
                Objdetect.CASCADE_SCALE_IMAGE,
                getSize(gray, 80), // 检测目标最小值
                getSize(gray, 800)); // 检测目标最大值

        return object.toArray();
    }
        Toss so long, let's take a look at the license plate test results:


        Above the license plate is almost horizontal, then tilt the license plate can not detect it? The truth is the following:


        The plates are tilted angle can be detected, but the license plate recognition in later, inclination correction is required. If the static detection is not terrific, then look at the effect of motion detection (convert gif out a bit fuzzy, I wonder, then):


        The next blog post will be with you to discuss the license plate recognition, so stay tuned. Make recommendations to welcome you to the love and image processing openCV friends, learn from each other.

Published 63 original articles · won praise 179 · views 180 000 +

Guess you like

Origin blog.csdn.net/u011686167/article/details/79008634