android opencv NDK人脸识别和对比
}
env->ReleaseStringUTFChars(name, filePath);
return 0;
}
- 人脸对比
/**
*人脸对比
*/
extern “C”
JNIEXPORT jdouble JNICALL
Java_com_hxg_ndkface_FaceDetection_histogramMatch(JNIEnv *env, jobject instance, jobject bitmap1,
jobject bitmap2) {
//1.Bitmap转成opencv能操作的C++对象Mat
Mat mat, mat1;
bitmap2Mat(env, mat, bitmap1);
bitmap2Mat(env, mat1, bitmap2);
// 转灰度矩阵
cvtColor(mat, mat, COLOR_BGR2HSV);
cvtColor(mat1, mat1, COLOR_BGR2HSV);
int channels[] = {0, 1};
int histsize[] = {180, 255};
float r1[] = {0, 180};
float r2[] = {0, 255};
const float *ranges[] = {r1, r2};
Mat hist1, hist2;
calcHist(&mat, 3, channels, Mat(), hist1, 2, histsize, ranges, true);
//https://www.cnblogs.com/bjxqmy/p/12292421.html
normalize(hist1, hist1, 1, 0, NORM_L1);
calcHist(&mat1, 3, channels, Mat(), hist2, 2, histsize, ranges, true);
normalize(hist2, hist2, 1, 0, NORM_L1);
double similarity = compareHist(hist1, hist2, HISTCMP_CORREL);
__android_log_print(ANDROID_LOG_ERROR, “TTTTT”, “相识度:%f”, similarity);
return similarity;
}
- Dnn模式的人脸识别,并抠图
private void copyCaseCadeFilePbtxt() {
InputStream is = null;
FileOutputStream os = null;
try {
// load cascade file from application resources
is = getResources().openRawResource(R.raw.opencv_face_detector);
File cascadeDir = getDir(“cascade”, Context.MODE_PRIVATE);
mCascadeFile = new File(cascadeDir, “opencv_face_detector.pbtxt”);
if (mCascadeFile.exists()) return;
os = new FileOutputStream(mCascadeFile);
byte[] buffer = new byte[1024 * 1024];
int bytesRead;
while ((bytesRead = is.read(buffer)) != -1) {
os.write(buffer, 0, bytesRead);
}
is.close();
os.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (is != null) {
is.close();
}
if (os != null) {
os.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
private void copyCaseCadeFileUint8() {
InputStream is = null;
FileOutputStream os = null;
try {
// load cascade file from application resources
is = getResources().openRawResource(R.raw.opencv_face_detector_uint8);
File cascadeDir = getDir(“cascade”, Context.MODE_PRIVATE);
mCascadeFile = new File(cascadeDir, “opencv_face_detector_uint8.pb”);
if (mCascadeFile.exists()) return;
os = new FileOutputStream(mCascadeFile);
byte[] buffer = new byte[1024 * 1024];
int bytesRead;
while ((bytesRead = is.read(buffer)) != -1) {
os.write(buffer, 0, bytesRead);
}
is.close();
os.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (is != null) {
is.close();
}
if (os != null) {
os.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
*Dnn模式的人脸识别,并抠图
*/
extern “C”
JNIEXPORT jboolean JNICALL
Java_com_hxg_ndkface_FaceDetection_faceDnnDetection(JNIEnv *env, jobject instance,
jstring model_binary,
jstring model_desc,
jstring checkPath,
jstring resultPath) {
const char *model_binary_path = env->GetStringUTFChars(model_binary, 0);
const char *model_desc_path = env->GetStringUTFChars(model_desc, 0);
const char *check_path = env->GetStringUTFChars(checkPath, 0);
const char *result_path = env->GetStringUTFChars(resultPath, 0);
Net net = readNetFromTensorflow(model_binary_path, model_desc_path);
net.setPreferableBackend(DNN_BACKEND_OPENCV);
net.setPreferableTarget(DNN_TARGET_CPU);
if (net.empty()) {
__android_log_print(ANDROID_LOG_ERROR, “TTTTT”, “%s”, “could not load net…”);
return false;
}
Mat frame = imread(check_path); //读入检测文件
__android_log_print(ANDROID_LOG_ERROR, “TTTTT”, “%s”, “输入数据调整”);
// 输入数据调整
Mat inputBlob = blobFromImage(frame, 1.0,
Size(300, 300), Scalar(104.0, 177.0, 123.0), false, false);
net.setInput(inputBlob, “data”);
// 人脸检测
Mat detection = net.forward(“detection_out”);
Mat detectionMat(detection.size[2], detection.size[3], CV_32F, detection.ptr());
Mat face_area;
for (int i = 0; i < detectionMat.rows; i++) {
// 置信度 0~1之间
float confidence = detectionMat.at(i, 2);
if (confidence > 0.7) {
//count++;
int xLeftBottom = static_cast(detectionMat.at(i, 3) * frame.cols);
int yLeftBottom = static_cast(detectionMat.at(i, 4) * frame.rows);
int xRightTop = static_cast(detectionMat.at(i, 5) * frame.cols);
int yRightTop = static_cast(detectionMat.at(i, 6) * frame.rows);
Rect object((int) xLeftBottom, (int) yLeftBottom,
(int) (xRightTop - xLeftBottom),
(int) (yRightTop - yLeftBottom));
face_area = frame(object); //扣出图片
rectangle(frame, object, Scalar(0, 255, 0)); //画框
}
}
imwrite(result_path, face_area); //写出文件
env->ReleaseStringUTFChars(model_binary, model_binary_path);
env->ReleaseStringUTFChars(model_desc, model_desc_path);
env->ReleaseStringUTFChars(checkPath, check_path);
env->Rel Android开源项目《ali1024.coding.net/public/P7/Android/git》 easeStringUTFChars(resultPath, result_path);
return true;
}
- Bitmap和Mat互转
/**
Bitmap转成op 《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》开源 encv能操作的C++对象Mat
@param env
@param mat
@param bitmap
*/
void bitmap2Mat(JNIEnv *env, Mat &mat, jobject bitmap) {
//Mat 里面有个type :CV_8UC4刚好对上我们的Bitmap中的ARGB_8888 , CV_8UC2对应Bitmap中的RGB_555
//获取 bitmap 信息
AndroidBitmapInfo info;
void *pixels;
try {
// AndroidBitmap_getInfo(env, bitmap, &info);
//锁定Bitmap画布
// AndroidBitmap_lockPixels(env, bitmap, &pixels);
CV_Assert(AndroidBitmap_getInfo(env, bitmap, &info) >= 0);
CV_Assert(info.format == ANDROID_BITMAP_FORMAT_RGBA_8888 ||
info.format == ANDROID_BITMAP_FORMAT_RGB_565);
CV_Assert(AndroidBitmap_lockPixels(env, bitmap, &pixels) >= 0);
CV_Assert(pixels);
//指定mat的宽高type BGRA
mat.create(info.height, info.width, CV_8UC4);
if (info.format == ANDROID_BITMAP_FORMAT_RGBA_8888) {
//对应mat应该是CV_8UC4
Mat temp(info.height, info.width, CV_8UC4, pixels);
//把数据temp复制到mat里面
temp.copyTo(mat);
} else if (info.format == ANDROID_BITMAP_FORMAT_RGB_565) {
//对应mat应该是CV_8UC2
Mat temp(info.height, info.width, CV_8UC2, pixels);
//mat 是CV_8UC4 ,CV_8UC2 > CV_8UC4
cvtColor(temp, mat, COLOR_BGR5652BGRA);
}
//解锁Bitmap画布
AndroidBitmap_unlockPixels(env, bitmap);
return;
} catch (Exception &e) {
AndroidBitmap_unlockPixels(env, bitmap);
jclass je = env->FindClass(“java/lang/Exception”);
env->ThrowNew(je, e.what());
return;
} catch (…) {
AndroidBitmap_unlockPixels(env, bitmap);
jclass je = env->FindClass(“java/lang/Exception”);
env->ThrowNew(je, “Unknown exception in JNI code {nBitmapToMat}”);
return;
}
}
/**
把mat转成bitmap
@param env
@param mat
@param bitmap
*/
void mat2Bitmap(JNIEnv *env, Mat mat, jobject bitmap) {
//Mat 里面有个type :CV_8UC4刚好对上我们的Bitmap中的ARGB_8888 , CV_8UC2对应Bitmap中的RGB_555
//获取 bitmap 信息
AndroidBitmapInfo info;
void *pixels;
try {
// AndroidBitmap_getInfo(env, bitmap, &info);
//锁定Bitmap画布
// AndroidBitmap_lockPixels(env, bitmap, &pixels);
CV_Assert(AndroidBitmap_getInfo(env, bitmap, &info) >= 0);
CV_Assert(info.format == ANDROID_BITMAP_FORMAT_RGBA_8888 ||
info.format == ANDROID_BITMAP_FORMAT_RGB_565);
CV_Assert(mat.dims == 2 && info.height == (uint32_t) mat.rows &&
info.width == (uint32_t) mat.cols);
CV_Assert(mat.type() == CV_8UC1 || mat.type() == CV_8UC3 || mat.type() == CV_8UC4);
CV_Assert(AndroidBitmap_lockPixels(env, bitmap, &pixels) >= 0);
CV_Assert(pixels);
if (info.format == ANDROID_BITMAP_FORMAT_RGBA_8888) {
//对应mat应该是CV_8UC4
Mat temp(info.height, info.width, CV_8UC4, pixels);
if (mat.type() == CV_8UC4) {
mat.copyTo(temp);
} else if (mat.type() == CV_8UC2) {
cvtColor(mat, temp, COLOR_BGR5652BGRA);
} else if (mat.type() == CV_8UC1) {//灰度mat
cvtColor(mat, temp, COLOR_GRAY2BGRA);
} else if (mat.type() == CV_8UC3) {
cvtColor(mat, temp, COLOR_RGB2BGRA);
}
} else if (info.format == ANDROID_BITMAP_FORMAT_RGB_565) {
//对应mat应该是CV_8UC2
Mat temp(info.height, info.width, CV_8UC2, pixels);
if (mat.type() == CV_8UC4) {
cvtColor(mat, temp, COLOR_BGRA2BGR565);
} else if (mat.type() == CV_8UC2) {
mat.copyTo(temp);
} else if (mat.type() == CV_8UC1) {//灰度mat
cvtColor(mat, temp, COLOR_GRAY2BGR565);
} else if (mat.type() == CV_8UC3) {
cvtColor(mat, temp, COLOR_RGB2BGR565);
}
}
//解锁Bitmap画布
AndroidBitmap_unlockPixels(env, bitmap);
return;
} catch (const Exception &e) {
AndroidBitmap_unlockPixels(env, bitmap);
jclass je = env->FindClass(“java/lang/Exception”);
env->ThrowNew(je, e.what());
return;
} catch (…) {
AndroidBitmap_unlockPixels(env, bitmap);
jclass je = env->FindClass(“java/lang/Exception”);
env->ThrowNew(je, “Unknown exception in JNI code {nMatToBitmap}”);
return;
}
}
- 人脸检测Activity
package com.hxg.ndkface;
import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.hardware.Camera;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.AppCompatImageView;
import androidx.appcompat.widget.AppCompatTextView;
import androidx.arch.core.executor.ArchTaskExecutor;
import com.hxg.ndkface.camera.AutoTexturePreviewView;
import com.hxg.ndkface.manager.CameraPreviewManager;
import com.hxg.ndkface.model.SingleBaseConfig;
import com.hxg.ndkface.utils.CornerUtil;
import com.hxg.ndkface.utils.FileUtils;
import com.tbruyelle.rxpermissions3.RxPermissions;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
public class MainNorFaceActivity extends AppCompatActivity {
private Bitmap mFaceBitmap;
private FaceDetection mFaceDetection;
private File mCascadeFile;
private AppCompatTextView mTextView;
private RxPermissions rxPermissions;
private AutoTexturePreviewView mAutoCameraPreviewView;
// 图片越大,性能消耗越大,也可以选择640480, 1280720
private static final int PREFER_WIDTH = SingleBaseConfig.getBaseConfig().getRgbAndNirWidth();
private static final int PERFER_HEIGH = SingleBaseConfig.getBaseConfig().getRgbAndNirHeight();
@Override
public void onDetachedFromWindow() {
super.onDetachedFromWindow();
CameraPreviewManager.getInstance().stopPreview();
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
rxPermissions = new RxPermissions(this);
mTextView = findViewById(R.id.note);
mAutoCameraPreviewView = findViewById(R.id.auto_camera_preview_view);
mFaceBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.face);
copyCaseCadeFile();
mFaceDetection = new FaceDetection();
mFaceDetection.loadCascade(mCascadeFile.getAbsolutePath());
}
/**
- 加载人脸识别的分类器文件
*/
private void copyCaseCadeFile() {
try {
// load cascade file from application resources
InputStream is = getResources().openRawResource(R.raw.lbpcascade_frontalface);
File cascadeDir = getDir(“cascade”, Context.MODE_PRIVATE);
mCascadeFile = new File(cascadeDir, “lbpcascade_frontalface.xml”);
if (mCascadeFile.exists()) return;
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();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
CornerUtil.clipViewCircle(mAutoCameraPreviewView);
rxPermissions.request(
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.CAMERA)
.subscribe(aBoolean -> {
startTestOpenDebugRegisterFunction();
});
}
@SuppressLint(“RestrictedApi”)
private void startTestOpenDebugRegisterFunction() {
CameraPreviewManager.getInstance().setCameraFacing(CameraPreviewManager.CAMERA_FACING_FRONT);
CameraPreviewManager.getInstance().startPreview(this, mAutoCameraPreviewView,
PREFER_WIDTH, PERFER_HEIGH, (byte[] data, Camera camera, int width, int height) -> {
//识别人脸,保存人脸特征信息
// String name = FileUtils.createFile(this) + “/test.png”;
// int type = mFaceDetection.faceDetectionSaveInfo(name, mFaceBitmap);
ArchTaskExecutor.getIOThreadExecutor().execute(() -> {
Bitmap bitmap = FileUtils.decodeToBitMap(data, camera);
boolean haveFace = mFaceDetection.faceDetection(bitmap);
runOnUiThread(() -> {
((AppCompatImageView) findViewById(R.id.tv_img)).setImageBitmap(bitmap);
});
if (haveFace) {
double similarity = mFaceDetection.histogramMatch(mFaceBitmap, bitmap);
String str = “对比度:”;
runOnUiThread(() -> {
mTextView.setText(str + similarity);
});
}
});
});
}
}
如果你进阶的路上缺乏方向,可以加入我们的圈子和安卓开发者们一起学习交流!
Android进阶学习全套手册
Android对标阿里P7学习视频
BATJ大厂Android高频面试题
最后,借用我最喜欢的乔布斯语录,作为本文的结尾:
人这一辈子没法做太多的事情,所以每一件都要做得精彩绝伦。
你的时间有限,所以不要为别人而活。不要被教条所限,不要活在别人的观念里。不要让别人的意见左右自己内心的声音。
最重要的是,勇敢的去追随自己的心灵和直觉,只有自己的心灵和直觉才知道你自己的真实想法,其他一切都是次要。
{
Bitmap bitmap = FileUtils.decodeToBitMap(data, camera);
boolean haveFace = mFaceDetection.faceDetection(bitmap);
runOnUiThread(() -> {
((AppCompatImageView) findViewById(R.id.tv_img)).setImageBitmap(bitmap);
});
if (haveFace) {
double similarity = mFaceDetection.histogramMatch(mFaceBitmap, bitmap);
String str = “对比度:”;
runOnUiThread(() -> {
mTextView.setText(str + similarity);
});
}
});
});
}
}
如果你进阶的路上缺乏方向,可以加入我们的圈子和安卓开发者们一起学习交流!
Android进阶学习全套手册
[外链图片转存中…(img-KAwxGl2y-1650260062463)]
Android对标阿里P7学习视频
[外链图片转存中…(img-rlhheYSe-1650260062464)]
BATJ大厂Android高频面试题
[外链图片转存中…(img-oGYFTJqY-1650260062464)]
最后,借用我最喜欢的乔布斯语录,作为本文的结尾:
人这一辈子没法做太多的事情,所以每一件都要做得精彩绝伦。
你的时间有限,所以不要为别人而活。不要被教条所限,不要活在别人的观念里。不要让别人的意见左右自己内心的声音。
最重要的是,勇敢的去追随自己的心灵和直觉,只有自己的心灵和直觉才知道你自己的真实想法,其他一切都是次要。
android opencv NDK人脸识别和对比相关推荐
- android opencv单机版人脸识别+比对
原理: 通过android 系统自带的谷歌人脸识别获取响应的图片,保存在本地,然后跟先前的照片作比较,相似度大于0.8可以算为同一个人 java 部分代码: public class FaceRecA ...
- Android离线人脸识别方案对比
Android 离线人脸识别方案对比总结 文章目录 Android 离线人脸识别方案对比总结 百度.腾讯.阿里.Face++.商汤等人脸识别 虹软人脸识别 OpenCV 人脸识别 中科视拓(Seeta ...
- android ndk人脸识别,NDK开发-实现支付宝人脸识别功能
1.下载 首先先去官网 https://opencv.org/opencv-3-2.html 下载 Android SDK: sourceforge ,下载下来以后我们的开发方式目前有两种:一种是基于 ...
- Android之OpenCv简单人脸识别功能(Bitmap)
Android之OpenCv简单人脸识别功能 OpenCv的下载 下载地址 - https://opencv.org/releases/ doc 文档目录 samples 示例代码 sdk 编译后的动 ...
- 基于Android端的照片比对系统,基于Android系统的人脸识别系统
[文章摘要] 当前随着基于Android系统的移动终端设备的广泛应用,以及图像采集设备的普遍集成,使得Android系统的图像采集设备除了具有照相.摄像功能以外,正在扩展新的实用型功能.其中,利用An ...
- 人脸识别4:Android InsightFace实现人脸识别Face Recognition(含源码)
人脸识别4:Android InsightFace实现人脸识别Face Recognition(含源码) 目录 人脸识别4:Android InsightFace实现人脸识别Face Recognit ...
- Java借助OpenCV实现人脸识别登录完整示例
Java借助OpenCV实现人脸识别登录完整示例 OpenCV 效果预览 概述 下载与安装 目录说明 OpenCV的基本使用 项目集成 图片人脸检测 人脸对比相似度 识别视频中的人脸 摄像头识别人脸 ...
- Android园区部队人脸识别源码门禁项目讲解
Android园区部队人脸识别源码门禁项目讲解 这边搞人脸识别相关项目有一段时间,今天抽时间讲述一个经典的人脸识别项目:部队人脸识别门禁系统. 大家都知道部队对人员管理安全要求是相当高的,很多保密的技 ...
- 怎样使用OpenCV进行人脸识别
不断维护的地址:http://plzcoding.com/face-recognition-with-opencv/ 怎样使用OpenCV进行人脸识别 本文大部分来自OpenCV官网上的Face Re ...
最新文章
- 手写识别python_Python徒手实现识别手写数字—图像识别算法(K最近邻)
- 解决TensorBoard训练集和测试集指标只能分开显示的问题(基于Keras)
- 一文搞懂 Prometheus 的直方图
- 腾讯云EMR基于YARN针对云原生容器化的优化与实践
- windows下buildbot 的搭建及config文件讲解
- Spring MVC:表单处理卷。 5 –选择,选项,选项标签
- 【Vegas2008】7月19日-凉粉的做法
- 黑客SQL服务器入侵实战演习
- Bamboo 0.2.11 发布,HAProxy 自动配置
- Python【每日一问】27
- solidword入门使用
- HTTP性能测试工具siege
- 超全面UI基础设计规范
- 超全汇总 | 基于Camera的3D目标检测算法综述!(单目/双目/伪激光雷达)
- R语言dplyr包bind_cols函数把两个dataframe数据的列横向合并起来、最终列数为原来两个dataframe列数的加和(Combine Data Frames)
- 函数的 smoothness 和 convexity
- Mac如何创建自签名证书?Mac创建自签名证书图文教程
- 双机(51单片机)串行通信最基本的方法
- Python|判断字符串是否符合日期要求
- 实用软件测试技术与持续质量改进方法 培训课程