package com.d.takephoto;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import com.googlecode.javacv.cpp.opencv_core;
import com.googlecode.javacv.cpp.opencv_imgproc;
import org.opencv.android.BaseLoaderCallback;
import org.opencv.android.LoaderCallbackInterface;
import org.opencv.android.OpenCVLoader;
import org.opencv.android.Utils;
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.MatOfFloat;
import org.opencv.core.MatOfInt;
import org.opencv.core.MatOfRect;
import org.opencv.core.Point;
import org.opencv.core.Rect;
import org.opencv.core.Scalar;
import org.opencv.core.Size;
import org.opencv.imgproc.Imgproc;
import org.opencv.objdetect.CascadeClassifier;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Random;
//public class MainActivity extends AppCompatActivity {
public class MainActivity extends Activity {
public static final int TAKE_PHOTO = 1;
//public static final int CROP_PHOTO = 2;
private CascadeClassifier cascadeClassifier;
private Button takephoto;
private ImageView picture;
private ImageView picture2;
private ImageView picture3;
private Uri imageUri;
Mat imageMat;
private static final String TAG = "OCVSample::Activity";
private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
@Override
public void onManagerConnected(int status) {
switch (status) {
case LoaderCallbackInterface.SUCCESS:
{
Log.i(TAG, "OpenCV loaded successfully");
imageMat=new Mat();
//加载人脸检测xml
try {
// Copy the resource into a temp file so OpenCV can load it
InputStream is = getResources().openRawResource(R.raw.haarcascade_frontalface_alt);
File cascadeDir = getDir("cascade", Context.MODE_PRIVATE);
File mCascadeFile = new File(cascadeDir, "haarcascade_frontalface_alt.xml");
FileOutputStream os = new FileOutputStream(mCascadeFile);
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = is.read(buffer)) != -1) {
os.write(buffer, 0, bytesRead);
}
is.close();
os.close();
// Load the cascade classifier
cascadeClassifier = new CascadeClassifier(mCascadeFile.getAbsolutePath());
} catch (Exception e) {
Log.e("OpenCVActivity", "Error loading cascade", e);
}
} break;
default:
{
super.onManagerConnected(status);
} break;
}
}
};
@Override
public void onResume()
{
super.onResume();
if (!OpenCVLoader.initDebug()) {
Log.d("OpenCV", "Internal OpenCV library not found. Using OpenCV Manager for initialization");
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_10, this, mLoaderCallback);
} else {
Log.d("OpenCV", "OpenCV library found inside package. Using it!");
mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS);
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
takephoto = (Button)findViewById(R.id.take_photo);
picture = (ImageView)findViewById(R.id.imageView);
picture2 = (ImageView)findViewById(R.id.imageView2);
RelativeLayout.LayoutParams param0 = new RelativeLayout.LayoutParams(500, 650);
picture.setLayoutParams(param0);
//RelativeLayout.LayoutParams param1 = new RelativeLayout.LayoutParams(500, 650);
//picture2.setLayoutParams(param1);
takephoto.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
File outputImage = new File(Environment.getExternalStorageDirectory(), "output_image.jpg");
try {
if (outputImage.exists()) {
outputImage.delete();
}
outputImage.createNewFile();
}catch (IOException e){
e.printStackTrace();
}
imageUri = Uri.fromFile(outputImage);
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
startActivityForResult(intent, TAKE_PHOTO);
}
});
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data){
switch (requestCode){
case TAKE_PHOTO:
//if (resultCode == RESULT_OK){
//Intent intent = new Intent("com.android.camera.action.CROP");
//intent.setDataAndType(imageUri, "image/*");
// intent.putExtra("scale", true);
//intent.putExtra(MediaStore.EXTRA_OUTPUT,imageUri);
//startActivityForResult(intent, CROP_PHOTO);
//}
//break;
//case CROP_PHOTO:
//if (resultCode == RESULT_OK){
try{
//获取原图
Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageUri));
Mat mat_src = new Mat(bitmap.getHeight(), bitmap.getWidth(), CvType.CV_8UC4);
Utils.bitmapToMat(bitmap, mat_src);
int nnHeight = bitmap.getHeight()/10;
int nnWidth = bitmap.getWidth()/10;
Mat mat_bits = new Mat(nnHeight, nnWidth, CvType.CV_8UC4);
Imgproc.resize(mat_src, mat_bits, new Size(nnWidth, nnHeight));
Bitmap bmp_gray0 = Bitmap.createBitmap(mat_bits.cols(), mat_bits.rows(), Bitmap.Config.ARGB_8888 );
Utils.matToBitmap(mat_bits, bmp_gray0);
picture.setImageBitmap(bitmap);
Mat mGray = new Mat(nnHeight, nnWidth, CvType.CV_8UC1);
Imgproc.cvtColor(mat_src, mGray, Imgproc.COLOR_BGRA2GRAY, 1);
//检测并显示
MatOfRect faces = new MatOfRect();
if (cascadeClassifier != null) {
cascadeClassifier.detectMultiScale(mGray, faces, 1.1, 2, 2, new Size(mGray.height()/5, mGray.height()/5), new Size());
}
Rect[] facesArray = faces.toArray();
//---------------------
int nHeight = 100;
int nWidth = 100;
//---------------------
//opencv_contrib.FaceRecognizer faceRec = new opencv_contrib.FaceRecognizer();
//opencv_contrib.FaceRecognizer faceRec = com.googlecode.javacv.cpp.opencv_contrib.createEigenFaceRecognizer();
// opencv_contrib.FaceRecognizer eigenRecog = com.googlecode.javacv.cpp.opencv_contrib.createEigenFaceRecognizer();
// opencv_contrib.FaceRecognizer faceRec = com.googlecode.javacv.cpp.opencv_contrib.createFisherFaceRecognizer();
opencv_contrib.FaceRecognizer lbphRecog = com.googlecode.javacv.cpp.opencv_contrib.createLBPHFaceRecognizer();
// opencv_core.MatVector var1 = new opencv_core.MatVector(2);
Bitmap bitmap1 = BitmapFactory.decodeResource(getResources(), R.drawable.img_01);
opencv_core.IplImage imgTemp1 = bitmapToIplImage(bitmap1);
Bitmap bitmap2 = BitmapFactory.decodeResource(getResources(), R.drawable.img_02);
opencv_core.IplImage imgTemp2 = bitmapToIplImage(bitmap2);
// int[] var2 = {1,1};
// var1.put(0, imgTemp1);
// var1.put(1, imgTemp2);
// faceRec.train(var1, var2);
for (int i = 0; i <facesArray.length; i++) {
Core.rectangle(mat_src, facesArray[i].tl(), facesArray[i].br(), new Scalar(0, 255, 0, 255), 3);
Point pt = new Point();
pt.x = facesArray[i].br().x;
pt.y = facesArray[i].br().y;
String str_x = Double.toString(pt.x);
String str_y = Double.toString(pt.y);
Mat copyMat = mGray.submat(facesArray[i]);
Mat mat_source = new Mat(nHeight, nWidth, CvType.CV_8UC1);
Imgproc.resize(copyMat, mat_source, new Size(nWidth, nHeight));
//int[] predicted_label = {-1};
//double[] predicted_confidence = {0.0};
opencv_core.IplImage sourceImg = bitmapToIplImage(bitmap);
//faceRec.predict(sourceImg, predicted_label, predicted_confidence);
double c1 = CmpPic(sourceImg, imgTemp1);
double c2 = CmpPic(sourceImg, imgTemp2);
String str = str_x + ", " + str_y + " S1:" + c1 + " S2:"+ c2;
Core.putText(mat_src,str, pt, Core.FONT_HERSHEY_SIMPLEX, 1, new Scalar(255,23,0),2);
Bitmap bmp_dst = Bitmap.createBitmap(copyMat.cols(), copyMat.rows(), Bitmap.Config.ARGB_8888 );
Utils.matToBitmap(copyMat, bmp_dst);
String str2 = getRandomString(8)+".png";
saveBitmap(bmp_dst, str2);
}
//图像显示
Bitmap bmp_gray = Bitmap.createBitmap(mat_src.cols(), mat_src.rows(), Bitmap.Config.ARGB_8888 );
Utils.matToBitmap(mat_src, bmp_gray);
picture2.setImageBitmap(bmp_gray);
// int nHeight = bitmap.getHeight()/10;
// int nWidth = bitmap.getWidth()/10;
// Mat mat_small = new Mat(nHeight, nWidth, CvType.CV_8UC4);
// Imgproc.resize(mat_src, mat_small, new Size(nWidth, nHeight));
//图像处理
//Mat mat_src = new Mat(bitmap.getHeight(), bitmap.getWidth(), CvType.CV_8UC4);
//Utils.bitmapToMat(bitmap, mat_src);
// int nHeight = bitmap.getHeight()/10;
// int nWidth = bitmap.getWidth()/10;
// Mat mat_small = new Mat(nHeight, nWidth, CvType.CV_8UC4);
// Imgproc.resize(mat_src, mat_small, new Size(nWidth, nHeight));
// Mat mat_gray = new Mat(mat_small.cols(), mat_small.rows(), CvType.CV_8UC1);
// Imgproc.cvtColor(mat_small, mat_gray, Imgproc.COLOR_BGRA2GRAY, 1);
//
// //-------------------------------------------------------------------
// Mat frame = new Mat(mat_small.cols(), mat_small.rows(), CvType.CV_8UC4);
// mat_small.copyTo(frame);
//
// Mat frameHSV = new Mat(mat_small.cols(), mat_small.rows(), CvType.CV_8UC3);; // hsv空间
// Mat mask = new Mat(mat_small.cols(), mat_small.rows(), CvType.CV_8UC1);
// Mat dst = new Mat(mat_small.cols(), mat_small.rows(), CvType.CV_8UC3); // 输出图像
// //dst.copyTo(frame);
// // 中值滤波,去除椒盐噪声
// Imgproc.medianBlur(frame, frame, 5);
// Imgproc.cvtColor(frame, frameHSV, Imgproc.COLOR_RGB2HSV, 3);
// Mat dstTemp1 = new Mat(mat_small.cols(), mat_small.rows(), CvType.CV_8UC1);
// Mat dstTemp2 = new Mat(mat_small.cols(), mat_small.rows(), CvType.CV_8UC1);
// // 对HSV空间进行量化,得到二值图像,亮的部分为手的形状
// Core.inRange(frameHSV, new Scalar(0, 30, 30), new Scalar(40, 170, 256), dstTemp1);
// Core.inRange(frameHSV, new Scalar(156, 30, 30), new Scalar(180, 170, 256), dstTemp2);
// Core.bitwise_or(dstTemp1, dstTemp2, mask);
// //dstTemp1.copyTo(mask);
// // 形态学操作,去除噪声,并使手的边界更加清晰
// Mat element = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(3, 3));
// Imgproc.erode(mask, mask, element);
// Imgproc.morphologyEx(mask, mask, Imgproc.MORPH_OPEN, element);
// Imgproc.dilate(mask, mask, element);
// Imgproc.morphologyEx(mask, mask, Imgproc.MORPH_CLOSE, element);
//
// frame.copyTo(dst, mask);
//-------------------------------------------------------------------
}catch (FileNotFoundException e){
e.printStackTrace();
}
//}
break;
default:
break;
}
}
//length用户要求产生字符串的长度
public static String getRandomString(int length){
String str="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
Random random=new Random();
StringBuffer sb=new StringBuffer();
for(int i=0;i<length;i++){
int number=random.nextInt(62);
sb.append(str.charAt(number));
}
return sb.toString();
}
//保存图片
public static void saveBitmap(Bitmap bm, String picName) {
File f = new File("/storage/emulated/0/Pictures/", picName);
if (f.exists()) {
f.delete();
}
try {
FileOutputStream out = new FileOutputStream(f);
bm.compress(Bitmap.CompressFormat.PNG, 90, out);
out.flush();
out.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 特征对比
*
* @param file1 人脸特征
* @param file2 人脸特征
* @return 相似度
*/
public double CmpPic(Mat img11, Mat img22) {
try {
// int l_bins = 256;
// int hist_size[] = {l_bins};
// float v_ranges[] = {0, 255};
// float ranges[][] = {v_ranges};
Mat hist = new Mat(256, 1, CvType.CV_8U, new Scalar(0));
ArrayList histsSource = new ArrayList();
histsSource.add(img11);
Imgproc.calcHist(histsSource, new MatOfInt(0), new Mat(), hist, new MatOfInt(256), new MatOfFloat(0f, 256f));
Mat hist2 = new Mat(256, 1, CvType.CV_8U, new Scalar(0));
ArrayList histsSource2 = new ArrayList();
histsSource2.add(img22);
Imgproc.calcHist(histsSource2, new MatOfInt(0), new Mat(), hist, new MatOfInt(256), new MatOfFloat(0f, 256f));
Core.normalize(hist,hist);
Core.normalize(hist2,hist2);
double c1 = Imgproc.compareHist(hist, hist2, 1);
double c2 = Imgproc.compareHist(hist, hist2, 2);
return (c1 + c2) / 2;
} catch (Exception e) {
e.printStackTrace();
return -1;
}
}
public Bitmap MatToBitmap(Mat src) {
Bitmap bitmap = Bitmap.createBitmap(src.width(), src.height(), Bitmap.Config.ARGB_8888);
Utils.matToBitmap(src, bitmap);
return bitmap;
}
public Mat bitmapToMat(Bitmap bitmap) {
Mat rgbMat = new Mat();
Utils.bitmapToMat(bitmap, rgbMat);
return rgbMat;
}
public Bitmap IplImageToBitmap(opencv_core.IplImage iplImage) {
Bitmap bitmap = null;
bitmap = Bitmap.createBitmap(iplImage.width(), iplImage.height(), Bitmap.Config.ARGB_8888);
bitmap.copyPixelsFromBuffer(iplImage.getByteBuffer());
return bitmap;
}
public opencv_core.IplImage bitmapToIplImage(Bitmap bitmap) {
opencv_core.IplImage iplImage;
iplImage = opencv_core.IplImage.create(bitmap.getWidth(), bitmap.getHeight(), opencv_core.IPL_DEPTH_8U, 4);
bitmap.copyPixelsToBuffer(iplImage.getByteBuffer());
return iplImage;
}
public double CmpPic(opencv_core.IplImage Image1, opencv_core.IplImage Image2) {
int l_bins = 20;
int hist_size[] = {l_bins};
float v_ranges[] = {0, 100};
float ranges[][] = {v_ranges};
opencv_core.IplImage imageArr1[] = {Image1};
opencv_core.IplImage imageArr2[] = {Image2};
opencv_imgproc.CvHistogram Histogram1 = opencv_imgproc.CvHistogram.create(1, hist_size, CV_HIST_ARRAY, ranges, 1);
opencv_imgproc.CvHistogram Histogram2 = opencv_imgproc.CvHistogram.create(1, hist_size, CV_HIST_ARRAY, ranges, 1);
cvCalcHist(imageArr1, Histogram1, 0, null);
cvCalcHist(imageArr2, Histogram2, 0, null);
cvNormalizeHist(Histogram1, 100.0);
cvNormalizeHist(Histogram2, 100.0);
return cvCompareHist(Histogram1, Histogram2, CV_COMP_CORREL);
}
}