厂家不提供java sdk,网上基本没啥资料,全靠摸索。使用JNA的Structure去映射数据结构,读取的图像数据处理出错,手动从pointer去读,需要根据提供的头文件截取每个数据项的大小。几乎要放弃去考虑用c++了,最终调用成功,还是要坚持。

环境

系统 win7 64
瑞为sdk版本 windows 32

瑞为sdk在win10 没有调用成功,在win7下调用成功。
但win10 下用c++写的能调用成功,百思不得解,也许是java的局限性。

瑞为接口定义

#ifndef _RECONOVA_FACE_CAMERA_SDK_H_
#define _RECONOVA_FACE_CAMERA_SDK_H_

#ifdef WIN32
#ifdef RECONOVAFACECAMERASDK_EXPORTS
#define RECONOVAFACECAMERASDK_API __declspec(dllexport)
#else
#define RECONOVAFACECAMERASDK_API __declspec(dllimport)

#pragma comment(lib, "ReconovaFaceCameraSdk")
#endif
#else
#define RECONOVAFACECAMERASDK_API
#endif

#ifdef __cplusplus
extern "C"
{
#endif

/**
 * 图片信息定义,图片格式BGR24
 */
typedef struct ReconovaBGR24Image_s {
    int            width;                    /* 宽 */
    int            height;                    /* 高 */
    int            widthStep;                /* 步长,四字节对齐 */
    int            imageSize;                /* 图片数据大小 */
    char        *imageData;                /* 图片数据 */
} ReconovaBGR24Image_t;

/**
 * 人脸区域定义,从眉毛到下巴的矩形框
 */
typedef struct ReconovaFaceRectInfo_s {
    int            left;                    /* 左边界值 */
    int            top;                    /* 上边界值 */
    int            right;                    /* 右边界值 */
    int            bottom;                    /* 下边界值 */
} ReconovaFaceRectInfo_t;

/**
 * 人脸特征信息
 */
typedef struct ReconovaFaceFeature_s {
    int            featLength;                /* 特征数据长度 */
    char        *featData;                /* 特征数据 */
} ReconovaFaceFeature_t;

/**
 * 人员跟踪信息
 */
typedef struct ReconovaPersonTraceInfo_s {
    unsigned int personId;                /* 人员ID */
    ReconovaBGR24Image_t frameImage;    /* 当前人脸对应的现场图片 */
    ReconovaFaceRectInfo_t faceRect;    /* 人脸位置 */
    ReconovaBGR24Image_t faceImage;        /* 人脸图片 */
    ReconovaFaceFeature_t faceFeature;    /* 人脸特征信息 */
} ReconovaPersonTraceInfo_t;

/**
 * 人员跟踪状态
 */
typedef enum ReconovaPersonTraceStatus_e {
    RECONOVA_PERSON_TRACE_STATUS_ENTER,    /* 人员进去 */
    RECONOVA_PERSON_TRACE_STATUS_UPDATE,/* 人员更新 */
    RECONOVA_PERSON_TRACE_STATUS_LEAVE    /* 人员离开 */
} ReconovaPersonTraceStatus_t;

/**
 * 视频帧回调 
 * @param image 视频帧信息
 * @parma faceList 人脸框列表
 * @parma faceNum 人脸个数
 * @parma data 用户自定义数据
 */
typedef int (*ReconovaFrameCallBack_t)(ReconovaBGR24Image_t *image, ReconovaFaceRectInfo_t *faceList, int faceNum, void *data);

/**
 * 人员跟踪信息回调
 * @param personTraceInfo 人员跟踪信息
 * @param personTraceStatus 人员跟踪状态
 * @param data 用户自定义数据
 */
typedef int (*ReconovaPersonTraceInfoCallBack_t)(ReconovaPersonTraceInfo_t *personTraceInfo, ReconovaPersonTraceStatus_t personTraceStatus, void *data);

/**
 * 模块初始化
 * @return 成功返回0,失败返回负数
 */
RECONOVAFACECAMERASDK_API int ReconovaFaceCameraSdkInit(void);

/**
 * 模块反初始化,释放资源
 * @return 成功返回0,失败返回负数
 */
RECONOVAFACECAMERASDK_API int ReconovaFaceCameraSdkUnInit(void);

/**
 * 注册视频帧回调
 * @param callBack[in] 回调函数
 * @param data[in] 自定义数据
 *
 * @note 该接口需要在启动USB像机之前调用
 *       该接口推送的是BGR24的图片原始数据
 *
 * @return 成功返回0,失败返回负数
 */
RECONOVAFACECAMERASDK_API int ReconovaFaceCameraSdkRegisterFrameCallBack(ReconovaFrameCallBack_t callBack, void *data);

/**
 * 注册人员跟踪信息回调
 * @param callBack[in] 回调函数
 * @param data[in] 自定义数据
 *
 * @return 成功返回0,失败返回负数
 */
RECONOVAFACECAMERASDK_API int ReconovaFaceCameraSdkRegisterPersonTraceInfoCallBack(ReconovaPersonTraceInfoCallBack_t callBack, void *data);

/**
 * 启动人脸摄像头
 *
 * @return 成功返回0,失败返回负数
 */
RECONOVAFACECAMERASDK_API int ReconovaFaceCameraSdkFaceCameraStart(void);

/**
 * 停止人脸摄像头
 *
 * @return 成功返回0,失败返回负数
 */
RECONOVAFACECAMERASDK_API int ReconovaFaceCameraSdkFaceCameraStop(void);


#ifdef __cplusplus
}
#endif

