Сегментация и распознавание символов - PullRequest
0 голосов
/ 04 февраля 2019

Пытался создать ANPR на базе Android для нашего дипломного проекта, но возникли проблемы с сегментацией и распознаванием символов.Я впервые имею дело с ANPR, Android и Eclipse.Я понятия не имею вообще.Прогресс, который я сделал, был только самоучкой.Я попробовал все, но я думаю, что это мой предел.Пытался провести какое-то исследование, но большинство из них используют Tesseract-ocr, который нам не разрешен.Я использую Eclipse-Kepler в качестве моей IDE.Был бы очень признателен за помощь.Спасибо!Вот мой код:

package com.example.camera2;

//java imports
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

//opencv imports
import org.opencv.android.BaseLoaderCallback;
import org.opencv.android.LoaderCallbackInterface;
import org.opencv.android.OpenCVLoader;
import org.opencv.android.Utils;
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;

import org.opencv.core.Point;
import org.opencv.core.Rect;
import org.opencv.core.Scalar;
import org.opencv.imgproc.Imgproc;

//android imports
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Paint;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;

public class MainActivity extends Activity {

    private static final String  TAG = "Browse Pics";
    protected static final int CAMERA_PIC_REQUEST = 0;
    private static final int SELECTED_PICTURE = 1;
    private OnClickListener ocl;
    private Button capture, browse;
    private ImageView iv;
    private Bitmap bmpClone;
    public static int threshold = 185;
    Mat maskrgb;

    static
    {
        if (OpenCVLoader.initDebug())
        {
            Log.i(TAG, "OK");
            System.loadLibrary("opencv_java");
        }else{
            Log.i(TAG, "Error encountered");
        }

    }

    private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this){

        @Override
        public void onManagerConnected(int status) {
            // TODO Auto-generated method stub
            switch(status){
                case LoaderCallbackInterface.SUCCESS:{
                    Log.i(TAG, "OpenCV loaded successfully");
                    break;
                }
                default:
                {
                    super.onManagerConnected(status);
                }
            }
        }

    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if (!OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_13, this, mLoaderCallback))
        {
          Log.e(TAG, "Cannot connect to OpenCV Manager");
        }else{
            Log.i(TAG, "OpenCV successful");
            setContentView(R.layout.activity_main);
            browse = (Button)this.findViewById(R.id.button1);
            capture = (Button)this.findViewById(R.id.button2);
            iv = (ImageView)this.findViewById(R.id.imageView1);
            ocl = new View.OnClickListener() {

                @Override
                public void onClick(View v) {
                    // TODO Auto-generated method stub
                    if(v.getId() == browse.getId()){ //when browse button is clicked
                        iv.setImageBitmap(null);
                        Intent i = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                        startActivityForResult(i, SELECTED_PICTURE);
                    }
                    else if(v.getId() == capture.getId()){  //when capture button is clicked
                        ImageView imageview = (ImageView) findViewById(R.id.imageView1);
                        imageview.setImageBitmap(null);
                        Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); 
                        startActivityForResult(cameraIntent, CAMERA_PIC_REQUEST);
                    }

                    }
            };
            browse.setOnClickListener(ocl);
            capture.setOnClickListener(ocl);
        }
    }

    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        switch(requestCode){
        case SELECTED_PICTURE:  //browse from gallery
            if(resultCode == RESULT_OK && null != data){
                Uri selectedImage = data.getData();
                String[] filePathColumn = {MediaStore.Images.Media.DATA};
                Cursor cursor = getContentResolver().query(selectedImage, filePathColumn, null, null, null);
                cursor.moveToFirst();
                int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
                String picturePath = cursor.getString(columnIndex);
                cursor.close();
                BitmapFactory.Options options = new BitmapFactory.Options();
                options.inSampleSize = 2;
                Bitmap temp = BitmapFactory.decodeFile(picturePath, options);
                Bitmap currentBitmap = temp.copy(Bitmap.Config.ARGB_8888, false);   //original bitmap

                if(currentBitmap.getWidth() > 450 && currentBitmap.getHeight() > 550){
                    Bitmap resizeBmp = Bitmap.createScaledBitmap(currentBitmap, 450, 550, false);
                    new MyTask(resizeBmp, MainActivity.this).execute();
                    iv.setImageBitmap(resizeBmp);
                }else{
                    new MyTask(currentBitmap, MainActivity.this).execute();
                    iv.setImageBitmap(currentBitmap);
                }

            }
            break;

        case CAMERA_PIC_REQUEST:    //use camera
            if(resultCode == RESULT_OK){
                Bitmap photo = (Bitmap) data.getExtras().get("data"); 
                if(photo.getWidth() > 600 && photo.getHeight() > 600){
                    Bitmap resizeBmp = Bitmap.createScaledBitmap(photo, 450, 550, false);
                    new MyTask(resizeBmp, MainActivity.this).execute();
                    iv.setImageBitmap(resizeBmp);
                }else{
                    new MyTask(photo, MainActivity.this).execute();
                    iv.setImageBitmap(photo);
                }
            }
            break;
        }
    }

    /*@Override
    public void onWindowFocusChanged(boolean hasFocus){
        ivWidth=iv.getWidth();
        ivHeight=iv.getHeight();
    }*/

