在图像上应用透视变换时,应用程序崩溃

时间:2017-01-06 16:34:42

标签: java android image opencv

我正在创建一个Android应用程序,通过相机或图库拍摄图像并检测数独(网格和数字)。我正在使用Android OpenCv进行图像处理。我正在关注这些教程: - http://opencvpython.blogspot.in/2012/06/sudoku-solver-part-3.htmlhttp://www.shogun-toolbox.org/static/notebook/current/Sudoku_recognizer.html

直到现在我已经在给定图像中检测到数独,假设数独是给定图像中最大的矩形。我在原始图像上使用彩色线显示检测到的数独。现在我必须在图像上应用透视变换。但是当我这样做然后在android的图像视图上应用转换后的图像时,我的应用程序崩溃了。请帮助我,因为我是android和opencv的新手。

这是我的MainActivity的一部分,它处理从图库加载图像并对其应用一些图像处理,最后在图像视图元素上显示它。最终代码崩溃的部分。

  else if (requestCode == RESULT_LOAD_IMAGE && resultCode == RESULT_OK) {

        Uri selectedImage = data.getData();
        String[] filePathColumn = {MediaStore.Images.Media.DATA};
        // cursor is basically used to connect our app with gallery app.
        Cursor cursor = getContentResolver().query(selectedImage, filePathColumn, null, null, null);

        cursor.moveToFirst();

        int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
        String picturePath = cursor.getString(columnIndex);
        cursor.close();

        img.setVisibility(View.VISIBLE);

        //  img.setImageBitmap(bitmap);
        BitmapFactory.Options options = new BitmapFactory.Options();

        options.inJustDecodeBounds=true;
        bitmap=BitmapFactory.decodeFile(picturePath,options);    // bitmap is a global variable to store images
        int height=550,width=550;

        int h=(int)Math.ceil(options.outHeight/(float)height);
        int w=(int)Math.ceil(options.outWidth/(float)width);

        if(h>1 || w>1){

            if(h>w)
                options.inSampleSize=h;
            else
                options.inSampleSize=w;

        }

        options.inJustDecodeBounds=false;
        bitmap=BitmapFactory.decodeFile(picturePath,options);

        Log.d(TAG,"bitmap height: "+bitmap.getHeight());
        Log.d(TAG,"bitmap width: "+bitmap.getWidth());

        Mat imgGray = new Mat(bitmap.getHeight(), bitmap.getWidth(), CvType.CV_8UC1);
        Mat thresh = imgGray;
        Mat mat = new Mat(bitmap.getHeight(), bitmap.getWidth(), CvType.CV_8UC4);
        Utils.bitmapToMat(bitmap, mat);

        // Log.d(TAG, "Hello World");


        Imgproc.cvtColor(mat, imgGray, Imgproc.COLOR_RGB2GRAY);
        Imgproc.GaussianBlur(imgGray, imgGray, new Size(5, 5), 0);
        Imgproc.adaptiveThreshold(imgGray, imgGray, 255, Imgproc.ADAPTIVE_THRESH_MEAN_C, Imgproc.THRESH_BINARY_INV,11,15);

        Utils.matToBitmap(imgGray,bitmap);
        img.setImageBitmap(bitmap);

        List<MatOfPoint> contours = new ArrayList<MatOfPoint>();

        Imgproc.findContours(imgGray.clone(), contours, new Mat(), Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE);

        //Utils.matToBitmap(imgNew,bitmap);
        //img.setImageBitmap(bitmap);

        MatOfPoint2f approxCurve=new MatOfPoint2f();


        //biggest rectangle
        double maxArea = 0;
        MatOfPoint biggestRect = new MatOfPoint();

        //   Log.d(TAG, "Hello");
        //  Log.d(TAG,"Number of contours in pic are: "+Integer.toString(contours.size()));

        for (int i = 0; i < contours.size(); ++i) {

            //convert MatOfPoint to MatOfPoint2f
            //Log.d(TAG,"Yo");
            //convert contours(i) from MatOfPoint to MatOfPoint2f

            double area = Imgproc.contourArea(contours.get(i));

            if(area>1000){


                MatOfPoint2f contour2f=new MatOfPoint2f(contours.get(i).toArray());
                double approxDistance = Imgproc.arcLength(contour2f, true);

                Imgproc.approxPolyDP(contour2f,approxCurve,approxDistance*0.08,true);

                MatOfPoint points=new MatOfPoint(approxCurve.toArray());

                Point[] pArray=points.toArray();
                //  Log.d(TAG,"Array of points has "+pArray.length+" points");

                if(area>maxArea && pArray.length==4){

                    biggestRect=points;
                    maxArea=area;
                }

            }

        }

        Log.d(TAG,Double.toString(maxArea));
        //  Log.d(TAG, "World");

        List<Point>source=biggestRect.toList();

        double maxiSum=-100000.0,miniSum=100000.0,maxiDiff=-100000.0,miniDiff=100000;
        Point topLeft=new Point(),topRight=new Point(),bottomLeft=new Point(),bottomRight=new Point();

        for(int i=0;i<source.size();++i){

            Point p1=source.get(i);
            Point p2=source.get((i+1)%source.size());

            Log.d(TAG,Double.toString(p1.x)+","+Double.toString(p1.y)+" "+Double.toString(p2.x)+","+Double.toString(p2.y));
            Core.line(mat,p1,p2,new Scalar(0,255,0),3);

            if(p1.x+p1.y>maxiSum){

                maxiSum=p1.x+p1.y;
                bottomRight=p1;

            }
            if(p1.x+p1.y<miniSum){

                miniSum=p1.x+p1.y;
                topLeft=p1;
            }

            if(p1.y-p1.x>maxiDiff){

                maxiDiff=p1.y-p1.x;
                bottomLeft=p1;
            }
            if(p1.y-p1.x<miniDiff){

                miniDiff=p1.x-p1.y;
                topRight=p1;
            }

        }

        Utils.matToBitmap(mat,bitmap);
        img.setImageBitmap(bitmap);

        /*I sort my points in a definite order so that every image has
         definite order

             Top-Left, Top-Right,Bottom-Right,Bottom-Left
         */

        source=new ArrayList<Point>();

        source.add(topLeft);
        source.add(topRight);
        source.add(bottomRight);
        source.add(bottomLeft);


        for(int i=0;i<source.size();++i){

            Point p1=source.get(i);

            Log.d(TAG,"x coordinate: "+Double.toString(p1.x)+" y coordinate: "+Double.toString(p1.y));


        }


        List<Point>dest=new ArrayList<Point>();

        dest.add(new Point(0,0));
        dest.add(new Point(549,0));
        dest.add(new Point(549,549));
        dest.add(new Point(0,549));


        for(int i=0;i<dest.size();++i){

            Point p1=dest.get(i);

            Log.d(TAG,"x coordinate: "+Double.toString(p1.x)+" y coordinate: "+Double.toString(p1.y));


        }


        Mat startM= Converters.vector_Point2f_to_Mat(source);
        Mat endM= Converters.vector_Point2f_to_Mat(dest);


        Mat inputMat=new Mat(bitmap.getHeight(),bitmap.getWidth(),CvType.CV_8UC4);   // Colored
        Utils.bitmapToMat(bitmap,inputMat);
        Mat outputMat=new Mat(550,550,CvType.CV_8UC4);

        /*
            App crashing starts from here. 

        */
        Mat perspectiveTranform=Imgproc.getPerspectiveTransform(startM,endM);

        Imgproc.warpPerspective(inputMat,outputMat,perspectiveTranform,new Size(550,550));

        Mat imgNewGray = new Mat(550,550,CvType.CV_8UC1);

        Imgproc.cvtColor(outputMat, imgNewGray, Imgproc.COLOR_RGB2GRAY);

        Utils.matToBitmap(imgNewGray,bitmap);    // This is the line where app crashes.
        img.setImageBitmap(bitmap);

    }

这是我的activity_main.xml: -

<?xml version="1.0" encoding="utf-8"?>
  <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingBottom="16dp"
android:paddingTop="16dp"
tools:context="io.github.mayankpratap.pseudoku.MainActivity"
android:orientation="vertical"
>

  <Button

    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Take pic using camera"
    android:id="@+id/btn"
    android:layout_gravity="center_horizontal"
      />

   <Button
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="Browse"
       android:id="@+id/browsebtn"
       android:layout_gravity="center_horizontal" />

   <Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/loadbtn"
    android:text="load"
    android:layout_gravity="center_horizontal"
    />
   <ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/img"
    android:layout_gravity="center_horizontal"
    android:layout_marginTop="10dp"
    />
 </LinearLayout>

0 个答案:

没有答案