#endif /* _RECONOVA_FACE_CAMERA_SDK_H_ */

java 依赖

        <dependency>
            <groupId>net.java.dev.jna</groupId>
            <artifactId>jna-platform</artifactId>
            <version>5.8.0</version>
        </dependency>

        <dependency>
            <groupId>org.bytedeco</groupId>
            <artifactId>javacv-platform</artifactId>
            <version>1.3.3</version>
        </dependency>

java 初始化和启动

@PostConstruct
    public void init() {

        EventQueue.invokeLater(()->{
            int res = -1;
            res = FaceService.INSTANCE.ReconovaFaceCameraSdkInit();
            if (0 != res) {
                log.error("ReconovaFaceCameraSdkInit failed");
                return;
            }

            res = FaceService.INSTANCE.ReconovaFaceCameraSdkRegisterFrameCallBack(reconovaFrameCallBack, null);
            if (0 != res) {
                log.error("ReconovaFaceCameraSdkRegisterFrameCallBack failed");
                return;
            }

            res = FaceService.INSTANCE.ReconovaFaceCameraSdkRegisterPersonTraceInfoCallBack(reconovaPersonTraceInfoCallBack, Pointer.NULL);
            if (0 != res) {
                log.error("ReconovaFaceCameraSdkRegisterPersonTraceInfoCallBack failed");
                return;
            }
            res = FaceService.INSTANCE.ReconovaFaceCameraSdkFaceCameraStart();
            if (0 != res) {
                log.error("ReconovaFaceCameraSdkFaceCameraStart failed");
            }

        });

    }

    @PreDestroy
    public void uninit() {
        FaceService.INSTANCE.ReconovaFaceCameraSdkFaceCameraStop();
        FaceService.INSTANCE.ReconovaFaceCameraSdkUnInit();
    }

java 回调函数定义

视频帧回调


public interface ReconovaFrameCallBack extends Callback {

    int invoke(Pointer image, Pointer faceList, int faceNum, Pointer data);
}

人脸跟踪信息回调

public interface ReconovaPersonTraceInfoCallBack extends Callback {
    int invoke(Pointer personTraceInfo, int personTraceStatus, Pointer data);
}

java 回调函数实现

视频帧回调

public class ReconovaFrameCallBackImpl implements ReconovaFrameCallBack {


    /**
     * 视频帧回调 展示图像数据
     *
     * 暂时没有展示的设计
     *
     *
     *
     * @param imgPointer 视频帧信息
     * @parma faceList 人脸框列表 需要往图片上画人脸矩形
     * @parma faceNum 人脸个数 faceNum=0 的时候要做页面切换
     * @parma data 用户自定义数据
     */
    @Override
    public int invoke(Pointer imgPointer, Pointer faceListPointer, int faceNum, Pointer data) {

        if (faceNum > 0) {
            ReconovaFaceRectInfo_t[] faceList = transferPointertoRect(faceListPointer, faceNum);
        //    Stream.of(faceList).map(f-> FaceUtils.calArea(f)).forEach(a->log.info("人脸大小{}",a));
        }


        // 暂时没有展示需求
        /*ReconovaBGR24Image_t image_t = transferPointerToImage(imgPointer);
        ReconovaFaceRectInfo_t[] faceList = transferPointertoRect(faceListPointer, faceNum);

        IplImage iplImage = cvCreateImageHeader(cvSize(image_t.width, image_t.height), IPL_DEPTH_8U, 3);
        BytePointer bytePointer = new BytePointer(image_t.imageData);
        cvSetData(iplImage, bytePointer, ((image_t.width * 3) + 3) >> 2 << 2);

        for (int i = 0; i < faceNum; i++) {
            cvRectangle(iplImage,
                    cvPoint(faceList[i].left, faceList[i].top),
                    cvPoint(faceList[i].right, faceList[i].bottom),
                    CV_RGB(0, 255, 0),
                    1,
                    4,
                    0
            );
        }

        cvNamedWindow("test",CV_WINDOW_FULLSCREEN);
        cvResizeWindow("test", image_t.width, image_t.height);
        cvShowImage("test", iplImage);

        cvReleaseImageHeader(iplImage);*/

        cvWaitKey(1);

        return 0;
    }

}

