又快又好,行人检测和人脸检测和人脸关键点检测(C++/Android源码)

Posted pan_jinquan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了又快又好,行人检测和人脸检测和人脸关键点检测(C++/Android源码)相关的知识,希望对你有一定的参考价值。

又快又好,行人检测(人体检测)和人脸检测和人脸关键点检测(C++/android

目录

又快又好,行人检测(人体检测)和人脸检测和人脸关键点检测(C++/Android)

1.前言

2.项目说明

(1)数据集

(2)模型训练

(3)依赖库

3. JNI接口

4. 人脸人体检测效果展示

5.源码下载

6.人体关键点Demo(Android版本)


1.前言

考虑到人脸人体检测的需求,本人开发了一套轻量化的,高精度的,可实时的人脸/人体检测Android Demo,主要支持功能如下:

  1. 支持人脸检测算法模型
  2. 支持人脸检测和人脸关键点检测(5个人脸关键点)算法模型
  3. 支持人体检测(行人检测)算法模型
  4. 支持人脸和人体同时检测算法模型

所有算法模型都使用C++开发,推理框架采用TNN,Android通过JNI接口进行算法调用;所有算法模型都可在普通Android手机实时跑,在普通Android手机,CPU和GPU都可以达到实时检测的效果(CPU约25毫秒左右,GPU约15毫秒左右)

先看一些效果:

人脸关键点检测人体检测人脸+人体检测

Android Demo APP免费体检:

链接: https://download.csdn.net/download/guyuealian/25924076

Android Demo APP源码下载地址:

实时人体检测和人脸检测和人脸关键点检测(C++/Android)

尊重原创,转载请注明出处https://panjinquan.blog.csdn.net/article/details/125348189

2.项目说明

(1)数据集

人脸人体的数据都来源于网上开源的数据集,其中把WiderFace数据集作为人脸检测和人脸关键点检测的训练数据集;使用COCO的数据集person标签作为人体检测训练的数据

数据集数据说明
WiderFace

WIDER FACE数据集是人脸检测的一个benchmark数据集,包含32203图像,以及393,703个标注人脸,其中,158,989个标注人脸位于训练集,39,496个位于验证集。每一个子集都包含3个级别的检测难度:Easy,Medium,Hard。这些人脸在尺度,姿态,光照、表情、遮挡方面都有很大的变化范围

下载地址:Download - Data Decorators/WIDER FACE | 格物钛,非结构化数据平台

COCO

COCO数据集是一个可用于图像检测(image detection),语义分割(semantic segmentation)和图像标题生成(image captioning)的大规模数据集。它有超过330K张图像(其中220K张是有标注的图像),包含150万个目标,80个目标类别(object categories:行人、汽车、大象等),91种材料类别(stuff categoris:草、墙、天空等),每张图像包含五句图像的语句描述,且有250,000个带关键点标注的行人。

(2)模型训练

训练代码请参考:https://github.com/Linzaer/Ultra-Light-Fast-Generic-Face-Detector-1MB ,一个基于SSD简化的人脸检测模型,很轻量化,整个模型仅仅1.7M左右,在普通Android手机都可以实时检测。

原始代码使用WiderFace人脸数据集进行训练,仅支持了人脸检测,后经鄙人优化后,提高了人脸检测效果,并支持人脸关键点检测,人体检测。数据集是WiderFace,VOC和COCO。

(3)依赖库

# pull 3rdparty(TNN,base-utils) submodule
git submodule init
git submodule update
  • 配置OpenCV

推荐opencv-4.3.0

mkdir build
cd build
cmake -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=/usr/local ..
sudo make install
  • 配置OpenCL(可选)

Android系统一般都支持OpenCL,Linux系统可参考如下配置:

# 参考安装OpenCL: https://blog.csdn.net/qq_28483731/article/details/68235383,作为测试,安装`intel cpu版本的OpenCL`即可
# 安装clinfo,clinfo是一个显示OpenCL平台和设备的软件
sudo apt-get install clinfo
# 安装依赖
sudo apt install dkms xz-utils openssl libnuma1 libpciaccess0 bc curl libssl-dev lsb-core libicu-dev
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
echo "deb http://download.mono-project.com/repo/debian wheezy main" | sudo tee /etc/apt/sources.list.d/mono-xamarin.list
sudo apt-get update
sudo apt-get install mono-complete
# 在intel官网上下载了intel SDK的tgz文件,并且解压
sudo sh install.sh
  • CMake配置说明

Linux OR Windows测试,CMakeLists.txt

# TNN set
    set(TNN_OPENCL_ENABLE ON CACHE BOOL "" FORCE)
    set(TNN_CPU_ENABLE ON CACHE BOOL "" FORCE)
    set(TNN_X86_ENABLE ON CACHE BOOL "" FORCE)
    set(TNN_QUANTIZATION_ENABLE OFF CACHE BOOL "" FORCE)
    set(TNN_OPENMP_ENABLE ON CACHE BOOL "" FORCE)  # Multi-Thread
    add_definitions(-DTNN_OPENCL_ENABLE)           # for OpenCL GPU
    add_definitions(-DDEBUG_ON)                    # for WIN/Linux Log
    add_definitions(-DDEBUG_LOG_ON)                # for WIN/Linux Log
    add_definitions(-DDEBUG_IMSHOW_OFF)            # for OpenCV show
    add_definitions(-DPLATFORM_LINUX)
    # add_definitions(-DPLATFORM_WINDOWS)

3. C++/Java接口

所有算法模型都使用C++开发,推理框架采用TNN,Android通过JNI接口进行算法调用

 Java接口:

package com.cv.tnn.model;

import android.graphics.Bitmap;

public class Detector 

    static 
        System.loadLibrary("tnn_wrapper");
    


    /***
     * 初始化关键点检测模型
     * @param proto: TNN *.tnnproto文件文件名(含后缀名)
     * @param model: TNN *.tnnmodel文件文件名(含后缀名)
     * @param root:模型文件的根目录,放在assets文件夹下
     * @param model_type:模型类型
     * @param num_thread:开启线程数
     * @param useGPU:关键点的置信度,小于值的坐标会置-1
     */
    public static native void init(String proto, String model, String root, int model_type, int num_thread, boolean useGPU);

    /***
     * 检测关键点
     * @param bitmap 图像(bitmap),ARGB_8888格式
     * @param score_thresh:置信度阈值
     * @param iou_thresh:  IOU阈值
     * @return
     */
    public static native FrameInfo[] detect(Bitmap bitmap, float score_thresh, float iou_thresh);

 C++ JNI接口

#include <jni.h>
#include <string>
#include <fstream>
#include "src/object_detection.h"
#include "src/Types.h"
#include "debug.h"
#include "android_utils.h"
#include "opencv2/opencv.hpp"

using namespace vision;

static ObjectDetection *detector = nullptr;


JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved) 
    return JNI_VERSION_1_6;