/*  private static Bitmap makeBlackTransparent(Bitmap image) {
        // convert image to matrix
        Mat src = new Mat(image.getWidth(), image.getHeight(), CvType.CV_8UC4);
        Utils.bitmapToMat(image, src);

        // init new matrices
        Mat dst = new Mat(image.getWidth(), image.getHeight(), CvType.CV_8UC4);
        Mat tmp = new Mat(image.getWidth(), image.getHeight(), CvType.CV_8UC4);
        Mat alpha = new Mat(image.getWidth(), image.getHeight(), CvType.CV_8UC4);

        // convert image to grayscale
        Imgproc.cvtColor(src, tmp, Imgproc.COLOR_BGR2GRAY);
        // threshold the image to create alpha channel with complete transparency in black background region and zero transparency in foreground object region.
        Imgproc.threshold(tmp, alpha, 100, 255, Imgproc.THRESH_BINARY);

        // split the original image into three single channel.
        List<Mat> rgb = new ArrayList<Mat>(3);
        Core.split(src, rgb);

        // Create the final result by merging three single channel and alpha(BGRA order)
        List<Mat> rgba = new ArrayList<Mat>(4);
        rgba.add(rgb.get(0));
        rgba.add(rgb.get(1));
        rgba.add(rgb.get(2));
        rgba.add(alpha);
        Core.merge(rgba, dst);

        // convert matrix to output bitmap
        Bitmap output = Bitmap.createBitmap(image.getWidth(), image.getHeight(), Bitmap.Config.ARGB_8888);
        Utils.matToBitmap(dst, output);
        dst.release();
        tmp.release();
        alpha.release();
        src.release();
        return output;
    }
*/
    public void debugger(String s){
        Log.v("","########### "+s);
    }

    //loading process
    private class MyTask extends AsyncTask<Void, Bitmap, Bitmap> {

        Context context;
        ProgressDialog ringDialog;
        Bitmap bmp;

        public MyTask(Bitmap bmp, Context con){
            super();
            this.bmp = bmp;
            context = con;
        }

        @Override
        protected void onPreExecute() {
            ringDialog = ProgressDialog.show(context, "Please wait...", "Removing background...");
            ringDialog.setCancelable(true);
        }

        @Override
        protected Bitmap doInBackground(Void... v) {
            // TODO Auto-generated method stub
            //calling the grabcut
            bmp = toGrayscale(bmp);
            bmp = grabCut(bmp);
            bmp = toThreshold(bmp, threshold);
            return bmp;
        }

        @Override
        protected void onPostExecute(Bitmap bmp) {
            //super.onPostExecute(bmp);
            ringDialog.dismiss();
            iv.setImageBitmap(bmp);
            //put here the process you want after the grabCut algorithm
        }

        //GrabCut Algorithm
        public Bitmap grabCut(Bitmap bm){

               Bitmap tempBitmap = bm.copy(Bitmap.Config.ARGB_8888, true);
               Mat img = new Mat(tempBitmap.getHeight(), tempBitmap.getWidth(), CvType.CV_8U);
               Utils.bitmapToMat(bm, img);

               int r = img.rows();
               int c = img.cols();

               Point p1 = new Point(c/12, r/12);
               Point p2 = new Point(c-c/12, r-r/12);

               Rect rect = new Rect(p1, p2);

               Mat mask = new Mat();
               debugger(""+mask.type());
               mask.setTo(new Scalar(125));
               Mat fgdModel = new Mat();
               fgdModel.setTo(new Scalar(255, 255, 255));
               Mat bgdModel = new Mat();
               bgdModel.setTo(new Scalar(255, 255, 255));

               Mat imgC3 = new Mat();  
               Imgproc.cvtColor(img, imgC3, Imgproc.COLOR_RGBA2RGB);
               Log.d("Grabcut", "Grabcut begins");
               Imgproc.grabCut(imgC3, mask, rect, bgdModel, fgdModel, 5, Imgproc.GC_INIT_WITH_RECT);

               Mat source = new Mat(1, 1, CvType.CV_8U, new Scalar(3.0));

               Core.compare(mask, source, mask, Core.CMP_EQ);

               Mat foreground = new Mat(img.size(), CvType.CV_8UC3, new Scalar(255, 255, 255));
               img.copyTo(foreground, mask);

               Log.d("Grab Cut", "Convert to Bitmap");
               Utils.matToBitmap(foreground, tempBitmap);

               img.release();
               imgC3.release();
               mask.release();
               fgdModel.release();
               bgdModel.release();

               return tempBitmap;
            }
    }

    private static ColorMatrix createGreyMatrix(){
        ColorMatrix matrix = new ColorMatrix(new float[] {
                0.2989f, 0.5870f, 0.1140f, 0, 0,
                0.2989f, 0.5870f, 0.1140f, 0, 0,
                0.2989f, 0.5870f, 0.1140f, 0, 0,
                0, 0, 0, 1, 0
        });
        return matrix;
    }

    private static ColorMatrix createThresholdMatrix(int threshold) {
        ColorMatrix matrix = new ColorMatrix(new float[] {
                85.f, 85.f, 85.f, 0.f, -255.f * threshold,
                85.f, 85.f, 85.f, 0.f, -255.f * threshold,
                85.f, 85.f, 85.f, 0.f, -255.f * threshold,
                0f, 0f, 0f, 1f, 0f
        });
        return matrix;
    }

    public Bitmap toGrayscale(Bitmap bmp) {        
        int width, height;
        height = bmp.getHeight();
        width = bmp.getWidth();
        Bitmap bmpGrayscale = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        Canvas c = new Canvas(bmpGrayscale);
        Paint paint = new Paint();
        ColorMatrix cm = new ColorMatrix();
        cm.setSaturation(0);
        ColorMatrixColorFilter f = new ColorMatrixColorFilter(createGreyMatrix());
        paint.setColorFilter(f);

        c.drawBitmap(bmp, 0, 0, paint);
        return bmpGrayscale;
    }

    public Bitmap toThreshold(Bitmap bmp, int threshold) {        
        int width, height;
        height = bmp.getHeight();
        width = bmp.getWidth();
        Bitmap bmpThreshold = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        Canvas c = new Canvas(bmpThreshold);
        Paint paint = new Paint();
        ColorMatrix cm = new ColorMatrix();
        cm.setSaturation(0);
        ColorMatrixColorFilter f = new ColorMatrixColorFilter(createThresholdMatrix(threshold));
        paint.setColorFilter(f);

        c.drawBitmap(bmp, 0, 0, paint);
        return bmpThreshold;
    }    


}
...