我正在创建一个Android应用程序,通过相机或图库拍摄图像并检测数独(网格和数字)。我正在使用Android OpenCv进行图像处理。我正在关注这些教程: - http://opencvpython.blogspot.in/2012/06/sudoku-solver-part-3.html和http://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>