JNIEXPORT void JNI_OnUnload(JavaVM *vm, void *reserved) 




extern "C"
JNIEXPORT void JNICALL
Java_com_cv_tnn_model_Detector_init(JNIEnv *env,
                                    jclass clazz,
                                    jstring proto,
                                    jstring model,
                                    jstring root,
                                    jint model_type,
                                    jint num_thread,
                                    jboolean use_gpu) 
    if (detector != nullptr) 
        delete detector;
        detector = nullptr;
    
    std::string parent = env->GetStringUTFChars(root, 0);
    std::string proto_file = parent + env->GetStringUTFChars(proto, 0);
    std::string model_file = parent + env->GetStringUTFChars(model, 0);
    DeviceType device = use_gpu ? GPU : CPU;
    LOGW("parent     : %s", parent.c_str());
    LOGW("useGPU     : %d", use_gpu);
    LOGW("device_type: %d", device);
    LOGW("model_type : %d", model_type);
    LOGW("num_thread : %d", num_thread);
    ObjectDetectiobParam model_param = MODEL_TYPE[model_type];//模型参数
    detector = new ObjectDetection(model_file,
                                   proto_file,
                                   model_param,
                                   num_thread,
                                   device);



extern "C"
JNIEXPORT jobjectArray JNICALL
Java_com_cv_tnn_model_Detector_detect(JNIEnv *env, jclass clazz, jobject bitmap,
                                      jfloat score_thresh, jfloat iou_thresh) 
    cv::Mat bgr;
    BitmapToMatrix(env, bitmap, bgr);
    int src_h = bgr.rows;
    int src_w = bgr.cols;
    // 检测区域为整张图片的大小
    FrameInfo resultInfo;
    // 开始检测
    if (detector!= nullptr)
        detector->detect(bgr, &resultInfo, score_thresh, iou_thresh);
    
    else
        ObjectInfo objectInfo;
        objectInfo.x1=0;
        objectInfo.y1=0;
        objectInfo.x2=84;
        objectInfo.y2=84;
        objectInfo.label=0;
        resultInfo.info.push_back(objectInfo);
    

    int nums = resultInfo.info.size();
    LOGW("object nums: %d\\n", nums);

    auto BoxInfo = env->FindClass("com/cv/tnn/model/FrameInfo");
    auto init_id = env->GetMethodID(BoxInfo, "<init>", "()V");
    auto box_id = env->GetMethodID(BoxInfo, "addBox", "(FFFFIF)V");
    auto ky_id = env->GetMethodID(BoxInfo, "addKeyPoint", "(FFF)V");
    jobjectArray ret = env->NewObjectArray(resultInfo.info.size(), BoxInfo, nullptr);
    for (int i = 0; i < nums; ++i) 
        auto info = resultInfo.info[i];
        env->PushLocalFrame(1);
        //jobject obj = env->AllocObject(BoxInfo);
        jobject obj = env->NewObject(BoxInfo, init_id);
        // set bbox
        //LOGW("rect:[%f,%f,%f,%f] label:%d,score:%f \\n", info.rect.x,info.rect.y, info.rect.w, info.rect.h, 0, 1.0f);
        env->CallVoidMethod(obj, box_id, info.x1, info.y1, info.x2 - info.x1, info.y2 - info.y1,
                            info.label, info.score);
        // set keypoint
        for (const auto &kps : info.landmarks) 
            //LOGW("point:[%f,%f] score:%f \\n", lm.point.x, lm.point.y, lm.score);
            env->CallVoidMethod(obj, ky_id, (float) kps.x, (float) kps.y, 1.0f);
        
        obj = env->PopLocalFrame(obj);
        env->SetObjectArrayElement(ret, i, obj);
    
    return ret;



