ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

基于RTSP视频流的Java后台服务端虹软人脸识别

2020-12-07 16:29:58  阅读:269  来源: 互联网

标签:人脸识别 Java 虹软 视频流 jar init grabber error logger


1 概述
      人脸识别技术是随着技术发展而产生的生物识别技术,目前已广泛应用于安防领域,主要用于身份验证和身份识别。视频监控是安防系统常见的一种表现形式,需要部署各种摄像头,包括网络摄像头IPC,可以通过流媒体如RTSP视频流的方式供第三方系统集成。
      虹软是计算机视觉行业领先的算法服务提供商及解决方案供应商,提供免费、离线的人脸识别SDK,主要包含人脸检测、性别检测、年龄检测、人脸识别、图像质量检测、RGB活体检测、IR活体检测等能力。支持主流Windows、Linux、Android、iOS等平台及Java、C++等开发语言。
      本文基于虹软免费人脸识别SDK,从IPC提供的RTSP视频流抓帧进行人脸识别。主要技术方案是通过JavaCV定时抓取视频帧保存为图像,然后针对图像通过虹软SDK提取特征,同特征库里面的人脸进行比较,超过设定的阈值就认为识别到。

2 项目环境
介绍项目中主要使用到的开发库及开发工具。

  1. 虹软人脸识别SDK。提供人脸识别相关开发接口。本文使用Windows X64 Java版本,ArcSoft_ArcFace_Java_Windows_x64_V3.0。

