java调用海康人脸识别比对demo(附demo源码下载)

之前已经写了个简单的,但是觉得可能有些人第一次使用会遇到大麻烦,所以写完整一点。
首先要明白 我们用JAVA代码去操控硬件是有两条路线走的,
第一条:联网方式,根据硬件厂家提供的SDK进行初始化、输入账号、密码进行连接。
第二条:用设备直接连接,如USB,这个就需要用到串口COMM编程了。
刚好两个我都在公司的项目上遇到过,所以就稍微懂了一点,但是仅仅是入门使用而已。
好了,接下来我们就开始回到题目了

  • **

思路概述:

**

引入海康的SDK中有个HCNetSDK.java,里面定义了很多很多东西,包括人脸对别。
那么我们需要人脸对比就写一个类去实现它里面定义的人脸比对的接口(它没明说是人脸比对,是通过报警回调函数中的黑名单报警这个接口去实现人脸比对的),
简单来说就是写个类去实现HCNetSDK.FMSGCallBack 然后根据条件函数 case HCNetSDK.COMM_SNAP_MATCH_ALARM(人脸对别的黑名单): 去操作我们需要的步骤。
然后除此之外,你引用人家的类 少不了进行类的初始化操作、账号和密码的设定,IP地址的绑定等这些步骤

步骤如下:

1.去海康官网下载最新的SDK 官网地址:https://www.hikvision.com/cn/
在这里插入图片描述
2.下载好了之后创建maven项目,
按照SDK里面的文档要求把下图文件夹和文件引入(在SDK库文件夹里),
7个dll文件和一个KCNetSDK文件夹(我这里创建了一个HCNetSDK的文件夹装下这些)
在这里插入图片描述
3.接下来把他的接口类引入 如下在这里插入图片描述
打开接口类 看33行 这里有个引入dll文件的代码

我这里是用的文件引入工具类(这个类后面有给出),你们自己换成目录
resources\HCNetSDK\HCNetSDK的绝对路径!!!!
其实这里引入的就是我们引入的7个dll文件中的HCNetSDK.dll这个文件,这里绝对路径引入的时候不要.dll后缀名。在这里插入图片描述
文件也引入了 接下来就是我们自己创建java类去调用它的接口类了
创建两个类 一个是报警回调函数的实现类(用来实现调用海康人脸比对)
一个是主类 里面包含 初始化海康接口类、调用第一个函数实现人脸对比等等

第一个类

/**
 * 报警回调函数中接收和处理数据
 */
@Controller
public class FMSGCallBackController implements HCNetSDK.FMSGCallBack {