4. 人脸人体检测效果展示

在普通Android手机上,CPU和GPU都可以达到实时检测(CPU约25毫秒左右,GPU约15毫秒左右), 下面是APP的检测效果,你可下载Android Demo APP真实体检一下哦~

APP模型选择人脸检测
人脸关键点检测人体检测人脸+人体检测

5.Demo源码下载

Android Demo APP免费体检:

链接: https://download.csdn.net/download/guyuealian/25924076

Android Demo APP源码下载地址:

实时人体检测和人脸检测和人脸关键点检测(C++/Android)

6.人体关键点Demo(Android版本)

本项目Demo支持人脸关键点检测(5个人脸关键点),如果你需要人体关键点检测,请查看鄙人另一篇博客:2D Pose人体关键点实时检测(Python/Android /C++ Demo)_pan_jinquan的博客-CSDN博客

以上是关于又快又好,行人检测和人脸检测和人脸关键点检测(C++/Android源码)的主要内容,如果未能解决你的问题,请参考以下文章

夜间(低光照)目标检测数据集整理:人脸检测,行人检测

人脸检测+人体检测C++ Android实现

人脸检测+人体检测C++ Android实现

学习OpenCV——行人检测&人脸检测(总算运行出来了)

CSP:Object as Point同会议论文,相似思想用于人脸和行人检测 | CVPR 2019

opencv 是怎么实现人脸检测的