人脸跟踪信息回调

public class ReconovaPersonTraceInfoCallBackImpl implements ReconovaPersonTraceInfoCallBack {

    /**
     * 人员跟踪信息回调
     * @param personTraceInfo 人员跟踪信息
     * @param personTraceStatus 人员跟踪状态
     *                         人员进去=0  人员更新=1      人员离开=2
     *
     * @param data 用户自定义数据
     */
    @Override
    public int invoke(Pointer personTraceInfo, int personTraceStatus, Pointer data) {
        log.info("personTraceStatus={}",personTraceStatus);
        // 更新状态下,人脸矩形达到一定的尺寸(越靠近摄像头,矩形越大,需要摸索出最佳尺寸),则将人脸数据发送后台检索信息
        FaceService.ReconovaPersonTraceInfo_t traceInfo = FaceUtils.transTraceInfo(personTraceInfo);
        FaceService.ReconovaFaceRectInfo_t  faceRect = traceInfo.faceRect;

        int width = faceRect.right - faceRect.left;
        int height= faceRect.bottom - faceRect.top;



        return 0;
    }

}

数据解析类

public class FaceUtils {

    public static String bgr2base64(FaceService.ReconovaBGR24Image_t image_t) {
        opencv_core.IplImage iplImage = cvCreateImageHeader(cvSize(image_t.width, image_t.height), IPL_DEPTH_8U, 3);
        BytePointer bytePointer = new BytePointer(image_t.imageData);
        cvSetData(iplImage, bytePointer, ((image_t.width * 3) + 3) >> 2 << 2);

        BufferedImage bufferedImage = Java2DFrameUtils.toBufferedImage(iplImage);
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream(10240 * 6);
        try {
            ImageIO.write(bufferedImage, "PNG", outputStream);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            cvReleaseImageHeader(iplImage);
        }
        String base64 = Base64.encodeBase64String(outputStream.toByteArray());
        cvReleaseImageHeader(iplImage);
        return base64;
    }


    public static FaceService.ReconovaBGR24Image_t transferPointerToImage(Pointer image) {

        FaceService.ReconovaBGR24Image_t reconovaBGR24Image_t = new FaceService.ReconovaBGR24Image_t();
        reconovaBGR24Image_t.width = image.getInt(0);
        reconovaBGR24Image_t.height = image.getInt(4);
        reconovaBGR24Image_t.widthStep = image.getInt(8);
        reconovaBGR24Image_t.imageSize = image.getInt(12);
        Pointer imgdataPointer = image.getPointer(16);
        reconovaBGR24Image_t.imageData = imgdataPointer.getByteArray(0, reconovaBGR24Image_t.imageSize);
        return reconovaBGR24Image_t;

    }

    public static FaceService.ReconovaFaceRectInfo_t[] transferPointertoRect(Pointer faceList, int faceNum) {
        FaceService.ReconovaFaceRectInfo_t[] arr = new FaceService.ReconovaFaceRectInfo_t[faceNum];
        for (int i = 0; i < faceNum; i++) {
            FaceService.ReconovaFaceRectInfo_t reconovaFaceRectInfo_t = new FaceService.ReconovaFaceRectInfo_t();
            reconovaFaceRectInfo_t.left = faceList.getInt(0 + i * 16);
            reconovaFaceRectInfo_t.top = faceList.getInt(4 + i * 16);
            reconovaFaceRectInfo_t.right = faceList.getInt(8 + i * 16);
            reconovaFaceRectInfo_t.bottom = faceList.getInt(12 + i * 16);
            arr[i] = reconovaFaceRectInfo_t;
        }

        return arr;
    }