    //报警信息回调函数
    public void invoke(int lCommand, HCNetSDK.NET_DVR_ALARMER pAlarmer, Pointer pAlarmInfo, int dwBufLen, Pointer pUser) {
        try {
            String sAlarmType = new String();
            String[] newRow = new String[3];
            //报警时间
            Date today = new Date();
            DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");
            String[] sIP = new String[2];

            sAlarmType = new String("lCommand=") + lCommand;
            //lCommand是传的报警类型
            switch (lCommand) {
                case HCNetSDK.COMM_SNAP_MATCH_ALARM: //人脸黑名单比对报警
                    HCNetSDK.NET_VCA_FACESNAP_MATCH_ALARM strFaceSnapMatch = new HCNetSDK.NET_VCA_FACESNAP_MATCH_ALARM();
                    strFaceSnapMatch.write();
                    Pointer pFaceSnapMatch = strFaceSnapMatch.getPointer();
                    pFaceSnapMatch.write(0, pAlarmInfo.getByteArray(0, strFaceSnapMatch.size()), 0, strFaceSnapMatch.size());
                    strFaceSnapMatch.read();



                    sAlarmType = sAlarmType + ":人脸黑名单比对报警,相识度:" + strFaceSnapMatch.fSimilarity + ",黑名单姓名:" +
                            new String(strFaceSnapMatch.struBlackListInfo.struBlackListInfo.struAttribute.byName, "GBK").trim() + ",黑名单证件信息:" +
                            new String(strFaceSnapMatch.struBlackListInfo.struBlackListInfo.struAttribute.byCertificateNumber).trim();

                //人脸相似度
                float fSimilarity = strFaceSnapMatch.fSimilarity;
                
			//********************************从这里开始 这里是我们自己操作的内容 里面的QueryInsertAlarmInformationService 换成你自己定义要干嘛的service就行
                //员工姓名
                String employeeName = new String(strFaceSnapMatch.struBlackListInfo.struBlackListInfo.struAttribute.byName, "GBK").trim();
                //报警时间
                String alarmTime = dateFormat.format(today);
                //如果识别的人名不为空则进行数据库操作
                if(null !=employeeName && !"".equals(employeeName)){
                    //根据姓名进行数据库匹配
                    QueryInsertAlarmInformationService queryInsertAlarmInformation = new QueryInsertAlarmInformationService();
                    //查询出用户USERID
                    String userID = queryInsertAlarmInformation.QueryUserIdByDepartAndName(employeeName);
                    //将数据保存到数据库
                    if(null!=userID && !"".equals(userID)){
                        queryInsertAlarmInformation.InsertAttAllEvent(userID,alarmTime);
                    }
                }
              //****************************自己操作的部分结束  
              
                newRow[0] = dateFormat.format(today);
                //报警类型
                newRow[1] = sAlarmType;
                //报警设备IP地址
                sIP = new String(pAlarmer.sDeviceIP).split("\0", 2);
                newRow[2] = sIP[0];
                System.out.println("人脸比对结果: "+employeeName+"   "+alarmTime);
               //System.out.println("这是人脸比对报警信息:" + "报警时间:" + dateFormat.format(today) + "\r\n" + "报警类型:" + sAlarmType + "\r\n" + "报警设备IP:" + sIP[0]);
                break;
            default:
                newRow[0] = dateFormat.format(today);
                //报警类型
                newRow[1] = sAlarmType;
                //报警设备IP地址
                sIP = new String(pAlarmer.sDeviceIP).split("\0", 2);
                newRow[2] = sIP[0];
                //System.out.println("这是人脸比对报警信息:"+"报警时间:"+dateFormat.format(today)+"\r\n"+"报警类型:"+sAlarmType+"\r\n"+"报警设备IP:"+sIP);
                break;
        }
    } catch (UnsupportedEncodingException ex) {
        Logger.getLogger(FaceCompareAlarmInfoController.class.getName()).log(Level.SEVERE, null, ex);
    }
}
}

QueryInsertAlarmInformationService 类 这个换成你自己定义的service

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;

/**
 * 对数据库逻辑的处理
 */
public class QueryInsertAlarmInformationService {

    public static Connection conn = null;
    public static PreparedStatement ps = null;
    public static ResultSet rs = null;

    /**
     * 向AttAllEvent中插入数据
     *
     * @param UserID
     * @param EventTime
     */
    public void InsertAttAllEvent(String UserID, String EventTime) {
        String eventType = "刷卡";
        Integer doorType = 0;
        try {
            //连接数据库
            conn = DataBaseConnectionUtil.getConnection();
            String sql = "insert into AttAllEvent (UserID,EventTime,EventType,DoorType) values(?,?,?,?)";
            ps = conn.prepareStatement(sql);
            ps.setString(1, UserID);
            ps.setString(2, EventTime);
            ps.setString(3, eventType);
            ps.setInt(4, doorType);
            // 执行sql语句
            ps.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            // 关闭数据库连接对象
            DataBaseConnectionUtil.close2(ps, conn);
        }
    }

    /**
     * 查询出所有部门的员工姓名和部门拼接
     */
    public  Map<String, String> QueryDepartNameAndEmployeeName() {
        Map<String, String> departName = new HashMap<>();
        try {
            conn = DataBaseConnectionUtil.getConnection();
            String sql = "SELECT  Department+Name as DName ,UserID FROM  AttUser;";
            ps = conn.prepareStatement(sql);
            rs = ps.executeQuery();

            while (rs.next()) {
                String dName = rs.getString("DName");
                String userID = rs.getString("UserID");
                departName.put(rs.getString("DName"), rs.getString("UserID"));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            // 关闭数据库连接对象
            DataBaseConnectionUtil.close(rs, ps, conn);
        }
        return departName;
    }

    /**
     * 查询出用户id
     * @param departUserName
     * @return
     */
    public  String QueryUserIdByDepartAndName( String departUserName) {
        Map<String, String> map = QueryDepartNameAndEmployeeName();
        for(Map.Entry<String, String> entry : map.entrySet()){
            String mapKey = entry.getKey();
            String mapValue = entry.getValue();
            //判断用户名和部门名是否匹配设备上传过来的
            if (departUserName.equals(mapKey)){
                return mapValue;
            }
        }
        return "";
    }
}

DataBaseConnectionUtil 数据库连接类 我们直接用的是JDBC连接数据库操作的 如果采用springboot或者其他框架整合了mybatis数据库框架的话可以节省这一步

import java.sql.*;

/**
 * 数据库连接工具类
 */
public class DataBaseConnectionUtil {
    // 连接驱动 这里连接的是sqlserver mysql的请更换
    private static final String DRIVERCLASSNAME= "com.microsoft.sqlserver.jdbc.SQLServerDriver"; 
    // 连接路径 
    private static final String URL = "jdbc:sqlserver://localhost:1433;DatabaseName=XXX";
    // 数据库用户名
    private static final String USERNAME = "sa";
    //  数据库密码
    private static final String PASSWORD = "123456";

