您的位置:首页 > 移动开发 > Android开发

Android OpenCV 人脸识别 Opencv3.1

2016-12-08 11:31 393 查看
只是一个简单的demo。只能检测人脸,识别率很低,以后还要实现人脸的识别,认出你是谁。以后补充。。。

1.配置环境

参考之前的文章
http://blog.csdn.net/aaron121314/article/details/53465547
2.布局

<org.opencv.android.JavaCameraView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/HelloOpenCvView" />


3.权限

<uses-permission android:name="android.permission.CAMERA"/>

<uses-feature android:name="android.hardware.camera" android:required="false"/>
<uses-feature android:name="android.hardware.camera.autofocus" android:required="false"/>
<uses-feature android:name="android.hardware.camera.front" android:required="false"/>
<uses-feature android:name="android.hardware.camera.front.autofocus" android:required="false"/>



4.初始化

private CameraBridgeViewBase mOpenCvCameraView;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
mOpenCvCameraView = (CameraBridgeViewBase) findViewById(R.id.HelloOpenCvView);
mOpenCvCameraView.setVisibility(SurfaceView.VISIBLE);
mOpenCvCameraView.setCvCameraViewListener(this);
}

@Override
protected void onResume() {
super.onResume();
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_0_0, this, mLoaderCallback);
}


private BaseLoaderCallback  mLoaderCallback = new BaseLoaderCallback(this) {
@Override
public void onManagerConnected(int status) {
switch (status) {
case LoaderCallbackInterface.SUCCESS:
{
try {
// load cascade file from application resources
InputStream is = getResources().openRawResource(R.raw.lbpcascade_frontalface);
File cascadeDir = getDir("cascade", C
4000
ontext.MODE_PRIVATE);
mCascadeFile = new File(cascadeDir, "lbpcascade_frontalface.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();

mJavaDetector = new CascadeClassifier(mCascadeFile.getAbsolutePath());
if (mJavaDetector.empty()) {
mJavaDetector = null;
}

cascadeDir.delete();

} catch (IOException e) {
e.printStackTrace();
}

mOpenCvCameraView.enableView();
} break;
default:
{
super.onManagerConnected(status);
} break;
}
}
};


到这里就可以显示Camera的画面了。

lbpcascade_frontalface.xml 这个人脸训练数据。用来检测人脸的。

5.检测人脸

实现这个listener

public class MainActivity extends AppCompatActivity implements CameraBridgeViewBase.CvCameraViewListener2

@Override
public void onCameraViewStarted(int width, int height) {
mGray = new Mat();
mRgba = new Mat();
mRgbaT=new Mat();
}@Overridepublic void onCameraViewStopped() { mGray.release(); mRgba.release();
mRgbaT.release();
}
@Override
public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {
mRgba = inputFrame.rgba();
mGray = inputFrame.gray();

Core.transpose(mRgba,mRgbaT); //转置函数,可以水平的图像变为垂直
Imgproc.resize(mRgbaT,mRgba, mRgba.size(), 0.0D, 0.0D, 0); //将转置后的图像缩放为mRgbaF的大小
Core.flip(mRgba, mRgba,0); //根据x,y轴翻转,0-x 1-y

Core.transpose(mGray,mRgbaT); //转置函数,可以水平的图像变为垂直
Imgproc.resize(mRgbaT,mGray, mGray.size(), 0.0D, 0.0D, 0); //将转置后的图像缩放为mRgbaF的大小
Core.flip(mGray, mGray,0); //根据x,y轴翻转,0-x 1-y

if (mAbsoluteFaceSize == 0) {
int height = mGray.rows();
if (Math.round(height * mRelativeFaceSize) > 0) {
mAbsoluteFaceSize = Math.round(height * mRelativeFaceSize);
}
}

MatOfRect faces = new MatOfRect();

if (mJavaDetector != null)
mJavaDetector.detectMultiScale(mGray, faces, 1.1, 2, 2, // TODO: objdetect.CV_HAAR_SCALE_IMAGE
new Size(mAbsoluteFaceSize, mAbsoluteFaceSize), new Size());

Rect[] facesArray = faces.toArray();
for (int i = 0; i < facesArray.length; i++) {
Log.i("a","face "+facesArray[i]);
Imgproc.rectangle(mRgba, facesArray[i].tl(), facesArray[i].br(), FACE_RECT_COLOR, 3);
}
return mRgba;
}
}


然后去检测人脸。

注意:我在测试的时候,preview画面的被旋转了90度,所以这样要把图像弄正。2个参数都要旋转,mGray也要选择,要不画面是正的,但是检测不到人脸。

Core.transpose(mRgba,mRgbaT); //转置函数,可以水平的图像变为垂直
Imgproc.resize(mRgbaT,mRgba, mRgba.size(), 0.0D, 0.0D, 0); //将转置后的图像缩放为mRgbaF的大小
Core.flip(mRgba, mRgba,0); //根据x,y轴翻转,0-x 1-y

Core.transpose(mGray,mRgbaT); //转置函数,可以水平的图像变为垂直
Imgproc.resize(mRgbaT,mGray, mGray.size(), 0.0D, 0.0D, 0); //将转置后的图像缩放为mRgbaF的大小
Core.flip(mGray, mGray,0); //根据x,y轴翻转,0-x 1-y
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: