Detect faces on an image in Android OpenCV java
When touch on the screen, this method is invoked, highgui.imwrite is suppose to overwrite the previous store into sdcard method.
public boolean onTouch(View v, MotionEvent event) {
Log.i(TAG,"onTouch event");
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss");
String currentDateandTime = sdf.format(new Date());
String fileName = Environment.getExternalStorageDirectory().getPath() +
"/sample_picture_" + currentDateandTime + ".jpg";
mOpenCvCameraView.takePicture(fileName);
Toast.makeText(this, fileName + " saved", Toast.LENGTH_SHORT).show();
Mat a = Highgui.imread(fileName);
MatOfRect faceDetections = new MatOfRect();
if (mDetectorType == JAVA_DETECTOR) {
if (mJavaDetector != null)
mJavaDetector.detectMultiScale(a, faceDetections);
}
else if (mDetectorType == NATIVE_DETECTOR) {
if (mNativeDetector != null)
mNativeDetector.detect(mGray, faceDetections);
}
else {
Log.e(TAG, "Detection method is not selected!");
}
for (Rect rect : faceDetections.toArray()){
Core.rectangle(a, new Point(rect.x, rect.y), new Point(rect.x + rect.width, rect.y + rect.height), new Scalar(0, 255, 0));
Boolean bool = null;
bool = Highgui.imwrite(fileName,a);
if (bool == true)
Log.d(TAG, "SUCCESS writing image to external storage");
else
Log.d(TAG, "Fail writing image to external storage");
}
return false;
}
Then this method will create fileName for storing in external storage and takes the picture.
public void takePicture(final String fileName) {
Log.i(TAG, "Taking picture");
this.mPictureFileName = fileName;
// Postview and jpeg are sent in the same buffers if the queue is not empty when performing a capture.
// Clear up buffers to avoid mCamera.takePicture to be stuck because of a memory issue
mCamera.setPreviewCallback(null);
// PictureCallback is implemented by the current class
mCamera.takePicture(null, null, this);
}
This method takes bytes array and store into sdcard.
public void onPictureTaken(byte[] data, Camera camera) {
Log.i(TAG, "Saving a bitmap to file");
// The camera preview was automatically stopped. Start it again.
mCamera.startPreview();
//...
mCamera.setPreviewCallback(this);
// Write the image in a file (in jpeg format)
try {
FileOutputStream fos = new FileOutputStream(mPictureFileName);
fos.write(data);
fos.close();
} catch (java.io.IOException e) {
Log.e("PictureDemo", "Exception in photoCallback", e);
}
}
There are 2 constructor for the class and the cascade file loaders
public ActivityView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ActivityView(Context context) {
super(context, null);
try {
// copy the resource into an XML file so that we can create the classifier
final File cascadeFile = getCascade(R.raw.lbpcascade_frontalface);
_javaDetector = new CascadeClassifier(cascadeFile.getAbsolutePath());
if (_javaDetector.empty()) {
Log.e(TAG, "Failed to load cascade classifier");
_javaDetector = null;
} else{
Log.i(TAG, "Loaded cascade classifier from " + cascadeFile.getAbsolutePath());
}
_nativeDetector = new DetectionBasedTracker(cascadeFile.getAbsolutePath(), 0);
cascadeFile.getParentFile().delete();
cascadeFile.delete();
} catch (IOException e) {
e.printStackTrace();
Log.e(TAG, "Failed to load cascade. Exception thrown: " + e);
}
}
private File getCascade(final int cascadeRessourceId) throws IOException{
InputStream is = null;
OutputStream os = null;
try{
is = getContext().getResources().openRawResource(cascadeRessourceId);
File cascadeDir = getContext().getDir("cascade", Context.MODE_PRIVATE);
File cascadeFile = new File(cascadeDir, "cascade.xml");
os = new FileOutputStream(cascadeFile);
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = is.read(buffer)) != -1) {
os.write(buffer, 0, bytesRead);
}
return cascadeFile;
}finally{
is.close();
os.close();
}
}
Now I believe I have converted to type Mat with highgui.imread(directory). But now I want to able to detect faces ...