Refactors the code a bit to remove unused code.

Adds the keystore.
parent 5ec8178a
......@@ -92,6 +92,7 @@
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" exported="" name="support-v4-22.0.0" level="project" />
<orderEntry type="library" exported="" name="support-annotations-22.0.0" level="project" />
<orderEntry type="library" exported="" name="bolts-android-1.2.1" level="project" />
<orderEntry type="library" exported="" name="appcompat-v7-22.0.0" level="project" />
<orderEntry type="module" module-name="openCVLibrary2411" exported="" />
</component>
......
......@@ -23,4 +23,5 @@ dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:22.0.0'
compile project(':openCVLibrary2411')
compile 'com.parse.bolts:bolts-android:1.2.1'
}
......@@ -21,7 +21,7 @@
</intent-filter>
</activity> -->
<activity
android:name=".CameraActivity"
android:name=".MainActivity"
android:label="@string/app_name"
android:screenOrientation="portrait">
<intent-filter>
......
package com.aluxoft.earrecognition;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Resources;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.provider.BaseColumns;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.support.v7.app.ActionBarActivity;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import org.opencv.android.Utils;
import org.opencv.calib3d.Calib3d;
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.MatOfByte;
import org.opencv.core.MatOfDMatch;
import org.opencv.core.MatOfKeyPoint;
import org.opencv.core.MatOfPoint2f;
import org.opencv.core.Point;
import org.opencv.core.Scalar;
import org.opencv.core.Size;
import org.opencv.core.TermCriteria;
import org.opencv.features2d.DMatch;
import org.opencv.features2d.DescriptorExtractor;
import org.opencv.features2d.DescriptorMatcher;
import org.opencv.features2d.FeatureDetector;
import org.opencv.features2d.Features2d;
import org.opencv.features2d.KeyPoint;
import org.opencv.highgui.Highgui;
import org.opencv.imgproc.Imgproc;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Vector;
public class CameraActivity extends ActionBarActivity {
String image1 = "/storage/emulated/0/DCIM/Camera/000_down_ear.jpg";
String image2 = "/storage/emulated/0/DCIM/Camera/001_front_ear.jpg";
String image3 = "/storage/emulated/0/DCIM/Camera/000_front_ear.jpg";
String image4 = "/storage/emulated/0/DCIM/Camera/test_1.png";
String image5 = "/storage/emulated/0/DCIM/Camera/test_3.png";
String image6 = "/storage/emulated/0/DCIM/Camera/test_2.png";
String image_patty_01 = "/storage/emulated/0/DCIM/Camera/PATTY_01.jpg";
String image_patty_02 = "/storage/emulated/0/DCIM/Camera/PATTY_02.jpg";
String image_elena_01 = "/storage/emulated/0/DCIM/Camera/ELENA_01.jpg";
String image_elena_02 = "/storage/emulated/0/DCIM/Camera/ELENA_02.jpg";
private static final int REQUEST_IMAGE_CAPTURE = 1;
private static final int SELECT_PICTURE = 0;
private String mCurrentPhotoPath;
private String mCurrentPhotoPath1 = null;//image_patty_02;
private String mCurrentPhotoPath2 = null;//image_elena_01;
private String mCurrentPhotoPath3 = null;//image_elena_02;
private int previewWidth = 150;
private int previewHeight = 150;
private ImageView previewImage1;
private ImageView previewImage2;
private ImageView previewImage3;
private ImageView previewImage;
public void resizeMat(Mat image) {
final double kMaxWidth = 160;
final double kMaxHeight = 120;
if (image.width() <= kMaxWidth && image.height() <= kMaxHeight) {
return;
}
double ratio = (double)image.width() / (double)image.height();
double width, height;
if (ratio > 1) {
width = kMaxWidth;
height = kMaxWidth * ((double)image.height()/(double)image.width());
} else {
height = kMaxHeight;
width = kMaxHeight* ratio;
}
Imgproc.resize(image, image, new Size(width, height));
}
public double distanceFromData(DescriptorMatcher matcher, MatOfKeyPoint keypoints1, Mat descriptors1, MatOfKeyPoint keypoints2, Mat descriptors2) {
MatOfDMatch matches = new MatOfDMatch();
matcher.match(descriptors1, descriptors2, matches);
DMatch[] aMatches = matches.toArray();
double distance = 0;
for (int i=0;i<aMatches.length;++i) {
distance += aMatches[i].distance;
}
return distance;
}
public void doOpenCvMagic() {
Mat img1 = Highgui.imread(mCurrentPhotoPath1, Highgui.CV_LOAD_IMAGE_GRAYSCALE);
resizeMat(img1);
Mat img2 = Highgui.imread(mCurrentPhotoPath2, Highgui.CV_LOAD_IMAGE_GRAYSCALE);
resizeMat(img2);
Mat img3 = Highgui.imread(mCurrentPhotoPath3, Highgui.CV_LOAD_IMAGE_GRAYSCALE);
resizeMat(img3);
FeatureDetector detector = FeatureDetector.create(FeatureDetector.SIFT);
MatOfKeyPoint keypoints1 = new MatOfKeyPoint();
MatOfKeyPoint keypoints2 = new MatOfKeyPoint();
MatOfKeyPoint keypoints3 = new MatOfKeyPoint();
detector.detect(img1, keypoints1);
detector.detect(img2, keypoints2);
detector.detect(img3, keypoints3);
Mat descriptors1 = new Mat();
Mat descriptors2 = new Mat();
Mat descriptors3 = new Mat();
DescriptorExtractor extractor = DescriptorExtractor.create(DescriptorExtractor.SIFT);
extractor.compute(img1, keypoints1, descriptors1);
extractor.compute(img2, keypoints2, descriptors2);
extractor.compute(img3, keypoints3, descriptors3);
DescriptorMatcher matcher = DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE);
Mat outImg1 = new Mat();
Mat outImg2 = new Mat();
Mat outImg3 = new Mat();
double distance13 = distanceFromData(matcher, keypoints3, descriptors3, keypoints1, descriptors1);
double distance23 = distanceFromData(matcher, keypoints3, descriptors3, keypoints2, descriptors2);
String message = "";
if (distance13 < distance23) {
message = "It's more likely to be the subject 1";
} else if (distance23 < distance13) {
message = "It's more likely to be the subject 2";
} else {
message = "Both subjects are equally likely";
}
new AlertDialog.Builder(this)
.setTitle("Identification")
.setMessage(message)
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
}
})
.setIcon(android.R.drawable.ic_dialog_info)
.show();
Features2d.drawKeypoints(img1, keypoints1, outImg1);
Features2d.drawKeypoints(img2, keypoints2, outImg2);
Features2d.drawKeypoints(img3, keypoints3, outImg3);
Bitmap bitmap = Bitmap.createBitmap(outImg1.cols(), outImg1.rows(), Bitmap.Config.ARGB_8888);
Utils.matToBitmap(outImg1, bitmap);
previewImage1.setImageBitmap(bitmap);
bitmap = Bitmap.createBitmap(outImg2.cols(), outImg2.rows(), Bitmap.Config.ARGB_8888);
Utils.matToBitmap(outImg2, bitmap);
previewImage2.setImageBitmap(bitmap);
bitmap = Bitmap.createBitmap(outImg3.cols(), outImg3.rows(), Bitmap.Config.ARGB_8888);
Utils.matToBitmap(outImg3, bitmap);
previewImage3.setImageBitmap(bitmap);
/*
for (int i=0;i<aMatches.length;++i) {
double dist = aMatches[i].distance;
if (dist < min_dist) {
min_dist = dist;
}
if (dist > max_dist) {
max_dist = dist;
}
}
Vector<DMatch> vgood_matches = new Vector<DMatch>();
for (int i=0;i<aMatches.length;++i) {
if (aMatches[i].distance < 3*min_dist) {
vgood_matches.add(aMatches[i]);
}
}
MatOfDMatch good_matches = new MatOfDMatch();
good_matches.fromList(vgood_matches);
Mat image_matches = new Mat();
Features2d.drawMatches(img1, keypoints1, img2, keypoints2, good_matches, image_matches, Scalar.all(-1), Scalar.all(-1), new MatOfByte(), Features2d.NOT_DRAW_SINGLE_POINTS);
Bitmap bitmap = Bitmap.createBitmap(image_matches.cols(), image_matches.rows(), Bitmap.Config.ARGB_8888);
Utils.matToBitmap(image_matches, bitmap);
previewImage1.setImageBitmap(bitmap);*/
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
System.loadLibrary("opencv_java");
System.loadLibrary("nonfree");
setContentView(R.layout.activity_camera);
previewImage1 = (ImageView)findViewById(R.id.imageView);
previewImage2 = (ImageView)findViewById(R.id.imageView2);
previewImage3 = (ImageView)findViewById(R.id.imageView3);
final Button takeButton = (Button)findViewById(R.id.button);
takeButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
previewImage = previewImage1;
takePhoto(takeButton);
mCurrentPhotoPath1 = mCurrentPhotoPath;
}
});
final Button pickButton = (Button)findViewById(R.id.button2);
pickButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
previewImage = previewImage2;
takePhoto(takeButton);
mCurrentPhotoPath2 = mCurrentPhotoPath;
}
});
final Button toIdentifyButton = (Button) findViewById(R.id.toidentify);
toIdentifyButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
previewImage = previewImage3;
takePhoto(takeButton);
mCurrentPhotoPath3 = mCurrentPhotoPath;
}
});
final Button processButton = (Button) findViewById(R.id.button3);
processButton.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
// do opencv magic here...
if (mCurrentPhotoPath1 != null && mCurrentPhotoPath2 != null && mCurrentPhotoPath3 != null) {
doOpenCvMagic();
}
}
});
}
public void pickPhoto(View view) {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Picture"), SELECT_PICTURE);
}
public void takePhoto(View view) {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO) {
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException ex) {
// Error occurred while creating the File
}
// Continue only if the File was successfully created
if (photoFile != null) {
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
}
}
}
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
// Save a file: path for use with ACTION_VIEW intents
mCurrentPhotoPath = image.getAbsolutePath();
return image;
}
@SuppressLint("NewApi")
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_IMAGE_CAPTURE) {
if (resultCode == RESULT_OK) {
if (mCurrentPhotoPath != null) {
/*
* añadimos la imagen a la galeria
*/
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
File f = new File(mCurrentPhotoPath);
Uri contentUri = Uri.fromFile(f);
mediaScanIntent.setData(contentUri);
this.sendBroadcast(mediaScanIntent);
String path = f.getAbsolutePath();
Log.e("", path);
Bitmap galleryImage = getBitMapForPreview(path,previewWidth,previewHeight);
previewImage.setImageBitmap(galleryImage);
}
}
}
if (requestCode == SELECT_PICTURE) {
if (resultCode == RESULT_OK) {
int currentapiVersion = android.os.Build.VERSION.SDK_INT;
if (currentapiVersion >= android.os.Build.VERSION_CODES.KITKAT) {
Uri uri = data.getData();
String IMAGE_FILEPATH = "";
try {
if (uri == null) {
IMAGE_FILEPATH = uri.getPath();
} else {
// get the id of the image selected by the user
String wholeID = DocumentsContract.getDocumentId(data.getData());
String id = wholeID.split(":")[1];
String[] projection = { MediaStore.MediaColumns.DATA };
String whereClause = BaseColumns._ID + "=?";
Cursor cursor = getContentResolver().query(getUri(), projection, whereClause,
new String[] { id }, null);
if (cursor != null) {
int column_index = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA);
if (cursor.moveToFirst()) {
IMAGE_FILEPATH = cursor.getString(column_index);
System.out.println(IMAGE_FILEPATH);
Bitmap galleryImage = getBitMapForPreview(IMAGE_FILEPATH,previewWidth,previewHeight);
previewImage.setImageBitmap(galleryImage);
}
cursor.close();
} else {
IMAGE_FILEPATH = uri.getPath();
Bitmap galleryImage = getBitMapForPreview(IMAGE_FILEPATH,previewWidth,previewHeight);
previewImage.setImageBitmap(galleryImage);
}
}
} catch (Exception e) {
try {
Uri selectedImageUri = data.getData();
String[] projection = { MediaStore.MediaColumns.DATA };
Cursor cursor = managedQuery(selectedImageUri, projection, null, null, null);
int column_index_data = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA);
cursor.moveToFirst();
String selectedImagePath = cursor.getString(column_index_data);
Bitmap galleryImage = getBitMapForPreview(selectedImagePath,previewWidth,previewHeight);
previewImage.setImageBitmap(galleryImage);
} catch (Exception ex) {
AlertDialog.Builder builder = new AlertDialog.Builder(CameraActivity.this);
builder.setMessage("El elemento seleccionado no es una imágen válida").setTitle("Información");
builder.setNegativeButton("Aceptar", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
// User cancelled the dialog
}
});
AlertDialog dialog = builder.create();
dialog.show();
}
}
} else {
try {
Uri selectedImageUri = data.getData();
String[] projection = { MediaStore.MediaColumns.DATA };
Cursor cursor = managedQuery(selectedImageUri, projection, null, null, null);
int column_index_data = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA);
cursor.moveToFirst();
String selectedImagePath = cursor.getString(column_index_data);
Bitmap galleryImage = getBitMapForPreview(selectedImagePath,previewWidth,previewHeight);
} catch (Exception e) {
AlertDialog.Builder builder = new AlertDialog.Builder(CameraActivity.this);
builder.setMessage("El elemento seleccionado no es una imágen válida").setTitle("Información");
builder.setNegativeButton("Aceptar", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
// User cancelled the dialog
}
});
AlertDialog dialog = builder.create();
dialog.show();
}
}
}
}
}
private Bitmap getBitMapForPreview(String path, int width, int height) {
BitmapFactory.Options options = new BitmapFactory.Options();
// solo se usa para calcular el samplesize
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, options);
options.inSampleSize = calculateInSampleSize(options, (int)convertDpToPixel((float)width, this), (int)convertDpToPixel((float)height,this));
options.inJustDecodeBounds = false;
Bitmap galleryImage = BitmapFactory.decodeFile(path, options);
return galleryImage;
}
/**
* esto se utiliza para reducir la carga en memoria de la imagen, android es muy
* ineficiente para cargar imagenes y si no se reduce el tamaño de acuerdo a la resolucion
* del dispositivo, se crean errores de memoria insuficiente, se tienen que obtener el calculo de
* los pixieles en base a los dp de la interfaz y generarlos de acuerdo a la densidad del dispositivo
*
* @param options
* @param reqWidth ancho del imageView donde se metera la imagen en pixeles
* @param reqHeight alto del imageView donde se metera la imagen en pixeles
* @return
*/
private int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and
// keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) > reqHeight && (halfWidth / inSampleSize) > reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
/**
* This method converts dp unit to equivalent pixels, depending on device density.
*
* @param dp A value in dp (density independent pixels) unit. Which we need to convert into pixels
* @param context Context to get resources and device specific display metrics
* @return A float value to represent px equivalent to dp depending on device density
*/
public static float convertDpToPixel(float dp, Context context){
Resources resources = context.getResources();
DisplayMetrics metrics = resources.getDisplayMetrics();
/**
*
* formulas de android developers:
*
* px = dp * (dpi / 160)
*
* dp = px / (dpi / 160)
*
*/
float px = dp * (metrics.densityDpi / 160f);
return px;
}
private Uri getUri() {
String state = Environment.getExternalStorageState();
if (!state.equalsIgnoreCase(Environment.MEDIA_MOUNTED))
return MediaStore.Images.Media.INTERNAL_CONTENT_URI;
return MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
}
}
package com.aluxoft.earrecognition;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.support.v7.app.ActionBarActivity;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.v7.app.ActionBarActivity;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import org.opencv.android.Utils;
import org.opencv.core.Mat;
import org.opencv.core.MatOfDMatch;
import org.opencv.core.MatOfKeyPoint;
import org.opencv.core.Size;
import org.opencv.features2d.DMatch;
import org.opencv.features2d.DescriptorExtractor;
import org.opencv.features2d.DescriptorMatcher;
import org.opencv.features2d.FeatureDetector;
import org.opencv.features2d.Features2d;
import org.opencv.highgui.Highgui;
import org.opencv.imgproc.Imgproc;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.Callable;
import bolts.Continuation;
import bolts.Task;
public class MainActivity extends ActionBarActivity {
ProgressDialog loading;
private static final int REQUEST_IMAGE_CAPTURE = 1;
private String mCurrentPhotoPath;
private String mCurrentPhotoPath1 = null;
private String mCurrentPhotoPath2 = null;
private String mCurrentPhotoPath3 = null;
private int previewWidth = 150;
private int previewHeight = 150;
private ImageView previewImage1;
private ImageView previewImage2;
private ImageView previewImage3;
private ImageView previewImage;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
System.loadLibrary("opencv_java");
System.loadLibrary("nonfree");
setContentView(R.layout.activity_main);
Button camara = (Button)findViewById(R.id.button3);
camara.setOnClickListener(new View.OnClickListener() {
previewImage1 = (ImageView)findViewById(R.id.imageView);
previewImage2 = (ImageView)findViewById(R.id.imageView2);
previewImage3 = (ImageView)findViewById(R.id.imageView3);
final Button captureFirstEarButton = (Button)findViewById(R.id.button);
captureFirstEarButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this,CameraActivity.class);
startActivity(intent);
previewImage = previewImage1;
takePhoto();
mCurrentPhotoPath1 = mCurrentPhotoPath;
}
});
final Button captureSecondEarButton = (Button)findViewById(R.id.button2);
captureSecondEarButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
previewImage = previewImage2;
takePhoto();
mCurrentPhotoPath2 = mCurrentPhotoPath;
}
});
final Button captureEarToIdentifyButton = (Button) findViewById(R.id.toidentify);
captureEarToIdentifyButton.setOnClickListener(new View.OnClickListener() {
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
public void onClick(View v) {
previewImage = previewImage3;
takePhoto();
mCurrentPhotoPath3 = mCurrentPhotoPath;
}
});
final Button processButton = (Button) findViewById(R.id.button3);
processButton.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
// do opencv magic here...
if (mCurrentPhotoPath1 != null && mCurrentPhotoPath2 != null && mCurrentPhotoPath3 != null) {
Task.callInBackground(new Callable<Void>() {
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
public Void call() throws Exception {
doOpenCvMagic();
return null;
}
}).continueWith(new Continuation<Void, Void>() {
@Override
public Void then(Task<Void> task) throws Exception {
return null;
}
});
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
}
});
return super.onOptionsItemSelected(item);
}
public void takePhoto() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO) {
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException ex) {
// Error occurred while creating the File
}
// Continue only if the File was successfully created
if (photoFile != null) {
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
}
}
}
@SuppressLint("NewApi")
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_IMAGE_CAPTURE) {
if (resultCode == RESULT_OK) {
if (mCurrentPhotoPath != null) {
// adds image to device gallery.
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
File f = new File(mCurrentPhotoPath);
Uri contentUri = Uri.fromFile(f);
mediaScanIntent.setData(contentUri);
this.sendBroadcast(mediaScanIntent);
String path = f.getAbsolutePath();
Log.e("", path);
Bitmap galleryImage = getBitMapForPreview(path,previewWidth,previewHeight);
previewImage.setImageBitmap(galleryImage);
}
}
}
}
public void doOpenCvMagic() {
Task.forResult("").continueWith(new Continuation<String, Void>() {
@Override
public Void then(Task<String> task) throws Exception {
loading = ProgressDialog.show(MainActivity.this, "Matching", "Wait while identifying the image...");
loading.setCancelable(false);
loading.setProgressStyle(ProgressDialog.STYLE_SPINNER);
return null;
}
}, Task.UI_THREAD_EXECUTOR);
Mat img1 = Highgui.imread(mCurrentPhotoPath1, Highgui.CV_LOAD_IMAGE_GRAYSCALE);
resizeMat(img1);
Mat img2 = Highgui.imread(mCurrentPhotoPath2, Highgui.CV_LOAD_IMAGE_GRAYSCALE);
resizeMat(img2);
Mat img3 = Highgui.imread(mCurrentPhotoPath3, Highgui.CV_LOAD_IMAGE_GRAYSCALE);
resizeMat(img3);
FeatureDetector detector = FeatureDetector.create(FeatureDetector.SIFT);
MatOfKeyPoint keypoints1 = new MatOfKeyPoint();
MatOfKeyPoint keypoints2 = new MatOfKeyPoint();
MatOfKeyPoint keypoints3 = new MatOfKeyPoint();
detector.detect(img1, keypoints1);
detector.detect(img2, keypoints2);
detector.detect(img3, keypoints3);
Mat descriptors1 = new Mat();
Mat descriptors2 = new Mat();
Mat descriptors3 = new Mat();
DescriptorExtractor extractor = DescriptorExtractor.create(DescriptorExtractor.SIFT);
extractor.compute(img1, keypoints1, descriptors1);
extractor.compute(img2, keypoints2, descriptors2);
extractor.compute(img3, keypoints3, descriptors3);
DescriptorMatcher matcher = DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE);
final Mat outImg1 = new Mat();
final Mat outImg2 = new Mat();
final Mat outImg3 = new Mat();
double distance13 = distanceFromData(matcher, keypoints3, descriptors3, keypoints1, descriptors1);
double distance23 = distanceFromData(matcher, keypoints3, descriptors3, keypoints2, descriptors2);
String message = "";
System.out.println(distance13);
System.out.println(distance23);
if (distance13 < distance23) {
message = "It's more likely to be the subject 1";
} else if (distance23 < distance13) {
message = "It's more likely to be the subject 2";
} else {
message = "Both subjects are equally likely";
}
Features2d.drawKeypoints(img1, keypoints1, outImg1);
Features2d.drawKeypoints(img2, keypoints2, outImg2);
Features2d.drawKeypoints(img3, keypoints3, outImg3);
Task.forResult(message).continueWith(new Continuation<String, Void>() {
@Override
public Void then(Task<String> task) throws Exception {
new AlertDialog.Builder(MainActivity.this)
.setTitle("Identification")
.setMessage(task.getResult())
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
}
})
.setIcon(android.R.drawable.ic_dialog_info)
.show();
Bitmap bitmap = Bitmap.createBitmap(outImg1.cols(), outImg1.rows(), Bitmap.Config.ARGB_8888);
Utils.matToBitmap(outImg1, bitmap);
previewImage1.setImageBitmap(bitmap);
bitmap = Bitmap.createBitmap(outImg2.cols(), outImg2.rows(), Bitmap.Config.ARGB_8888);
Utils.matToBitmap(outImg2, bitmap);
previewImage2.setImageBitmap(bitmap);
bitmap = Bitmap.createBitmap(outImg3.cols(), outImg3.rows(), Bitmap.Config.ARGB_8888);
Utils.matToBitmap(outImg3, bitmap);
previewImage3.setImageBitmap(bitmap);
loading.dismiss();
return null;
}
}, Task.UI_THREAD_EXECUTOR);
}
// ------- Helper methods -------
public void resizeMat(Mat image) {
final double kMaxWidth = 160;
final double kMaxHeight = 120;
if (image.width() <= kMaxWidth && image.height() <= kMaxHeight) {
return;
}
double ratio = (double)image.width() / (double)image.height();
double width, height;
if (ratio > 1) {
width = kMaxWidth;
height = kMaxWidth * ((double)image.height()/(double)image.width());
} else {
height = kMaxHeight;
width = kMaxHeight* ratio;
}
Imgproc.resize(image, image, new Size(width, height));
}
public double distanceFromData(DescriptorMatcher matcher, MatOfKeyPoint keypoints1, Mat descriptors1, MatOfKeyPoint keypoints2, Mat descriptors2) {
MatOfDMatch matches = new MatOfDMatch();
matcher.match(descriptors1, descriptors2, matches);
DMatch[] aMatches = matches.toArray();
double distance = 0;
for (int i=0;i<aMatches.length;++i) {
distance += aMatches[i].distance;
}
return distance;
}
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
// Save a file: path for use with ACTION_VIEW intents
mCurrentPhotoPath = image.getAbsolutePath();
return image;
}
private Bitmap getBitMapForPreview(String path, int width, int height) {
BitmapFactory.Options options = new BitmapFactory.Options();
// Just used to compute the sample size.
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, options);
options.inSampleSize = calculateInSampleSize(options, (int)convertDpToPixel((float)width, this), (int)convertDpToPixel((float)height,this));
options.inJustDecodeBounds = false;
Bitmap galleryImage = BitmapFactory.decodeFile(path, options);
return galleryImage;
}
/**
* This is used to decreases the image memory load, android is inefficient loading images
* and if you don't reduce the size accordingly to the resolution of the widget, it will have
* memory errors, it has to compute the pixels using the dpi of the screen and generate them
* according to the device screen density.
*
* @param options
* @param reqWidth width of the imageView
* @param reqHeight height of the imageView
* @return
*/
private int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and
// keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) > reqHeight && (halfWidth / inSampleSize) > reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
/**
* This method converts dp unit to equivalent pixels, depending on device density.
*
* @param dp A value in dp (density independent pixels) unit. Which we need to convert into pixels
* @param context Context to get resources and device specific display metrics
* @return A float value to represent px equivalent to dp depending on device density
*/
public static float convertDpToPixel(float dp, Context context){
Resources resources = context.getResources();
DisplayMetrics metrics = resources.getDisplayMetrics();
/**
* android developers equations:
* px = dp * (dpi / 160)
* dp = px / (dpi / 160)
*/
float px = dp * (metrics.densityDpi / 160f);
return px;
}
}
/**
* Created by josejuliomartinez on 24/09/15.
*/
package com.aluxoft.test;
public class TestConstants {
// ----- For testing purposes ----------------------------------------
static final String image1 = "/storage/emulated/0/DCIM/Camera/000_down_ear.jpg";
static final String image2 = "/storage/emulated/0/DCIM/Camera/001_front_ear.jpg";
static final String image3 = "/storage/emulated/0/DCIM/Camera/000_front_ear.jpg";
static final String image4 = "/storage/emulated/0/DCIM/Camera/test_1.png";
static final String image5 = "/storage/emulated/0/DCIM/Camera/test_3.png";
static final String image6 = "/storage/emulated/0/DCIM/Camera/test_2.png";
static final String image_patty_01 = "/storage/emulated/0/DCIM/Camera/PATTY_01.jpg";
static final String image_patty_02 = "/storage/emulated/0/DCIM/Camera/PATTY_02.jpg";
static final String image_elena_01 = "/storage/emulated/0/DCIM/Camera/ELENA_01.jpg";
static final String image_elena_02 = "/storage/emulated/0/DCIM/Camera/ELENA_02.jpg";
// ---------------------------------------------------------------------
}
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="wrap_content" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity"
android:id="@+id/MainActivity">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Capture First ear"
android:id="@+id/button"
android:layout_marginTop="47dp"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignRight="@+id/button2"
android:layout_alignEnd="@+id/button2" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Capture Second ear"
android:id="@+id/button2"
android:layout_centerVertical="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_below="@+id/imageView"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Capture ear to identify"
android:id="@+id/toidentify"
android:layout_centerVertical="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_below="@+id/imageView2"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/imageView"
android:layout_below="@+id/button"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignRight="@+id/button"
android:layout_alignEnd="@+id/button"
android:maxHeight="150dp" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/imageView2"
android:layout_below="@+id/button2"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignRight="@+id/button2"
android:layout_alignEnd="@+id/button2"
android:maxHeight="150dp" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/imageView3"
android:layout_below="@+id/toidentify"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignRight="@+id/button2"
android:layout_alignEnd="@+id/button2"
android:maxHeight="150dp" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Identify"
android:id="@+id/button3"
android:layout_below="@+id/imageView3"
android:layout_alignParentLeft="true" />
</RelativeLayout>
</ScrollView>
\ No newline at end of file
......@@ -13,7 +13,7 @@
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Cargar primera imagen"
android:text="Capture First ear"
android:id="@+id/button"
android:layout_marginTop="47dp"
android:layout_alignParentTop="true"
......@@ -25,13 +25,23 @@
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Cargar segunda imagen"
android:text="Capture Second ear"
android:id="@+id/button2"
android:layout_centerVertical="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_below="@+id/imageView"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Capture ear to identify"
android:id="@+id/toidentify"
android:layout_centerVertical="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_below="@+id/imageView2"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
......@@ -54,12 +64,23 @@
android:layout_alignEnd="@+id/button2"
android:maxHeight="150dp" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/imageView3"
android:layout_below="@+id/toidentify"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignRight="@+id/button2"
android:layout_alignEnd="@+id/button2"
android:maxHeight="150dp" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Procesar"
android:text="Identify"
android:id="@+id/button3"
android:layout_below="@+id/imageView2"
android:layout_below="@+id/imageView3"
android:layout_alignParentLeft="true" />
......
File added
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment