I'm trying to create an Android app which uses JavaCV to match images by their SURF features.
I'm trying to first load an image from the Assets folder, extract SURF features for it and save them in a database. Code seems to work okay until the cvExtractSURF function is executed. Actually, I'm not sure if it executed at all. The emulator/debugger starts thinking and a few minutes later, Eclipse says it was disconnected. Same problem on a real device: just goes to Home and the code is never executed further. No error is logged to Logcat, no exception seems to be thrown, nothing.... Here is the code where this happens.
package com.landmark;
import java.io.IOException;
import java.io.InputStream;
import java.nio.FloatBuffer;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.graphics.*;
import android.widget.Toast;
import android.content.Context;
import android.content.res.AssetManager;
import static com.googlecode.javacv.cpp.opencv_core.CvSeq;
import static com.googlecode.javacv.cpp.opencv_core.IplImage;
import static com.googlecode.javacv.cpp.opencv_core.cvGetSeqElem;
import static com.googlecode.javacv.cpp.opencv_core.*;
import static com.googlecode.javacv.cpp.opencv_features2d.*;
import static com.googlecode.javacv.cpp.opencv_highgui.*;
import static com.googlecode.javacv.cpp.opencv_imgproc.*;
public class DatabaseHelper extends SQLiteOpenHelper {
static final String dbName = "ImageDatabase.db";
static final String imageTableName = "ImageData";
static final String colImageID = "ImageID";
static final String colInfo = "ObjectInformation";
static final String surfTableName = "SURFData";
static final String colSURFId = "SURFID";
static final String colDir = "Dir";
static final String colHessian = "Hessian";
static final String colLaplacian = "Laplacian";
static final String colCoordX = "CoordX";
static final String colCoordY = "CoordY";
static final String colSize = "Size";
static final String colRefDescriptorID = "DescriptorID";
static final String colRefImageID = "ImageRefID";
static final String descriptorTableName = "DescriptorData";
static final String colDescriptorID = "DescriptorRefID";
static final String colDescriptorValue = "DescriptorValue";
private Context currentContext = null;
public DatabaseHelper (Context context){
super(context, dbName, null, 1);
this.currentContext = context;
}
@Override
public void onCreate (SQLiteDatabase database){
database.execSQL("CREATE TABLE " + imageTableName +
" ( " + colImageID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
+ colInfo + " TEXT );");
database.execSQL("CREATE TABLE " + surfTableName +
" ( " + colSURFId + " INTEGER PRIMARY KEY AUTOINCREMENT, "
+ colDir + " REAL, "
+ colHessian + " REAL, "
+ colLaplacian + " INTEGER, "
+ colCoordX + " REAL, "
+ colCoordY + " REAL, "
+ colSize + " INTEGER, "
+ colRefDescriptorID + " INTEGER, "
+ colRefImageID + " INTEGER, "
+ " FOREIGN KEY (" + colRefImageID + ") REFERENCES " + imageTableName + " (" + colImageID + "));");
database.execSQL("CREATE TABLE " + descriptorTableName +
" ( " + colDescriptorID + " INTEGER, "
+ colDescriptorValue + " REAL, "
+ "FOREIGN KEY (" + colDescriptorID + ") REFERENCES " + surfTableName + " (" + colDescriptorID + "));");
//image 01
AssetManager assets = currentContext.getAssets();
String imageFilename = "HramAlexanderNevski03.jpg";
InputStream imageStream = null;
try {
imageStream = assets.open(imageFilename);
} catch (IOException e) {
e.printStackTrace();
}
Bitmap bitmapImage = BitmapFactory.decodeStream(imageStream);
int width = bitmapImage.getWidth();
int height = bitmapImage.getHeight();
IplImage image = IplImage.create(width, height, IPL_DEPTH_8U, 4);
IplImage greyImage = IplImage.create(width, height, IPL_DEPTH_8U, 1);
bitmapImage.copyPixelsToBuffer(image.getByteBuffer());
cvCvtColor(image, greyImage, CV_BGR2GRAY);
CvMemStorage storage = CvMemStorage.create();
CvSeq imageKeypoints = new CvSeq();
CvSeq imageDescriptors = new CvSeq();
CvSURFParams params = cvSURFParams(500, 1);
cvExtractSURF(greyImage, null, imageKeypoints, imageDescriptors, storage, params, 0);
//storage.release();
database.execSQL("INSERT INTO "+ imageTableName + " VALUES (" + null + ", "
+ "'This is the Alexander Nevski memorial'" + ");");
for(int i=0; i<imageKeypoints.total(); i++){
CvSURFPoint point = new CvSURFPoint(cvGetSeqElem(imageKeypoints, i));
database.execSQL("INSERT INTO " + surfTableName + " VALUES (" + null + ", " + point.dir() + ", "
+ point.hessian() + ", " + point.laplacian() + ", "
+ point.pt().x() + ", " + point.pt().y() + ", "
+ point.size() + ", " + null + ", " + 0 + ");");
for (int j=0; j<imageDescriptors.total(); j++){
int size = imageDescriptors.elem_size();
FloatBuffer descriptors = cvGetSeqElem(imageDescriptors, j).capacity(size).asByteBuffer().asFloatBuffer();
for (int k=0; k<descriptors.capacity(); k++){
database.execSQL("INSERT INTO " + descriptorTableName + " VALUES ( (SELECT LAST_INSERT_ROWID() - "
+ j + "), " + descriptors.get(k) + ");");
}
}
}
}
@Override
public void onUpgrade(SQLiteDatabase database, int oldVersion, int newVersion){
}
public void onOpen(SQLiteDatabase database){
super.onOpen(database);
}
}
I searched for similar problems but I can't seem to find any.
Forgot to add that I'm using OpenCV 2.3.1 (due to some issues with newer JavaCV), JavaCV from 29.03.2012, Eclipse Indigo, Windows 7 32-bit.
I'm still a newbie with Android development so a little help would be appreciated.