JavaCV を使用して SURF 機能で画像を照合する Android アプリを作成しようとしています。
最初に Assets フォルダーから画像を読み込み、SURF 機能を抽出してデータベースに保存しようとしています。cvExtractSURF 関数が実行されるまで、コードは問題なく動作するようです。実際、それがまったく実行されたかどうかはわかりません。エミュレーター/デバッガーが考え始め、数分後、Eclipse は切断されたと言います。実際のデバイスでの同じ問題: ホームに移動するだけで、コードはそれ以上実行されません。エラーは Logcat に記録されません。例外はスローされないようです。何も発生しません。これが発生するコードを次に示します。
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);
}
}
同様の問題を検索しましたが、見つからないようです。
OpenCV 2.3.1 (新しい JavaCV のいくつかの問題のため)、2012 年 3 月 29 日の JavaCV、Eclipse Indigo、Windows 7 32 ビットを使用していることを追加するのを忘れていました。
私はまだAndroid開発の初心者なので、少し助けていただければ幸いです。