    public static FaceService.ReconovaFaceFeature_t transferFaceFeture(Pointer pointer) {
        FaceService.ReconovaFaceFeature_t reconovaFaceFeature_t = new FaceService.ReconovaFaceFeature_t();
        reconovaFaceFeature_t.featLength = pointer.getInt(0);
        Pointer dataP = pointer.getPointer(4);
        reconovaFaceFeature_t.featData = dataP.getByteArray(0, reconovaFaceFeature_t.featLength);
        return reconovaFaceFeature_t;

    }


    public static FaceService.ReconovaPersonTraceInfo_t transTraceInfo(Pointer pointer) {

        FaceService.ReconovaPersonTraceInfo_t traceInfo_t = new FaceService.ReconovaPersonTraceInfo_t();
        traceInfo_t.personId = pointer.getInt(0);

        FaceService.ReconovaBGR24Image_t reconovaBGR24Image_t = new FaceService.ReconovaBGR24Image_t();
        reconovaBGR24Image_t.width = pointer.getInt(0+4);
        reconovaBGR24Image_t.height = pointer.getInt(4+4);
        reconovaBGR24Image_t.widthStep = pointer.getInt(8+4);
        reconovaBGR24Image_t.imageSize = pointer.getInt(12+4);
        Pointer imgdataPointer = pointer.getPointer(16+4);
        reconovaBGR24Image_t.imageData = imgdataPointer.getByteArray(0, reconovaBGR24Image_t.imageSize);
        traceInfo_t.frameImage = reconovaBGR24Image_t;


        FaceService.ReconovaFaceRectInfo_t reconovaFaceRectInfo_t = new FaceService.ReconovaFaceRectInfo_t();
        reconovaFaceRectInfo_t.left = pointer.getInt(0 + ReconovaBGR24Image_size+4);
        reconovaFaceRectInfo_t.top = pointer.getInt(4 + ReconovaBGR24Image_size+4);
        reconovaFaceRectInfo_t.right = pointer.getInt(8 + ReconovaBGR24Image_size+4);
        reconovaFaceRectInfo_t.bottom = pointer.getInt(12 + ReconovaBGR24Image_size+4);
        traceInfo_t.faceRect = reconovaFaceRectInfo_t;


        FaceService.ReconovaBGR24Image_t reconovaBGR24Image_t2 = new FaceService.ReconovaBGR24Image_t();
        reconovaBGR24Image_t2.width = pointer.getInt(0+ReconovaBGR24Image_size+4+ReconovaFaceRectInfo_size);
        reconovaBGR24Image_t2.height = pointer.getInt(4+ReconovaBGR24Image_size+4+ReconovaFaceRectInfo_size);
        reconovaBGR24Image_t2.widthStep = pointer.getInt(8+ReconovaBGR24Image_size+4+ReconovaFaceRectInfo_size);
        reconovaBGR24Image_t2.imageSize = pointer.getInt(12+ReconovaBGR24Image_size+4+ReconovaFaceRectInfo_size);
        Pointer imgdataPointer2 = pointer.getPointer(16+ReconovaBGR24Image_size+4+ReconovaFaceRectInfo_size);
        reconovaBGR24Image_t2.imageData = imgdataPointer2.getByteArray(0, reconovaBGR24Image_t2.imageSize);
        traceInfo_t.faceImage = reconovaBGR24Image_t2;

        FaceService.ReconovaFaceFeature_t reconovaFaceFeature_t = new FaceService.ReconovaFaceFeature_t();
        reconovaFaceFeature_t.featLength = pointer.getInt(0+ReconovaBGR24Image_size*2+4+ReconovaFaceRectInfo_size);
        Pointer dataP = pointer.getPointer(4+ReconovaBGR24Image_size*2+4+ReconovaFaceRectInfo_size);
        reconovaFaceFeature_t.featData = dataP.getByteArray(0, reconovaFaceFeature_t.featLength);
        traceInfo_t.faceFeature = reconovaFaceFeature_t;

        return traceInfo_t;
    }

    public static long calArea(FaceService.ReconovaFaceRectInfo_t faceRect) {
        int width = faceRect.right - faceRect.left;
        int height= faceRect.bottom - faceRect.top;
        return width*height;
    }
}



硬件      javacv JNA 摄像头

本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!