    //静态代码块
    static {
        try {
            // 加载驱动
            Class.forName(DRIVERCLASSNAME);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    /*
     * 获取数据库连接
     */
    public static Connection getConnection() {
        Connection conn = null;
        try{
            conn= DriverManager.getConnection(URL, USERNAME, PASSWORD);
        }catch(SQLException e){
            e.printStackTrace();

        }
        return conn;
    }

    /*
     * 关闭数据库连接,释放资源
     */
    public static void close(ResultSet rs, PreparedStatement ps, Connection conn) {
        if(rs!=null){
            try{
                rs.close();
                rs=null;
            }catch(SQLException e){
                e.printStackTrace();
            }
        }
        if(ps!=null){
            try{
                ps.close();
                ps=null;
            }catch(SQLException e){
                e.printStackTrace();
            }
        }
        if(conn!=null){
            try{
                conn.close();
                conn=null;
            }catch(SQLException e){
                e.printStackTrace();
            }
        }
    }
    /*
     * 关闭数据库连接,释放资源
     */
    public static void close2( PreparedStatement ps, Connection conn) {
        if(ps!=null){
            try{
                ps.close();
                ps=null;
            }catch(SQLException e){
                e.printStackTrace();
            }
        }
        if(conn!=null){
            try{
                conn.close();
                conn=null;
            }catch(SQLException e){
                e.printStackTrace();
            }
        }
    }
}

主类:

**

@Controller
public class FaceCompareAlarmInfoController {

    HCNetSDK hCNetSDK = HCNetSDK.INSTANCE;
    //设备信息
    HCNetSDK.NET_DVR_DEVICEINFO_V30 m_strDeviceInfo;
    //已登录设备的IP地址
    String m_sDeviceIP;
    //用户句柄
    NativeLong lUserID;
    //报警布防句柄
NativeLong lAlarmHandle;
//报警监听句柄
NativeLong lListenHandle;
//报警回调函数实现
FMSGCallBackController fMSFCallBack;

public FaceCompareAlarmInfoController() {
    this.initInformation();
}

/**
 * 初始化信息
 */
public void initInformation() {
    //初始化的参数
    lUserID = new NativeLong(-1);
    lAlarmHandle = new NativeLong(-1);
    lListenHandle = new NativeLong(-1);
    fMSFCallBack = null;
    //注册
    Boolean login = this.Login();
    if (login){
        //注册成功就进行布防
        this.SetupAlarmChan();
        while (true) ;
    }
}


/**
 * 用户注册
 *
 * @return
 */
public Boolean Login() {
    //初始化
    HCNetSDK hCNetSDK = HCNetSDK.INSTANCE;
    boolean initSuc = hCNetSDK.NET_DVR_Init();
    if (initSuc != true) {
        System.out.println("初始化失败"+ "  失败原因是:" + hCNetSDK.NET_DVR_GetLastError());
    } else {
        System.out.println("接口初始化成功");
    }
    m_sDeviceIP = HCNetDeviceConUtil.m_sDeviceIP;
    m_strDeviceInfo = new HCNetSDK.NET_DVR_DEVICEINFO_V30();
    int iPort = HCNetDeviceConUtil.PORT;
    lUserID = hCNetSDK.NET_DVR_Login_V30(m_sDeviceIP,
            (short) iPort, HCNetDeviceConUtil.USERNAME, HCNetDeviceConUtil.PASSWORD, m_strDeviceInfo);
    long userID = lUserID.longValue();
    if (userID == -1) {
        System.out.println("注册失败" + "  失败原因是:" + hCNetSDK.NET_DVR_GetLastError());
        return false;
    } else {
        System.out.println("注册成功");
        return true;
    }
}

/**
 * 报警布防
 */
public void SetupAlarmChan() {
    if (fMSFCallBack == null) {
        fMSFCallBack = new FMSGCallBackController();
        Pointer pUser = null;
        if (!hCNetSDK.NET_DVR_SetDVRMessageCallBack_V30(fMSFCallBack, pUser)) {
            System.out.println("设置回调函数失败!"+ "  失败原因是:" + hCNetSDK.NET_DVR_GetLastError());
        }
    }
    HCNetSDK.NET_DVR_SETUPALARM_PARAM m_strAlarmInfo = new HCNetSDK.NET_DVR_SETUPALARM_PARAM();
    m_strAlarmInfo.dwSize = m_strAlarmInfo.size();
    m_strAlarmInfo.byLevel = 1;
    m_strAlarmInfo.byAlarmInfoType = 1;
    m_strAlarmInfo.write();
    lAlarmHandle = hCNetSDK.NET_DVR_SetupAlarmChan_V41(lUserID, m_strAlarmInfo);
    if (lAlarmHandle.intValue() == -1) {
        System.out.println("布放失败" + "  失败原因是:" + hCNetSDK.NET_DVR_GetLastError());
    } else {
        System.out.println("布防成功");
    }
    }
}

HCNetDeviceConUtil 账号和密码工具类

import java.io.UnsupportedEncodingException;

/**
 * 海康设备账号和密码
 */
public class HCNetDeviceConUtil {

    // 登录IP
    public static final String m_sDeviceIP = "登录IP";	//(登录IP 例如 192.168.0.1,它可以用来组网,可以在海康后台组建由这个ip控制的某几个海康摄像头)
    // 登录名
    public static final String USERNAME = "账号"; //(例如 admin)
    // 密码
    public static final String PASSWORD = "密码"; //(例如 123456)
	    //设备端口号
		    public static final Integer PORT = 8000;
		    //加载海康HCNetSDK.dll文件的路径
		    public static final String loadLibrary=HCNetSDKPath.DLL_PATH;
		
		    public static class HCNetSDKPath {
		        public static String DLL_PATH;
	/*下面这个是加载dll文件的 ,也就是上面的第3步(做了第3步可以不要这个static里面的内容,但是用这个把第3步换成工具类加载更加的方便后续的维护,所以我们把第3步的加载路径换成:
	  HCNetSDK INSTANCE = (HCNetSDK) Native.loadLibrary(HCNetDeviceConUtil.loadLibrary,
            HCNetSDK.class);
*/
		       static {
		            String path = (HCNetSDKPath.class.getResource("/HCNetSDK/HCNetSDK.dll").getPath()).replaceAll("%20", " ").substring(1).replace("/",
		                    "\\");
		            try {
		                DLL_PATH = java.net.URLDecoder.decode(path, "utf-8");
		            } catch (UnsupportedEncodingException e) {
		                e.printStackTrace();
		            }
		        }
		    }
		}

源码下载:(下面下载的这个代码和我上面的不一样,但是也是一个完整的人脸比对demo,思路是一样的)
链接:https://pan.baidu.com/s/1QenBYOZO8HGXIgaoTtmvAw
提取码:fkjj

  • 11
    点赞
  • 61
    收藏
    觉得还不错? 一键收藏
  • 43
    评论
Java对接海康人脸识别可以通过以下步骤完成: 1. 导入海康人脸识别Java SDK:首先,下载并导入海康人脸识别Java SDK,包括相应的jar文件和依赖的库文件。 2. 配置SDK和连接设备:在代码中,配置SDK的相关参数,例如设备的IP地址、端口号、用户名和密码等。通过这些参数,建立与海康设备的连接。 3. 创建人脸识别服务:使用SDK提供的API,创建人脸识别服务对象。这个对象负责与海康设备进行通信,包括发送指令、接收数据等操作。 4. 初始化服务:在服务对象中进行初始化操作,例如连接设备、设置图片上传、启用实时人脸检测等。这些初始化操作可以根据实际需求进行配置。 5. 进行人脸识别调用相应的API进行人脸识别操作。例如,通过实时视频流或者上传的图片进行人脸检测、抓拍、比对等操作。可以设置相应的回调函数来获取识别结果。 6. 处理识别结果:根据识别结果进行相应的业务逻辑处理。识别结果可以包括人脸检测信息、人脸角度、人脸特征值等。根据实际需求,可以进行敏感数据的隐私保护。 7. 关闭服务和断开连接:在程序结束或者不再需要人脸识别服务时,关闭服务对象,断开与设备的连接。 通过以上步骤,可以完成Java对接海康人脸识别的操作。具体的代码实现要根据海康提供的SDK文档进行编写和调试。当然,在实际应用中,还需要考虑异常处理、性能优化等因素。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 43
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值