厂家不提供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;
}
}
本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!