android - 无法将匹配图像的结果用于下一个活动
问题描述
相机活动:
public class CameraActivity extends AppCompatActivity implements View.OnClickListener {
private static String TAG = "OpenCVLibrary";
static {
System.loadLibrary("opencv_java3");
if (!OpenCVLoader.initDebug()) {
Log.d(TAG, "OpenCv Not Successfully Loaded");
} else {
Log.d(TAG, "OpenCv Successfully Loaded");
}
}
private static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 100;
DBController db;
ImageProcessing imgproc;
Button btnProcess;
Cursor res;
ProgressDialog progressDialog;
ImageView imgTaken;
private Bitmap bmp;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera);
//getSupportActionBar().setTitle("Camera");
if (!OpenCVLoader.initDebug()) {
}
//Initialize View
imgTaken = (ImageView) findViewById(R.id.imgTaken);
btnProcess = (Button) findViewById(R.id.btnProcess);
btnProcess.setEnabled(false);
Button btnBack = (Button) findViewById(R.id.btnBack);
//Create a Bitmap of the Image captured using camera
//imgTaken.setImageBitmap(getTakenImage());
//Set OnClick Listener
btnBack.setOnClickListener(this);
btnProcess.setOnClickListener(this);
}
public Bitmap getTakenImage(){
//String path = getApplicationContext().getExternalFilesDir(null).toString()+"/pic.jpg";
bmp = ((BitmapDrawable) imgTaken.getDrawable()).getBitmap();
return bmp;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
finish();
return true;
}
@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.btnProcess:
Cursor res;
db = new DBController(this);
process();
break;
//pagpicture
case R.id.btnBack:
Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
//finish();
break;
default:
break;
}
}
//result nung camera
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
Bitmap bp = (Bitmap) data.getExtras().get("data");
new Utility(CameraActivity.this).SaveTemp(bp,""+1);
btnProcess.setEnabled(true);
imgTaken.setImageBitmap(bp);
} else if (resultCode == RESULT_CANCELED) {
// User cancelled the image capture
} else {
// Image capture failed, advise user
}
}
}
public void process(){
final String TAG = "Image Processing";
progressDialog = new ProgressDialog(CameraActivity.this);
final ArrayList<ProcessResult> processResults = new ArrayList<>();
db = new DBController(this);
imgproc = new ImageProcessing();
AsyncTask<String,String,String> task = new AsyncTask<String, String, String> () {
@Override
protected void onPreExecute() {
super.onPreExecute();
//Processing Dialog
progressDialog.setMessage("Processing Image \nPlease wait!...");
progressDialog.setCancelable(false);
progressDialog.show();
}
@Nullable
@Override
protected String doInBackground(String... strings) {
/*Compute for the Match Percentage of the Image
compareFeature Method
First Params = Plant Image
Second Params = Image Taken
Retrieve all Plant Image in the Database
*/
try {
res = db.getAllData("tableplantdetails");
Log.d(TAG, "" + res.getCount());
if (res.moveToFirst()) {
//String file = Environment.getExternalStorageDirectory().toString() + "/Android/data/com.thesis.app.parafish/files/" + res.getString(2);
//Bitmap tmpbmp = BitmapFactory.decodeFile(file);
int rate = 0;
Log.d(TAG,rate+"");
do {
Log.e(TAG, res.getString(0) + "/" + res.getString(1) + "/" + res.getString(2)+ "/" + res.getString(3)+ "/" + res.getString(4));
String imgpath = res.getString(3);
String[] newimgpath = imgpath.split("/");
String file = Environment.getExternalStorageDirectory().toString() + "/Android/data/com.example.geraldine.myisucculent/files/" + newimgpath[1];
Bitmap tmpbmp = BitmapFactory.decodeFile(file);
ProcessResult result = new ProcessResult();
if(tmpbmp!=null &&getTakenImage()!=null){
rate = compareFeature(tmpbmp, getTakenImage());
}
Log.d(TAG, rate + "");
result.setplantID(res.getString(0));
result.setResult(rate);
processResults.add(result);
} while (res.moveToNext());
}
}catch (Exception e){
e.printStackTrace();
}
Log.d(TAG,"here");
Collections.sort(processResults, new ArraySort());
/*Rearrange the Top 3 Best Match. Result with the same Parasite ID with the highest Match
remain while the other one will be remove from the list
By doing this ArrayList with Index from 0-2 is now the Top 3 Match with different parasite id
*/
for(int i = 0; i < processResults.size(); i++){
Log.d("Top3",processResults.get(i).getResult().toString());
}
int index = 0;
for(int i = 0; i < processResults.size()-1; i++){
ProcessResult result1 = processResults.get(i);
for(int y=i+1;y < (processResults.size()-1)-i;y++){
ProcessResult result2 = processResults.get(y);
Log.d("Top3",result1.getplantID()+" Compared to "+result2.getplantID());
if(result1.getplantID().equals(result2.getplantID())){
processResults.remove(i+1);
}
}
}
for(int i = 0; i < processResults.size(); i++){
Log.d("Top3","ID="+processResults.get(i).getplantID()+" Rate:"+processResults.get(i).getResult().toString());
}
return null;
}
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
progressDialog.dismiss();
//tempo
Intent intent = new Intent(CameraActivity.this, Match.class);
//startActivity(intentcam);
//Nagfoforce close dahil dito...
intent.putExtra("top1",processResults.get(0).getplantID());
intent.putExtra("percentage1",processResults.get(0).getResult()+"");
Log.d("Top1","ID="+processResults.get(0).getplantID()+" Rate:"+processResults.get(0).getResult().toString());
intent.putExtra("top2",processResults.get(1).getplantID());
intent.putExtra("percentage2",processResults.get(1).getResult()+"");
Log.d("Top2","ID="+processResults.get(1).getplantID()+" Rate:"+processResults.get(1).getResult().toString());
intent.putExtra("top3",processResults.get(2).getplantID());
intent.putExtra("percentage3",processResults.get(2).getResult()+"");
Log.d("Top3","ID="+processResults.get(2).getplantID()+" Rate:"+processResults.get(2).getResult().toString());
intent.putExtra("from","CameraActivity");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
getApplicationContext().startActivity(intent);
}
};
task.execute("");
}
public int compareFeature(Bitmap bmp1, Bitmap bmp2) {
final String TAG = "FEATURE_MATCH";
int percentage = 0;
Log.d(TAG,"Start Comparing");
// Load images to compare
bmp1 = bmp1.copy(Bitmap.Config.ARGB_8888, true);
bmp2 = bmp2.copy(Bitmap.Config.ARGB_8888, true);
Mat img1 = new Mat();
Mat img2 = new Mat();
Utils.bitmapToMat(bmp1, img1);
Utils.bitmapToMat(bmp2, img2);
Imgproc.cvtColor(img1, img1, Imgproc.COLOR_RGBA2GRAY);
Imgproc.cvtColor(img2, img2, Imgproc.COLOR_RGBA2GRAY);
Log.d(TAG,"Bitmap Converted to GrayScale");
// Declare key point of images
MatOfKeyPoint keypoints1 = new MatOfKeyPoint();
MatOfKeyPoint keypoints2 = new MatOfKeyPoint();
Mat descriptors1 = new Mat();
Mat descriptors2 = new Mat();
Log.d(TAG,"Keypoints and Descriptor Initialize");
// Definition of ORB key point detector and descriptor extractors
FeatureDetector detector = FeatureDetector.create(FeatureDetector.SIFT);
DescriptorExtractor extractor = DescriptorExtractor.create(DescriptorExtractor.SIFT);
// Detect key points
detector.detect(img1, keypoints1);
detector.detect(img2, keypoints2);
Log.d(TAG,"KeyPoints Detected");
// Extract descriptors
extractor.compute(img1, keypoints1, descriptors1);
extractor.compute(img2, keypoints2, descriptors2);
Log.d("OpenCVLibrary","Extract Descriptors");
// Definition of descriptor matcher
DescriptorMatcher matcher = DescriptorMatcher.create(DescriptorMatcher.FLANNBASED);
// Match points of two images
//MatOfDMatch matches = new MatOfDMatch();
List<MatOfDMatch> matches = new LinkedList<MatOfDMatch>();
// Avoid to assertion failed
// Assertion failed (type == src2.type() && src1.cols == src2.cols && (type == CV_32F || type == CV_8U)
if (descriptors1.type() == descriptors2.type() &&
descriptors1.cols() == descriptors2.cols()) {
//matcher.match(descriptors1, descriptors2, matches);
matcher.knnMatch(descriptors1, descriptors2, matches,2);
//List<DMatch> matchesList = matches.toList();
LinkedList<DMatch> good_matches = new LinkedList<DMatch>();
float nndrRatio = 0.8f;
Log.d("OpenCVLibrary","Total No of Match:"+matches.size()+"");
for (int i = 0; i < matches.size(); i++) {
MatOfDMatch matofDMatch = matches.get(i);
DMatch[] dmatcharray = matofDMatch.toArray();
DMatch m1 = dmatcharray[0];
DMatch m2 = dmatcharray[1];
if (m1.distance <= m2.distance * nndrRatio) {
good_matches.addLast(m1);
}
}
MatOfDMatch goodEnough = new MatOfDMatch();
goodEnough.fromList(good_matches);
Log.d("OpenCVLibrary","Total No of GM:"+good_matches.size()+"");
double matchCount = matches.size();
double goodMatch = good_matches.size();
Log.d("OpenCVLibrary","Computation: ("+goodMatch+"/"+matchCount+")");
double tmp =(goodMatch/matchCount);
Log.d("OpenCVLibrary","Computation: "+tmp+"*100");
double tmp2 = tmp*100;
percentage = (int) tmp2;
Log.d("OpenCVLibrary","Total Percentage:"+percentage+"");
}
return percentage;
}
}
比赛活动
public class Match extends AppCompatActivity implements View.OnClickListener{
ImageView img1,img2,img3;
TextView tv1,tv2,tv3,tnote;
CardView cv1,cv2,cv3;
Cursor res;
DBController db = new DBController(this);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_match);
//getSupportActionBar().setTitle("Best Match");
String path = getApplicationContext().getExternalFilesDir(null).toString();
img1 = (ImageView) findViewById(R.id.imgtop1);
img2 = (ImageView) findViewById(R.id.imgtop2);
img3 = (ImageView) findViewById(R.id.imgtop3);
tv1 = (TextView) findViewById(R.id.percent1);
tv2 = (TextView) findViewById(R.id.percent2);
tv3 = (TextView) findViewById(R.id.percent3);
tnote = (TextView) findViewById(R.id.txtNote);
cv1 = (CardView) findViewById(R.id.top1);
cv2 = (CardView) findViewById(R.id.top2);
cv3 = (CardView) findViewById(R.id.top3);
cv1.setOnClickListener(this);
cv2.setOnClickListener(this);
cv3.setOnClickListener(this);
Intent intent = getIntent();
if(intent.getStringExtra("top1")==""){
cv1.setVisibility(View.GONE);
cv2.setVisibility(View.GONE);
cv3.setVisibility(View.GONE);
tnote.setText("No Succulent Match");
}
else if(null != intent){
Log.e("Top3",intent.getStringExtra("percentage1"));
Log.e("Top3",intent.getStringExtra("percentage2"));
Log.e("Top3",intent.getStringExtra("percentage3"));
Log.e("Top3",intent.getStringExtra("top1"));
Log.e("Top3",intent.getStringExtra("top2"));
Log.e("Top3",intent.getStringExtra("top3"));
String p1 = intent.getStringExtra("percentage1");
String p2 = intent.getStringExtra("percentage2");
String p3 = intent.getStringExtra("percentage3");
tv1.setText(tv1.getText().toString()+p1+"%");
tv2.setText(tv2.getText().toString()+p2+"%");
tv3.setText(tv3.getText().toString()+p3+"%");
res = db.getSpecificData("tableplantdetails","plantID="+intent.getStringExtra("top1"));
res.moveToFirst();
String imgpath = res.getString(3);
String[] newimgpath = imgpath.split("/");
Bitmap img = BitmapFactory.decodeFile(path+"/"+newimgpath[1]);
if(img!=null){
img1.setImageBitmap(img);
}
res = db.getSpecificData("tableplantdetails","plantID="+intent.getStringExtra("top2"));
res.moveToFirst();
String imgpath2 = res.getString(3);
String[] newimgpath2 = imgpath2.split("/");
img = BitmapFactory.decodeFile(path+"/"+newimgpath2[1]);
if(img!=null){
img2.setImageBitmap(img);
}
res = db.getSpecificData("tableplantdetails","plantID="+intent.getStringExtra("top3"));
res.moveToFirst();
String imgpath3 = res.getString(3);
String[] newimgpath3 = imgpath3.split("/");
img = BitmapFactory.decodeFile(path+"/"+newimgpath3[1]);
if(img!=null){
img3.setImageBitmap(img);
}
if(p1.equals("0")){
cv1.setVisibility(View.GONE);
}if(p2.equals("0")){
cv2.setVisibility(View.GONE);
}if(p3.equals("0")){
cv3.setVisibility(View.GONE);
}
}
}
@Override
public void onClick(View view) {
Intent intent = getIntent();
Intent nIntent;
switch(view.getId()){
case R.id.top1:
nIntent = new Intent(getApplicationContext(),view_succulent_info.class);
nIntent.putExtra("plantID",intent.getStringExtra("top1"));
startActivity(nIntent);
break;
case R.id.top2:
nIntent = new Intent(getApplicationContext(),view_succulent_info.class);
nIntent.putExtra("plantID",intent.getStringExtra("top2"));
startActivity(nIntent);
break;
case R.id.top3:
nIntent = new Intent(getApplicationContext(),view_succulent_info.class);
nIntent.putExtra("plantID",intent.getStringExtra("top3"));
startActivity(nIntent);
break;
default:
break;
}
}
@Override
protected void onPause() {
super.onPause();
finish();
}
}
DBController(数据库)
public class DBController extends SQLiteOpenHelper {
//Database Name
private static final String DATABASE_NAME = "isucculents.db";
//Tables Name
private static final String TABLE_PLANTS = "tableplantdetails";
private static final String TABLE_DISEASE = "tableplantdisease";
private static final String TABLE_HISTORY = "tablehistory";
//plant details column names
public static final String KEY_PLANTID = "plantID";
public static final String KEY_PLANTNAME = "plantname";
public static final String KEY_PDESCRIPTION = "plantdescription";
public static final String KEY_PIMAGEPATH = "plantimagepath";
public static final String KEY_PIMAGETYPE = "plantimagetype";
public static final String KEY_PSTATUS = "status";
public static final String[] ALL_PKEYS = new String[] {KEY_PLANTID, KEY_PLANTNAME, KEY_PDESCRIPTION, KEY_PIMAGEPATH, KEY_PIMAGETYPE, KEY_PSTATUS};
//Plant Disease Column Names
public static final String KEY_DISEASEID = "plantdiseaseID";
public static final String KEY_DISEASENAME = "plantdiseasename";
public static final String KEY_DDESCRIPTION = "plantdiseasedescription";
public static final String KEY_DIMAGEPATH = "plantdiseaseimagepath";
public static final String KEY_DSTATUS = "status";
public static final String KEY_DPLANTID = "plantID";
public static final String[] ALL_DKEYS = new String[] {KEY_DISEASEID, KEY_DISEASENAME, KEY_DDESCRIPTION, KEY_DIMAGEPATH, KEY_DSTATUS, KEY_DPLANTID};
//History Column Names 2
public static final String KEY_HISID = "historyID";
public static final String KEY_HISCUREID = "recommendedcureID";
public static final String KEY_HISPLANTNAME = "plantname";
public static final String KEY_HISCAPTUREDIMAGE = "capturedimagefilepath";
public static final String KEY_HISDATEDETECTED = "datedetected";
public static final String KEY_HISSTATUS = "status";
public static final String [] ALL_HISKEYS = new String[] {KEY_HISID,KEY_HISCUREID,KEY_HISPLANTNAME,KEY_HISCAPTUREDIMAGE,KEY_HISDATEDETECTED,KEY_HISSTATUS};
private Context mContext;
private static String TAG = "DBController";
public DBController (Context context) {
super(context, "/mnt/sdcard/"+DATABASE_NAME, null, 1);
this.mContext = context;
}
@Override
public void onCreate(SQLiteDatabase db) {
String CREATE_PLANTS = "CREATE TABLE IF NOT EXISTS tableplantdetails(" +
"plantID INTEGER PRIMARY KEY ," +
"plantname TEXT," +
"plantdescription TEXT," +
"plantimagepath TEXT," +
"plantimagetype TEXT," +
"status TEXT)";
String CREATE_DISEASE = "CREATE TABLE IF NOT EXISTS tableplantdisease(" +
"plantdiseaseID INTEGER PRIMARY KEY ," +
"plantdiseasename TEXT," +
"plantdiseasedescription TEXT," +
"plantdiseaseimagepath TEXT," +
"status TEXT," +
"plantID INTEGER)";
String CREATE_HISTORY = "CREATE TABLE IF NOT EXISTS tablehistory(" +
"historyID INTEGER PRIMARY KEY," +
"recordID INTEGER," +
"detecteddiseaseID INTEGER," +
"recommendedcureID INTEGER," +
"plantname TEXT," +
"capturedimagefilepath TEXT," +
"datedetected TEXT," +
"status TEXT)";
db.execSQL(CREATE_PLANTS);
db.execSQL(CREATE_DISEASE);
db.execSQL(CREATE_HISTORY);
}
@Override
public void onUpgrade(SQLiteDatabase db, int il, int i1) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_PLANTS);
db.execSQL("DROP TABLE IF EXISTS " + TABLE_DISEASE);
db.execSQL("DROP TABLE IF EXISTS " + TABLE_HISTORY);
// Create tables again
onCreate(db);
}
public Cursor getAllData(String tbl_Name){
SQLiteDatabase db = this.getWritableDatabase();
Cursor res = db.rawQuery(String.format("SELECT * FROM %s",tbl_Name),null);
return res;
}
public Cursor getSpecificData(String tbl_Name, String WhereClause){
SQLiteDatabase db = this.getWritableDatabase();
String sql= String.format("SELECT * FROM %s WHERE %s",tbl_Name,WhereClause );
Log.d("SQL Query",sql);
Cursor res = db.rawQuery(sql,null);
return res;
}
public boolean saveforMonitoring(HashMap<String,String> queryValues){
SQLiteDatabase db =this.getWritableDatabase();
ContentValues values = new ContentValues();
Utility util = new Utility(mContext);
long result = -1;
final downloadImage downImage = new downloadImage();
Log.d(TAG,"Saving Data for Monitoring");
values.put("historyID", queryValues.get("id"));
values.put("recordID", queryValues.get("recordid"));
values.put("detecteddiseaseID", queryValues.get("dis_id"));
values.put("recommendedcureID", queryValues.get("cure_id"));
values.put("plantname", queryValues.get("plantname"));
values.put("capturedimagepathfile", "IMG_"+queryValues.get("image")+".jpg");
values.put("datedetected", queryValues.get("date"));
String root = mContext.getExternalFilesDir(null).toString()+"/temp/IMG_temp.jpg";
Bitmap bmp = BitmapFactory.decodeFile(root);
util.SaveImage(bmp,queryValues.get("image"));
result = db.insert("tablehistory", null, values);
db.close();
if(result == -1){
return false;
}else{
return true;
}
}
LOGCAT
E/AndroidRuntime:致命异常:主进程:com.example.geraldine.myisucculent,PID:6262 java.lang.IndexOutOfBoundsException:索引:0,大小:0 在 java.util.ArrayList.get(ArrayList.java:437) 在com.example.geraldine.myisucculent.CameraActivity$1.onPostExecute(CameraActivity.java:236) 在 com.example.geraldine.myisucculent.CameraActivity$1.onPostExecute(CameraActivity.java:144) 在 android.os.AsyncTask.finish(AsyncTask. java:695) 在 android.os.AsyncTask.-wrap1(Unknown Source:0) 在 android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:712) 在 android.os.Handler.dispatchMessage(Handler.java:105 ) 在 android.os.Looper.loop(Looper.java:164) 在 android.app.ActivityThread.main(ActivityThread.java:6541) 在 java.lang.reflect.Method。在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767) 的 com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240) 调用(本机方法) 应用程序终止。
解决方案
推荐阅读
- python-3.x - 线程:在深度复制时暂停对象的定期更新,Python
- python - 如何打印 xpath 匹配节点的代码?
- python - 使用带有 @interact 的按钮
- oauth-2.0 - OAuth2 - 如何将 clientId/客户端密码列表添加为 JSON 文件,而不是单个客户端 ID/客户端密码?
- android - 依赖关系解析为不兼容的版本
- postgresql - 带有 json 数据的 GORM 数据库列
- c# - 显示 PDF 文档 C#
- python - 将我的数据划分为网格并在每个框中选择一个点
- reactjs - 如何用 React JS 实现 Adonis JS 版本 4.1 的 WebSocket
- python - 部署到 Elastic-Beanstalk 时出现瞭望塔区域错误的 Django