案例中用到的jar包,javacv1.2,opencv3.0
java模仿c的结构体,保存身份证信息
package com.aast.service;
import java.util.ArrayList;
import java.util.List;
import com.sun.jna.*;
/**
* C++ 获取身份证信息的接口
* @author Administrator
*/
public interface Termb extends Library{
public static class IdCardTxtInfo extends Structure{
public byte[] name=new byte[31];
public byte[] sex=new byte[6];
public byte[] nation=new byte[11];
public byte[] borndate=new byte[9];
public byte[] address=new byte[71];
public byte[] idno=new byte[19];
public byte[] department=new byte[31];
public byte[] StartDate=new byte[9];
public byte[] EndDate=new byte[9];
public byte[] Reserve=new byte[37];
public byte[] AppAddress=new byte[71];
public byte[] PhotoBMP=new byte[1024*10];
@Override
protected List<String> getFieldOrder() {
List<String> list=new ArrayList<>();
list.add("name");
list.add("sex");
list.add("nation");
list.add("borndate");
list.add("address");
list.add("idno");
list.add("department");
list.add("StartDate");
list.add("EndDate");
list.add("Reserve");
list.add("AppAddress");
list.add("PhotoBMP");
return list;
}
}
public int InitFilePath(String fname);
public int InitComm(int iPort);
public int Authenticate();
public int Read_Content(int iActive);
public int GetIdCardTxtInfo(IdCardTxtInfo result);
public int CloseComm();
}
下面这个是获取人脸图片信息的
C的结构体
//(1) 人脸位置,图片中人脸的位置信息
typedef struct {
long nTop;//上
long nLeft; //左
long nRight; //右
long nBottom; //下
float score;//人脸质量,范围:0-100 ,数值越高质量越好
char szPhotoPath[MAX_PATH];//人脸截图路径
}FaceInfo;
//(2)特征值,图片中人脸的特征值信息
typedef struct
{
float pmodel[1280]; //特征值数组
long model_size; //数组大小
}FaceModelInfo;
//(3)一张图片整体信息
typedef struct
{
BOOL bNeedPhoto; //是否要保留人脸截图
FaceInfo faceInfo[4];//人脸信息
FaceModelInfo faceModelInfo[4];//人脸特征信息
int nFacesize;//有多少个人脸
}FaceCheckInfo;
package com.aast.service;
import java.util.Arrays;
import java.util.List;
import com.sun.jna.*;
import com.sun.jna.ptr.FloatByReference;
import com.sun.jna.win32.*;
public interface Camera extends StdCallLibrary{
public class FaceInfo extends Structure{
public NativeLong nTop; //上
public NativeLong nLeft; //左
public NativeLong nRight; //右
public NativeLong nBottom;//下
public float score; //人脸质量,范围:0-100 ,数值越高质量越好
public byte[] szPhotoPath=new byte[260];//人脸截图路径
public static class ByReference extends FaceInfo implements Structure.ByReference { }
public static class ByValue extends FaceInfo implements Structure.ByValue{ }
@Override
protected List<String> getFieldOrder(){
return Arrays.asList(new String[]{"nTop", "nLeft", "nRight", "nBottom","score","szPhotoPath"});
}
@Override
public String toString() {
return "FaceInfo [nTop=" + nTop + ", nLef=" + nLeft + ", nRight=" + nRight + ", nBottom=" + nBottom
+ ", score=" + score + ", szPhotoPath=" + szPhotoPath;//Arrays.toString(szPhotoPath) + "]";
}
}
public class FaceModelInfo extends Structure{
public float[] pmodel=new float[1280]; //特征值数组
public NativeLong model_size; //数组大小
public static class ByReference extends FaceModelInfo implements Structure.ByReference { }
public static class ByValue extends FaceModelInfo implements Structure.ByValue{ }
@Override
protected List<String> getFieldOrder(){
return Arrays.asList(new String[]{"pmodel","model_size"});
}
@Override
public String toString() {
return "FaceModelInfo [pmodel=" + Arrays.toString(pmodel) + ", model_size=" + model_size + "]";
}
}
public class FaceCheckInfo extends Structure{
public byte bNeedPhoto; //是否要保留人脸截图
public FaceInfo[] faceInfo=new FaceInfo[4];
public FaceModelInfo[] faceModelInfo=new FaceModelInfo[4];
public int nFacesize;//有多少个人脸
public static class ByReference extends FaceCheckInfo implements Structure.ByReference { }
public static class ByValue extends FaceCheckInfo implements Structure.ByValue{ }
@Override
protected List<String> getFieldOrder(){
return Arrays.asList(new String[]{"bNeedPhoto", "faceInfo", "faceModelInfo", "nFacesize"});
}
@Override
public String toString() {
return "FaceCheckInfo [bNeedPhoto=" + bNeedPhoto + ", faceInfo=" + Arrays.toString(faceInfo)
+ ", faceModelInfo=" + Arrays.toString(faceModelInfo) + ", nFacesize=" + nFacesize + "]";
}
}
boolean InitSDK(String path);//初始化SDK,一个应用程序只初始化一次,一般在应用启动时,TRUE为成功,FASE为失败
int DetectFace(byte[] pImageBuf,int nImageLen,FaceCheckInfo.ByReference faceCheckInfo);
boolean CalcModel(FaceModelInfo faceModelInfo1,FaceModelInfo faceModelInfo2,FloatByReference pFxd);
boolean DelSDK();
}
1.java调用身份证SDK
package com.aast.utils;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import com.aast.entity.IdCardInfo;
import com.aast.service.Termb;
import com.sun.jna.Native;
public class IDCardSDK {
private static Termb lib=null;
private static Termb.IdCardTxtInfo info =null;
private static IdCardInfo idCardInfo=null;
private static String str;
static{
lib = (Termb) Native.loadLibrary("c:\\src\\termb", Termb.class);
}
public static String check(){
return str;
}
public static IdCardInfo start(){
if (lib.InitComm(1001) != 1){
System.out.println ("InitComm error! 读卡器链接错误");
return null;
}
lib.Authenticate();//身份证授权
if (lib.Read_Content(1) != 1){
System.out.println ("Read_Content error! 身份证没有放置好");
return null;
}
else{
try{
lib.InitFilePath("C:\\tmp\\images\\");//wlt图片 文本路径默认在当前文件夹
info=new Termb.IdCardTxtInfo();//初始化内存
lib.GetIdCardTxtInfo(info);//读取个人信息
idCardInfo=new IdCardInfo();//封装个人信息
idCardInfo.setName(new String(info.name, "gbk").trim());
idCardInfo.setSex(new String(info.sex, "gbk").trim());
idCardInfo.setNation(new String(info.nation, "gbk").trim());
idCardInfo.setBorndate(new String(info.borndate, "gbk").trim());
idCardInfo.setAddress(new String(info.address, "gbk").trim());
String id=new String(info.idno, "gbk").trim();
idCardInfo.setIdno(id);
idCardInfo.setDepartment(new String(info.department, "gbk").trim());
idCardInfo.setStartDate(new String(info.StartDate, "gbk").trim());
idCardInfo.setEndDate(new String(info.EndDate, "gbk").trim());
idCardInfo.setReserve(new String(info.Reserve, "gbk").trim());
idCardInfo.setAppAddress(new String(info.AppAddress, "gbk").trim());
idCardInfo.setPhotoBMP(getPhoto(id));
}catch(IOException e){
System.out.println("读取身份证信息失败!");
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}finally {
//lib.CloseComm();
}
}
return idCardInfo;
}
private static byte[] getPhoto(String id) throws Exception{
File bmpfile=new File("C:\\tmp\\images\\"+id+".bmp");
File txtfile=new File("C:\\tmp\\images\\"+id+".txt");
if(!bmpfile.exists()){
return null;
}
if(bmpfile.exists()){
txtfile.delete();//删除文本
}
ByteArrayOutputStream bos = new ByteArrayOutputStream((int)bmpfile.length());
BufferedInputStream in = null;
try{
in = new BufferedInputStream(new FileInputStream(bmpfile));
int buf_size = 1024;
byte[] buffer = new byte[buf_size];
int len = 0;
while((len = in.read(buffer,0,buf_size))!=-1){
bos.write(buffer,0,len);
}
return bos.toByteArray();
}catch (IOException e) {
e.printStackTrace();
throw e;
}finally{
try{
in.close();
bmpfile.delete();//删除图像
}catch (IOException e) {
e.printStackTrace();
}
bos.close();
}
}
}
调用获取人脸信息,以及人脸比对
package com.aast.utils;
import com.aast.service.Camera;
import com.aast.service.Camera.FaceCheckInfo;
import com.aast.service.Camera.FaceInfo;
import com.aast.service.Camera.FaceModelInfo;
import com.sun.jna.Native;
import com.sun.jna.ptr.FloatByReference;
public class FaceCheckSDK {
private static FaceCheckInfo.ByReference faceCheckInfo=null;
private static FaceCheckInfo.ByReference faceCheckInfo1=null;
private static Camera INSTANCE =null;
private static String rootPath =null;
private static FloatByReference xsd=new FloatByReference(0);
static{
INSTANCE= (Camera) Native.loadLibrary("c:\\src\\FaceSDKV2", Camera.class);
rootPath= "c:\\src\\" ;
INSTANCE.InitSDK(rootPath);
}
/**进行人脸比对
* @param pImageBuf 身份证照片byte[]
* @param imgPath2 摄像头截图路径
* @return
*/
public static float startCompare(FaceCheckInfo.ByReference faceCheckInfo,byte[] pImgBuf){
faceCheckInfo1=initFaceCheckInfo();
INSTANCE.DetectFace(pImgBuf, pImgBuf.length, faceCheckInfo1);
boolean b=INSTANCE.CalcModel(faceCheckInfo.faceModelInfo[0],faceCheckInfo1.faceModelInfo[0],xsd);
return xsd.getValue();
}
/**给结构体分配内存
* @return
*/
private static FaceCheckInfo.ByReference initFaceCheckInfo(){
FaceCheckInfo.ByReference faceCheckInfo=new FaceCheckInfo.ByReference();
for(int i=0;i<faceCheckInfo.faceInfo.length;i++)
faceCheckInfo.faceInfo[i]=new FaceInfo();
for(int i=0;i<faceCheckInfo.faceModelInfo.length;i++)
faceCheckInfo.faceModelInfo[i]=new FaceModelInfo();
return faceCheckInfo;
}
/**获取身份证照片信息
* @param pImgBuf
* @return
*/
public static FaceCheckInfo.ByReference getIdcardFaceInfo(byte[] pImgBuf){
FaceCheckInfo.ByReference faceCheckInfo=initFaceCheckInfo();
INSTANCE.DetectFace(pImgBuf, pImgBuf.length, faceCheckInfo);
return faceCheckInfo;
}
}
上面包含结构体嵌套 ,以及结构体数组的问题
附上C-JAVA对应的数据,boolean 和int 好像都可互相转换,这里测试没什么问题