下载地址:虹软官网开发者中心(https://ai.arcsoft.com.cn)。

  1. JavaCV。是一款基于JavaCPP调用方式(JNI的一层封装),提供了在计算机视觉领域的封装库,封装了包含FFmpeg、OpenCV、tensorflow、caffe、tesseract、libdc1394、OpenKinect、videoInput和ARToolKitPlus等在内的计算机视觉领域的常用库和实用程序类。本文使用javacv-platform-1.5.1-bin版本。

下载地址:github(https://github.com/bytedeco/javacv)。也可以通过Maven的方式下载必要的jar包。

  1. Eclipse。一个开放源代码的、基于Java的可扩展开发平台。用于Java项目的工程化组织。本文使用Oxygen Release (4.7.0)。

下载地址:Eclipse官网(https://www.eclipse.org/downloads/)

  1. JDK。提供Java开发环境。本文使用jdk-8u181-windows-x64版本。

下载地址:Oracle官网(https://www.oracle.com/java/)

3 整体流程

整体流程包括各种初始化,启动RTSP视频流监测线程,启动人脸识别任务,如下图所示:
在这里插入图片描述
4 工程概况

创建一个常规的Java项目,引入必要的第三方jar包。

  1. 引入虹软人脸识别jar包。

arcsoft-sdk-face-3.0.0.0.jar

  1. 引入JavaCV必要的jar包。

artoolkitplus.jar

ffmpeg.jar

ffmpeg-windows-x86_64.jar

flandmark.jar

flycapture.jar

javacpp.jar

javacv.jar

leptonica.jar

libdc1394.jar

libfreenect.jar

libfreenect2.jar

librealsense.jar

openblas.jar

opencv.jar

tesseract.jar

videoinput.jar

  1. 引入log4j相关jar包。

slf4j-api-1.7.25.jar

slf4j-log4j12-1.7.25.jar

log4j-1.2.17.jar

Java工程结构如下图所示:
在这里插入图片描述
运行的时候,需要将虹软SDK核心DLL拷到jar包所在目录。

5 效果展示
工程以常规java项目运行,通过日志观察识别效果。打印识比对分值和人脸库的文件名。如下图所示:
在这里插入图片描述
6 核心代码说明
6.1 配置文件

#人脸识别相关参数

config.FaceAppId = 3D9hF3f4uNxgDGRkRr9PD6P7CbuSC1GrPe5dBnxxxxx

config.FaceSdkKey = 2aSheKNE4aMokrkRmn5qJ7kvPirhZM7YpDLx

config.FaceThreshold = 0.75

#人脸库图片所在路径

config.FaceLibPath = d:/facelib/

#rtsp视频流地址

config.RtspUrl = rtsp://192.168.0.100:554/live/camera

#执行任务的线程数量

config.ThreadNum = 16

AppId和SdkKey根据虹软开发者中心实际应用情况配置。配置项通过ConfigMgr类加载。
在这里插入图片描述
6.2 虹软人脸识别接口封装类

      主要对核心方法进行封装,包括初始化、特征提取、特征比对,是对虹软SDK提供的接口进行封装。
在这里插入图片描述
初始化引擎代码:

public static boolean init(String _sAppID, String _sSdkKey)

{

       m_oFaceEngine = new FaceEngine();

       // 引擎激活

       int iFaceActiveCode = m_oFaceEngine.activeOnline(_sAppID, _sSdkKey);

       if (iFaceActiveCode != ErrorInfo.MOK.getValue() &&

                     iFaceActiveCode != ErrorInfo.MERR_ASF_ALREADY_ACTIVATED.getValue())

       {

           logger.error("人脸识别引擎在线激活失败!({})", iFaceActiveCode);

           return false;

    }

       

       // 引擎配置

       EngineConfiguration oEngineConfiguration = new EngineConfiguration();

       oEngineConfiguration.setDetectMode(DetectMode.ASF_DETECT_MODE_IMAGE);

       oEngineConfiguration.setDetectFaceOrientPriority(DetectOrient.ASF_OP_0_ONLY);

       // 功能配置

       FunctionConfiguration oFunctionConfiguration = new FunctionConfiguration();

       oFunctionConfiguration.setSupportFaceDetect(true);

       oFunctionConfiguration.setSupportFaceRecognition(true);

       oFunctionConfiguration.setSupportAge(false);

       oFunctionConfiguration.setSupportGender(false);

       oEngineConfiguration.setFunctionConfiguration(oFunctionConfiguration);

       // 初始化引擎

       int iFaceInitCode = m_oFaceEngine.init(oEngineConfiguration);

       if (iFaceInitCode != ErrorInfo.MOK.getValue())

       {

              logger.error("人脸识别引擎初始化失败!({})", iFaceInitCode);

              return false;

    }

             

    return true;

}
  提取特征代码:

public static FaceFeature getFaceFeature(byte[] _abyImageData)

{

       try

       {

           ImageInfo oImageInfo = ImageFactory.getRGBData(_abyImageData);

           List<FaceInfo> lstFaceInfo = new ArrayList<FaceInfo>();

           int iCode = m_oFaceEngine.detectFaces(oImageInfo.getImageData(), oImageInfo.getWidth(), oImageInfo.getHeight(), ImageFormat.CP_PAF_BGR24, lstFaceInfo);

           if (iCode != ErrorInfo.MOK.getValue())

           {

               logger.error("检测人脸失败({})", iCode);

               return null;

           }

              

           if (lstFaceInfo.isEmpty())

           {

               logger.error("检测人脸为空({})", iCode);

               return null;

           }

      

           FaceFeature oFaceFeature = new FaceFeature();

           iCode = m_oFaceEngine.extractFaceFeature(oImageInfo.getImageData(), oImageInfo.getWidth(), oImageInfo.getHeight(), ImageFormat.CP_PAF_BGR24, lstFaceInfo.get(0), oFaceFeature);

           if (iCode != ErrorInfo.MOK.getValue())

           {

                  logger.error("提取人脸特征失败({})", iCode);

                  return null;

           }

           return oFaceFeature;

       }

       catch (Exception e)

       {

              logger.error(e.getMessage());

              return null;

       }

}

       特征比对代码:

public static float compare(FaceFeature _oFaceFeature1, FaceFeature _oFaceFeature2)

{

       float fSimilarity = 0.0f;

             

       try

       {

           FaceSimilar oFaceSimilar = new FaceSimilar();

           int iCode = m_oFaceEngine.compareFaceFeature(_oFaceFeature1, _oFaceFeature2, oFaceSimilar);

           if (iCode != ErrorInfo.MOK.getValue())

           {

                  logger.error("人脸比对失败({})", iCode);

                  return fSimilarity;

           }

          

           fSimilarity = oFaceSimilar.getScore();

       }

       catch (Exception e)

       {

              logger.error(e.getMessage());

       }

      

       return fSimilarity;

}

6.3 任务调度封装类

     主要是通过JDK提供的线程池ScheduledExecutorService对程序中任务执行进行调度。
在这里插入图片描述
主要代码如下:

private ScheduledExecutorService svc;

private boolean init;

   

private TaskMgr()

{

svc = null;

    init = false;

}

/**

 * 初始化

*/

public void init(int _iThreadNum)

{

svc = Executors.newScheduledThreadPool(_iThreadNum);

    init = true;

}

   

 /**

* 销毁

 */

public void destroy()

{

if (init)

{

           svc.shutdown();

    }

}

 

/**

* 增加一个任务

* @param _task 任务对象,实现Runnable接口

*/

public void pushTask(Runnable _task)

{

svc.schedule(_task, 0, TimeUnit.MILLISECONDS);

}

6.4 人脸库管理封装类

加载指定目录下的图片,提取特征保存到内存中形成人脸库,供1:N识别时进行遍历。
在这里插入图片描述

初始化代码:

public void init(String _faceLibPath)

{

File fileDir = new File(_faceLibPath);

if (fileDir.exists() && fileDir.isDirectory())

{

      String[] children = fileDir.list();

      for (int i = 0; i < children.length; i++)

{

File fileImage = new File(fileDir, children[i]);

FaceFeature faceFeature = ArcfaceApi.getFaceFeature(fileImage);

      if (faceFeature != null)

{

myFaceFeatureList.add(new MyFaceFeature(children[i], faceFeature));

}

}

  }

  

logger.info("face lib size:{}", myFaceFeatureList.size());

}

6.5 RTSP视频流抓帧线程类

该线程启动时一直运行,通过JavaCV定时抓帧,得到的图片启动一个任务提交到线程池,调用人脸库管理封装类进行识别。
在这里插入图片描述

创建帧抓取器

private void createGrabber()

{

       try

       {

              grabber = FFmpegFrameGrabber.createDefault(rtspUrl);

              grabber.setFrameRate(frameRate);

              grabber.setVideoBitrate(bitRate);

              grabber.setImageWidth(frameWidth);

              grabber.setImageHeight(frameHeight);

              grabber.start();

       }

       catch  (Exception e)

       {

              logger.error(e.getMessage());

       }

}

定时抓帧保存为图片格式

private void startGrabber()

{

       Java2DFrameConverter java2DFrameConverter = new Java2DFrameConverter();

 

       while (true)

       {

              if (grabber == null)

              {

                     logger.info("连接rtsp:" + rtspUrl + ",开始创建grabber");

                     createGrabber();

              }

 

              try

              {

                     Frame frame = grabber.grabImage();

                     if (frame != null)

                     {

                            BufferedImage bi = java2DFrameConverter.getBufferedImage(frame);

                            byte[] bytes = imageToBytes(bi, "jpg");

                            if (bytes != null && bytes.length > 0)

                            {

                                   // 人脸检测

                                   TaskMgr.getInstance().pushTask(new FrameHandleTask(bytes));

                            }

                     }

              }

              catch (Exception e)

              {

                     logger.error(e.getMessage());

                           

                     if (grabber != null)

                     {

                            try

                            {

                                   grabber.stop();

                            }

                            catch (FrameGrabber.Exception ex)

                            {

                                   logger.error("grabber stop exception: " + ex.getMessage());

                            }

                            finally

                            {

                                   grabber = null;

                            }

                     }

              }

                    

              try

              {

                     Thread.sleep(100);

              }

              catch (InterruptedException e)

              {

                     logger.error(e.getMessage());

              }

       }

}

6.6 工程启动

   在Main方法中进行初始化,并启动线程。
public class ArcfaceRtspDemo

{

private final static Logger logger = LoggerFactory.getLogger(ArcfaceRtspDemo.class);

      

       public static void main(String[] args)

       {

       // 加载配置文件

       ConfigMgr.getInstance().init();

       // 任务初始化

       TaskMgr.getInstance().init(ConfigMgr.getInstance().getThreadNum());

       // 人脸初始化

       boolean bRet = ArcfaceApi.init(ConfigMgr.getInstance().getFaceAppId(), ConfigMgr.getInstance().getFaceSdkKey());

       if (bRet)

       {

         logger.info("Init Face success");

        MyFaceMgr.getInstance().init(ConfigMgr.getInstance().getFaceLibPath());

       }

       else

       {

              logger.error("Init Face error");

       }

             

       RtspFrameGrabberThread thread = new RtspFrameGrabberThread(ConfigMgr.getInstance().getRtspUrl());

       thread.start();

}

7 结论

本文所介绍的方法,只是提供可行性验证,说明可以通过抓取RTSP视频帧调用虹软SDK进行人脸识别。可以作为商业项目的参考。在实际项目中,可以通过对相关参数的调整达到更好的性能。

8 源码下载

源码包含了完整的第三方库,所以比较大,上传到百度网盘提供下载。

链接:https://pan.baidu.com/s/1f3crf1x_2jq8uMm9DqVcZg

提取码:78jd

了解更多人脸识别产品相关内容请到虹软视觉开放平台

标签:人脸识别,Java,虹软,视频流,jar,init,grabber,error,logger
来源: https://blog.csdn.net/qq_40110356/article/details/110820564

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有