Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
5d5330dd33
Binary file not shown.
Binary file not shown.
|
|
@ -192,7 +192,21 @@
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- <dependency>-->
|
||||||
|
<!-- <groupId>arcsoft</groupId>-->
|
||||||
|
<!-- <artifactId>arcsoft</artifactId>-->
|
||||||
|
<!-- <version>3.0</version>-->
|
||||||
|
<!-- <scope>system</scope>-->
|
||||||
|
<!-- <systemPath>${project.basedir}/lib/arcsoft-sdk-face-3.0.0.0-linux.jar</systemPath>-->
|
||||||
|
<!-- </dependency>-->
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>arcsoft</groupId>
|
||||||
|
<artifactId>arcsoft</artifactId>
|
||||||
|
<version>3.0</version>
|
||||||
|
<scope>system</scope>
|
||||||
|
<systemPath>${project.basedir}/lib/arcsoft-sdk-face-3.0.0.0-windows.jar</systemPath>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,8 @@ public class FaceMetadataModel {
|
||||||
private String ifUseMegviiFaceUrl;
|
private String ifUseMegviiFaceUrl;
|
||||||
@ApiModelProperty("旷视算法版本,多个数据用,分隔")
|
@ApiModelProperty("旷视算法版本,多个数据用,分隔")
|
||||||
private String openMegviiFaceVersion;
|
private String openMegviiFaceVersion;
|
||||||
|
@ApiModelProperty("是否启用虹软算法 默认开启")
|
||||||
|
private String ifRainbowSoftFaceUrl;
|
||||||
public FaceMetadataModel() {
|
public FaceMetadataModel() {
|
||||||
this.setIfUseBitFaceBoxUrl("2");
|
this.setIfUseBitFaceBoxUrl("2");
|
||||||
this.setIfUseGateMachineUrl("2");
|
this.setIfUseGateMachineUrl("2");
|
||||||
|
|
@ -49,6 +50,15 @@ public class FaceMetadataModel {
|
||||||
this.setIfGetMegviiFeature3568Device("2");
|
this.setIfGetMegviiFeature3568Device("2");
|
||||||
this.setIfUseMegvii1109FaceUrl("2");
|
this.setIfUseMegvii1109FaceUrl("2");
|
||||||
this.setIfNoneMegviiFeatureOnlyDevicePhoto("2");
|
this.setIfNoneMegviiFeatureOnlyDevicePhoto("2");
|
||||||
|
this.setIfRainbowSoftFaceUrl("1");
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getIfRainbowSoftFaceUrl() {
|
||||||
|
return ifRainbowSoftFaceUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIfRainbowSoftFaceUrl(String ifRainbowSoftFaceUrl) {
|
||||||
|
this.ifRainbowSoftFaceUrl = ifRainbowSoftFaceUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getMegvii3288FaceUrl() {
|
public String getMegvii3288FaceUrl() {
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,6 @@ import com.alibaba.fastjson.JSON;
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
||||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
import com.bonus.common.core.exception.ServiceException;
|
|
||||||
import com.bonus.canteen.core.common.utils.SysUtil;
|
import com.bonus.canteen.core.common.utils.SysUtil;
|
||||||
import com.bonus.canteen.core.customer.dto.BitmainOtherInfoDTO;
|
import com.bonus.canteen.core.customer.dto.BitmainOtherInfoDTO;
|
||||||
import com.bonus.canteen.core.customer.dto.BitmainResultDTO;
|
import com.bonus.canteen.core.customer.dto.BitmainResultDTO;
|
||||||
|
|
@ -21,12 +20,15 @@ import com.bonus.canteen.core.customer.metadata.service.FaceMetadataService;
|
||||||
import com.bonus.canteen.core.customer.model.CustInfo;
|
import com.bonus.canteen.core.customer.model.CustInfo;
|
||||||
import com.bonus.canteen.core.customer.service.CustInfoService;
|
import com.bonus.canteen.core.customer.service.CustInfoService;
|
||||||
import com.bonus.canteen.core.customer.service.FaceRegisterService;
|
import com.bonus.canteen.core.customer.service.FaceRegisterService;
|
||||||
|
import com.bonus.canteen.core.customer.utils.ArcFaceHelper;
|
||||||
import com.bonus.canteen.core.customer.utils.BitmainUtil;
|
import com.bonus.canteen.core.customer.utils.BitmainUtil;
|
||||||
|
import com.bonus.canteen.core.customer.utils.FaceResult;
|
||||||
import com.bonus.canteen.core.customer.utils.UfaceUtil;
|
import com.bonus.canteen.core.customer.utils.UfaceUtil;
|
||||||
import com.bonus.canteen.core.customer.v4.dto.FaceRegisterDTO;
|
import com.bonus.canteen.core.customer.v4.dto.FaceRegisterDTO;
|
||||||
import com.bonus.canteen.core.customer.v4.megvii.MegviiUtilV4;
|
import com.bonus.canteen.core.customer.v4.megvii.MegviiUtilV4;
|
||||||
import com.bonus.canteen.core.customer.vo.MultiModelFaceVO;
|
import com.bonus.canteen.core.customer.vo.MultiModelFaceVO;
|
||||||
import com.bonus.canteen.core.device.constants.FaceVerTypeEnum;
|
import com.bonus.canteen.core.device.constants.FaceVerTypeEnum;
|
||||||
|
import com.bonus.common.core.exception.ServiceException;
|
||||||
import com.bonus.common.houqin.utils.LeBeanUtil;
|
import com.bonus.common.houqin.utils.LeBeanUtil;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
@ -35,10 +37,7 @@ import org.springframework.web.util.UriComponents;
|
||||||
import org.springframework.web.util.UriComponentsBuilder;
|
import org.springframework.web.util.UriComponentsBuilder;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
|
|
@ -161,7 +160,10 @@ public class FaceRegisterServiceImpl implements FaceRegisterService {
|
||||||
public List<MultiModelFaceVO> multiModelRegisterHandler(UnifiedFaceRegisterParamDTO registerParamDTO, boolean isSaveErrorPicture) {
|
public List<MultiModelFaceVO> multiModelRegisterHandler(UnifiedFaceRegisterParamDTO registerParamDTO, boolean isSaveErrorPicture) {
|
||||||
List<MultiModelFaceVO> list = new ArrayList();
|
List<MultiModelFaceVO> list = new ArrayList();
|
||||||
FaceMetadataModel faceMetadataModel = this.faceMetadataService.queryMetadata();
|
FaceMetadataModel faceMetadataModel = this.faceMetadataService.queryMetadata();
|
||||||
if (!ObjectUtil.isEmpty(faceMetadataModel) && (!"2".equals(faceMetadataModel.getIfUseBitFaceBoxUrl()) || !"2".equals(faceMetadataModel.getIfUseGateMachineUrl()) || !"2".equals(faceMetadataModel.getIfUseMegvii1109FaceUrl()) || !"2".equals(faceMetadataModel.getIfUseMegvii3288FaceUrl()) || !"2".equals(faceMetadataModel.getIfUseMegvii3568FaceUrl()))) {
|
faceMetadataModel.setIfUseMegvii3288FaceUrl("2");
|
||||||
|
if (!ObjectUtil.isEmpty(faceMetadataModel) && (!"2".equals(faceMetadataModel.getIfUseBitFaceBoxUrl()) || !"2".equals(faceMetadataModel.getIfUseGateMachineUrl())
|
||||||
|
|| !"2".equals(faceMetadataModel.getIfUseMegvii1109FaceUrl()) || !"2".equals(faceMetadataModel.getIfUseMegvii3288FaceUrl())
|
||||||
|
|| !"2".equals(faceMetadataModel.getIfUseMegvii3568FaceUrl()) || !"2".equals(faceMetadataModel.getIfRainbowSoftFaceUrl()))) {
|
||||||
BitmainOtherInfoDTO bitmainOtherInfoDTO = (BitmainOtherInfoDTO)BeanUtil.copyProperties(registerParamDTO, BitmainOtherInfoDTO.class, new String[0]);
|
BitmainOtherInfoDTO bitmainOtherInfoDTO = (BitmainOtherInfoDTO)BeanUtil.copyProperties(registerParamDTO, BitmainOtherInfoDTO.class, new String[0]);
|
||||||
Optional<BitmainResultDTO> bitmainResultDTO = this.registerBitmain(registerParamDTO.getImageBase64(), bitmainOtherInfoDTO);
|
Optional<BitmainResultDTO> bitmainResultDTO = this.registerBitmain(registerParamDTO.getImageBase64(), bitmainOtherInfoDTO);
|
||||||
if (bitmainResultDTO.isPresent()) {
|
if (bitmainResultDTO.isPresent()) {
|
||||||
|
|
@ -225,10 +227,32 @@ public class FaceRegisterServiceImpl implements FaceRegisterService {
|
||||||
SysUtil.removeOssObject(registerParamDTO.getMinioPicPath());
|
SysUtil.removeOssObject(registerParamDTO.getMinioPicPath());
|
||||||
throw new ServiceException("[旷世1109算法]:失败");
|
throw new ServiceException("[旷世1109算法]:失败");
|
||||||
}
|
}
|
||||||
|
|
||||||
list.add(faceFeature1109);
|
list.add(faceFeature1109);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//虹软人脸识别
|
||||||
|
//TODO 待提取公共数据
|
||||||
|
if ("1".equals(faceMetadataModel.getIfRainbowSoftFaceUrl())){
|
||||||
|
System.out.println("开始采集虹软人脸");
|
||||||
|
ArcFaceHelper arcFaceHelper = new ArcFaceHelper();
|
||||||
|
System.out.println("开始采集" + registerParamDTO.getMinioPicPath());
|
||||||
|
String finalUrl = String.format("%s%s", "http://192.168.0.14:9090", registerParamDTO.getMinioPicPath().trim());
|
||||||
|
System.out.println("finalUrl:" + finalUrl);
|
||||||
|
FaceResult faceResult = arcFaceHelper.getFaceFeatures(finalUrl);
|
||||||
|
System.err.println("采集结束");
|
||||||
|
if (faceResult != null){
|
||||||
|
MultiModelFaceVO faceVO = new MultiModelFaceVO();
|
||||||
|
faceVO.setMsg("[软件]成功");
|
||||||
|
faceVO.setFaceVer(Integer.valueOf(FaceVerTypeEnum.FACE_VER_ARC.getKey()));
|
||||||
|
faceVO.setFeature(Base64.getEncoder().encodeToString(faceResult.getFeatures()));
|
||||||
|
faceVO.setSuccess(true);
|
||||||
|
list.add(faceVO);
|
||||||
|
System.out.println("faceResult.getFeatures():" + Base64.getEncoder().encodeToString(faceResult.getFeatures()));
|
||||||
|
System.out.println("人脸采集成功");
|
||||||
|
}else {
|
||||||
|
throw new ServiceException("[虹软算法]:特征值提取失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return list;
|
return list;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -237,4 +261,11 @@ public class FaceRegisterServiceImpl implements FaceRegisterService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String customTrim(String input) {
|
||||||
|
if (input == null || input.isEmpty()) return input;
|
||||||
|
int start = 0, end = input.length() - 1;
|
||||||
|
while (start <= end && Character.isWhitespace(input.charAt(start))) start++;
|
||||||
|
while (end >= start && Character.isWhitespace(input.charAt(end))) end--;
|
||||||
|
return input.substring(start, end + 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,460 @@
|
||||||
|
package com.bonus.canteen.core.customer.utils;
|
||||||
|
|
||||||
|
import com.arcsoft.face.*;
|
||||||
|
import com.arcsoft.face.enums.DetectMode;
|
||||||
|
import com.arcsoft.face.enums.DetectOrient;
|
||||||
|
import com.arcsoft.face.enums.ErrorInfo;
|
||||||
|
import com.arcsoft.face.enums.ImageFormat;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
import java.awt.color.ColorSpace;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.awt.image.ColorConvertOp;
|
||||||
|
import java.awt.image.DataBufferByte;
|
||||||
|
import java.io.*;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 人脸识别工具类
|
||||||
|
* @author zys
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
public class ArcFaceHelper {
|
||||||
|
|
||||||
|
private static final String APP_ID = "52XE2dQBtdmMsfDMvyKmPCD8wfSfJyBsQBsVa2HXS6pg";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* x64
|
||||||
|
*/
|
||||||
|
private static final String WIN64_SDK_KEY = "3TMzo8nmWDka6NJDrbX7e2y1ew4QgSia4iGBniyWU4qq";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* linux_64
|
||||||
|
*/
|
||||||
|
private static final String LINUX64_SDK_KEY = "3TMzo8nmWDka6NJDrbX7e2y1WpVESExKSnShHKmNAiML";
|
||||||
|
|
||||||
|
private static FaceEngine faceEngine = null;
|
||||||
|
|
||||||
|
public static final float STANDARD_SCORE = 0.85F;
|
||||||
|
|
||||||
|
static {
|
||||||
|
int errorCode = 0;
|
||||||
|
try{
|
||||||
|
String os = System.getProperty("os.name");
|
||||||
|
if(StringUtils.startsWith(os.toLowerCase(), "win")){
|
||||||
|
faceEngine = new FaceEngine("D:\\arcsoft_lib_64");
|
||||||
|
//激活引擎
|
||||||
|
faceEngine.activeOnline(APP_ID, WIN64_SDK_KEY);
|
||||||
|
} else {
|
||||||
|
faceEngine = new FaceEngine("/data/arcsoft_lib_64");
|
||||||
|
//激活引擎
|
||||||
|
errorCode = faceEngine.activeOnline(APP_ID, LINUX64_SDK_KEY);
|
||||||
|
}
|
||||||
|
System.out.println("引擎激活code:" + errorCode);
|
||||||
|
}catch (Throwable e){
|
||||||
|
System.out.println("加载人脸识别引擎异常:" + e.getMessage());
|
||||||
|
}
|
||||||
|
if (errorCode != ErrorInfo.MOK.getValue() && errorCode != ErrorInfo.MERR_ASF_ALREADY_ACTIVATED.getValue()) {
|
||||||
|
System.out.println("引擎激活失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static FaceEngine getFaceEngine() {
|
||||||
|
return faceEngine;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FaceResult getFaceFeatures(String imgSrc) {
|
||||||
|
System.out.println("-----getFaceFeatures");
|
||||||
|
if(imgSrc.contains("http")){
|
||||||
|
System.out.println("-----imgSrc.contains(http)");
|
||||||
|
return getFaceFeatures(getNetUrlHttp(imgSrc));
|
||||||
|
}else{
|
||||||
|
return getFaceFeatures(new File(imgSrc));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public FaceResult getFaceFeatures2(String imgSrc) {
|
||||||
|
if(imgSrc.contains("http")){
|
||||||
|
return getFaceFeatures(getNetUrlHttp(imgSrc));
|
||||||
|
}else{
|
||||||
|
return getFaceFeatures(new File(imgSrc));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static FaceResult getFaceFeatures(File file) {
|
||||||
|
System.out.println("-----开始识别");
|
||||||
|
|
||||||
|
int errorCode = 0;
|
||||||
|
try{
|
||||||
|
String os = System.getProperty("os.name");
|
||||||
|
if(StringUtils.startsWith(os.toLowerCase(), "win")){
|
||||||
|
faceEngine = new FaceEngine("D:\\arcsoft_lib_64");
|
||||||
|
//激活引擎
|
||||||
|
faceEngine.activeOnline(APP_ID, WIN64_SDK_KEY);
|
||||||
|
} else {
|
||||||
|
faceEngine = new FaceEngine("/data/lzhdata/arcsoft_lib_64");
|
||||||
|
//激活引擎
|
||||||
|
errorCode = faceEngine.activeOnline(APP_ID, LINUX64_SDK_KEY);
|
||||||
|
}
|
||||||
|
System.out.println("引擎激活code:" + errorCode);
|
||||||
|
}catch (Throwable e){
|
||||||
|
System.out.println("加载人脸识别引擎异常:" + e.getMessage());
|
||||||
|
}
|
||||||
|
if (errorCode != ErrorInfo.MOK.getValue() && errorCode != ErrorInfo.MERR_ASF_ALREADY_ACTIVATED.getValue()) {
|
||||||
|
System.out.println("引擎激活失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ImageInfoTwo imageInfo = getRGBDataTwo(file);
|
||||||
|
if (imageInfo == null){
|
||||||
|
faceEngine.unInit();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
EngineConfiguration engineConfiguration = EngineConfiguration.builder().functionConfiguration(
|
||||||
|
FunctionConfiguration.builder()
|
||||||
|
.supportFaceDetect(true)
|
||||||
|
.supportAge(true)
|
||||||
|
.supportFace3dAngle(true)
|
||||||
|
.supportFaceDetect(true)
|
||||||
|
.supportFaceRecognition(true)
|
||||||
|
.supportGender(true)
|
||||||
|
.build()).build();
|
||||||
|
//初始化引擎
|
||||||
|
int faceEngineInitCode = faceEngine.init(engineConfiguration);
|
||||||
|
if (faceEngineInitCode != ErrorInfo.MOK.getValue()){
|
||||||
|
System.out.println("初始化引擎失败" + faceEngineInitCode);
|
||||||
|
}
|
||||||
|
//人脸检测
|
||||||
|
List<FaceInfo> lstFaceInfo = new ArrayList<FaceInfo>();
|
||||||
|
faceEngine.detectFaces(imageInfo.getImageData(), imageInfo.getWidth(), imageInfo.getHeight(),
|
||||||
|
ImageFormat.CP_PAF_BGR24, lstFaceInfo);
|
||||||
|
if (lstFaceInfo.size() == 0) {
|
||||||
|
faceEngine.unInit();
|
||||||
|
return null;
|
||||||
|
// throw new NullPointerException("未检测到人脸");
|
||||||
|
}
|
||||||
|
FaceResult result = new FaceResult();
|
||||||
|
//提取人脸特征
|
||||||
|
FaceFeature faceFeature = new FaceFeature();
|
||||||
|
int code = faceEngine.extractFaceFeature(imageInfo.getImageData(), imageInfo.getWidth(), imageInfo.getHeight(),
|
||||||
|
ImageFormat.CP_PAF_BGR24, lstFaceInfo.get(0), faceFeature);
|
||||||
|
result.setFeatures(faceFeature.getFeatureData());
|
||||||
|
//人脸信息检测
|
||||||
|
int processCode = faceEngine.process(imageInfo.getImageData(), imageInfo.getWidth(), imageInfo.getHeight(),
|
||||||
|
ImageFormat.CP_PAF_BGR24, lstFaceInfo,
|
||||||
|
FunctionConfiguration.builder().supportAge(true).supportFace3dAngle(true).supportGender(true).build());
|
||||||
|
if(code != 0 || processCode != 0){
|
||||||
|
faceEngine.unInit();
|
||||||
|
return null;
|
||||||
|
// throw new IllegalArgumentException("提取特征失败");
|
||||||
|
}
|
||||||
|
//性别提取
|
||||||
|
List<GenderInfo> genderInfoList = new ArrayList<GenderInfo>();
|
||||||
|
int genderCode = faceEngine.getGender(genderInfoList);
|
||||||
|
//0:MALE;1:FEMALE;-1:UNKNOWN
|
||||||
|
result.setSex(genderInfoList.get(0).getGender());
|
||||||
|
//年龄提取
|
||||||
|
List<AgeInfo> ageInfoList = new ArrayList<AgeInfo>();
|
||||||
|
int ageCode = faceEngine.getAge(ageInfoList);
|
||||||
|
result.setAge(ageInfoList.get(0).getAge());
|
||||||
|
//3D信息提取
|
||||||
|
List<Face3DAngle> face3DAngleList = new ArrayList<Face3DAngle>();
|
||||||
|
int face3dCode = faceEngine.getFace3DAngle(face3DAngleList);
|
||||||
|
faceEngine.unInit();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void unInintEngine() {
|
||||||
|
int code = faceEngine.unInit();
|
||||||
|
System.out.println("销毁引擎:" + code);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ImageInfo getRGBData(File file) {
|
||||||
|
if (file == null){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
ImageInfo imageInfo;
|
||||||
|
try {
|
||||||
|
//将图片文件加载到内存缓冲区
|
||||||
|
BufferedImage image = ImageIO.read(file);
|
||||||
|
imageInfo = bufferedImage2ImageInfo(image);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return imageInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ImageInfo bufferedImage2ImageInfo(BufferedImage image) {
|
||||||
|
ImageInfo imageInfo = new ImageInfo();
|
||||||
|
int width = image.getWidth();
|
||||||
|
int height = image.getHeight();
|
||||||
|
// 使图片居中
|
||||||
|
width = width & (~3);
|
||||||
|
height = height & (~3);
|
||||||
|
imageInfo.setWidth(width);
|
||||||
|
imageInfo.setHeight(height);
|
||||||
|
//根据原图片信息新建一个图片缓冲区
|
||||||
|
BufferedImage resultImage = new BufferedImage(width, height, image.getType());
|
||||||
|
//得到原图的rgb像素矩阵
|
||||||
|
int[] rgb = image.getRGB(0, 0, width, height, null, 0, width);
|
||||||
|
//将像素矩阵 绘制到新的图片缓冲区中
|
||||||
|
resultImage.setRGB(0, 0, width, height, rgb, 0, width);
|
||||||
|
//进行数据格式化为可用数据
|
||||||
|
BufferedImage dstImage = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_3BYTE_BGR);
|
||||||
|
try {
|
||||||
|
if (resultImage.getType() != BufferedImage.TYPE_3BYTE_BGR) {
|
||||||
|
ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB);
|
||||||
|
ColorConvertOp colorConvertOp = new ColorConvertOp(cs, dstImage.createGraphics().getRenderingHints());
|
||||||
|
colorConvertOp.filter(resultImage, dstImage);
|
||||||
|
} else {
|
||||||
|
dstImage = resultImage;
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
// TODO: handle exception
|
||||||
|
System.err.println(e.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取rgb数据
|
||||||
|
imageInfo.setRgbData(((DataBufferByte) (dstImage.getRaster().getDataBuffer())).getData());
|
||||||
|
return imageInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static File getNetUrlHttp(String path){
|
||||||
|
//对本地文件命名,path是http的完整路径,主要得到资源的名字
|
||||||
|
String newUrl = path;
|
||||||
|
newUrl = newUrl.split("[?]")[0];
|
||||||
|
String[] bb = newUrl.split("/");
|
||||||
|
//得到最后一个分隔符后的名字
|
||||||
|
String fileName = bb[bb.length - 1];
|
||||||
|
|
||||||
|
//保存到本地的路径
|
||||||
|
String filePath;
|
||||||
|
String os = System.getProperty("os.name");
|
||||||
|
if(StringUtils.startsWith(os.toLowerCase(), "win")){
|
||||||
|
filePath = "D:\\images\\"+fileName;
|
||||||
|
} else {
|
||||||
|
filePath = "/data/real_name/faceDetection/"+fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
File file = null;
|
||||||
|
|
||||||
|
URL urlfile;
|
||||||
|
InputStream inputStream = null;
|
||||||
|
OutputStream outputStream = null;
|
||||||
|
try{
|
||||||
|
//判断文件的父级目录是否存在,不存在则创建
|
||||||
|
file = new File(filePath);
|
||||||
|
if(!file.getParentFile().exists()){
|
||||||
|
file.getParentFile().mkdirs();
|
||||||
|
}
|
||||||
|
try{
|
||||||
|
//创建文件
|
||||||
|
file.createNewFile();
|
||||||
|
}catch (Exception e){
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
//下载
|
||||||
|
urlfile = new URL(newUrl);
|
||||||
|
inputStream = urlfile.openStream();
|
||||||
|
outputStream = new FileOutputStream(file);
|
||||||
|
|
||||||
|
int bytesRead = 0;
|
||||||
|
byte[] buffer = new byte[8192];
|
||||||
|
while ((bytesRead=inputStream.read(buffer,0,8192))!=-1) {
|
||||||
|
outputStream.write(buffer, 0, bytesRead);
|
||||||
|
}
|
||||||
|
}catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}finally {
|
||||||
|
try {
|
||||||
|
if (null != outputStream) {
|
||||||
|
outputStream.close();
|
||||||
|
}
|
||||||
|
if (null != inputStream) {
|
||||||
|
inputStream.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
ArcFaceHelper arcFaceHelper = new ArcFaceHelper();
|
||||||
|
arcFaceHelper.compareFaceFeatures(null,null);
|
||||||
|
}
|
||||||
|
public String compareFaceFeatures(String file,String targetUrl) {
|
||||||
|
// FaceEngine faceEngine = new FaceEngine("D:\\arcsoft_lib_64");
|
||||||
|
// FaceEngine faceEngine = new FaceEngine("/opt/jar/gsks/arcsoft_lib_64");
|
||||||
|
//激活引擎
|
||||||
|
FaceEngine faceEngine = null;
|
||||||
|
int errorCode = 0;
|
||||||
|
try{
|
||||||
|
String os = System.getProperty("os.name");
|
||||||
|
if(StringUtils.startsWith(os.toLowerCase(), "win")){
|
||||||
|
faceEngine = new FaceEngine("D:\\arcsoft_lib_64");
|
||||||
|
//激活引擎
|
||||||
|
faceEngine.activeOnline(APP_ID, WIN64_SDK_KEY);
|
||||||
|
} else {
|
||||||
|
faceEngine = new FaceEngine("/data/lzhdata/arcsoft_lib_64");
|
||||||
|
//激活引擎
|
||||||
|
faceEngine.activeOnline(APP_ID, LINUX64_SDK_KEY);
|
||||||
|
}
|
||||||
|
}catch (Throwable e){
|
||||||
|
System.out.println("加载人脸识别引擎异常:" + e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// int errorCode = faceEngine.activeOnline(APP_ID, WIN64_SDK_KEY);
|
||||||
|
|
||||||
|
if (errorCode != ErrorInfo.MOK.getValue() && errorCode != ErrorInfo.MERR_ASF_ALREADY_ACTIVATED.getValue()) {
|
||||||
|
System.out.println("引擎激活失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ActiveFileInfo activeFileInfo=new ActiveFileInfo();
|
||||||
|
errorCode = faceEngine.getActiveFileInfo(activeFileInfo);
|
||||||
|
if (errorCode != ErrorInfo.MOK.getValue() && errorCode != ErrorInfo.MERR_ASF_ALREADY_ACTIVATED.getValue()) {
|
||||||
|
System.out.println("获取激活文件信息失败");
|
||||||
|
}
|
||||||
|
//引擎配置
|
||||||
|
EngineConfiguration engineConfiguration = new EngineConfiguration();
|
||||||
|
engineConfiguration.setDetectMode(DetectMode.ASF_DETECT_MODE_IMAGE);
|
||||||
|
engineConfiguration.setDetectFaceOrientPriority(DetectOrient.ASF_OP_ALL_OUT);
|
||||||
|
engineConfiguration.setDetectFaceMaxNum(10);
|
||||||
|
engineConfiguration.setDetectFaceScaleVal(16);
|
||||||
|
//功能配置
|
||||||
|
FunctionConfiguration functionConfiguration = new FunctionConfiguration();
|
||||||
|
functionConfiguration.setSupportAge(true);
|
||||||
|
functionConfiguration.setSupportFace3dAngle(true);
|
||||||
|
functionConfiguration.setSupportFaceDetect(true);
|
||||||
|
functionConfiguration.setSupportFaceRecognition(true);
|
||||||
|
functionConfiguration.setSupportGender(true);
|
||||||
|
functionConfiguration.setSupportLiveness(true);
|
||||||
|
functionConfiguration.setSupportIRLiveness(true);
|
||||||
|
engineConfiguration.setFunctionConfiguration(functionConfiguration);
|
||||||
|
//初始化引擎
|
||||||
|
errorCode = faceEngine.init(engineConfiguration);
|
||||||
|
|
||||||
|
if (errorCode != ErrorInfo.MOK.getValue()) {
|
||||||
|
System.out.println("初始化引擎失败");
|
||||||
|
}
|
||||||
|
ImageInfoTwo imageInfo = getRGBDataTwo(new File(targetUrl));
|
||||||
|
List<FaceInfo> faceInfoList = new ArrayList<FaceInfo>();
|
||||||
|
errorCode = faceEngine.detectFaces(imageInfo.getImageData(), imageInfo.getWidth(), imageInfo.getHeight(),
|
||||||
|
imageInfo.getImageFormat(), faceInfoList);
|
||||||
|
System.out.println(faceInfoList);
|
||||||
|
if (faceInfoList.isEmpty()){
|
||||||
|
faceEngine.unInit();
|
||||||
|
return "不符合特征值";
|
||||||
|
}
|
||||||
|
//特征提取2
|
||||||
|
FaceFeature faceFeature = new FaceFeature();
|
||||||
|
errorCode = faceEngine.extractFaceFeature(imageInfo.getImageData(), imageInfo.getWidth(), imageInfo.getHeight(),
|
||||||
|
imageInfo.getImageFormat(), faceInfoList.get(0), faceFeature);
|
||||||
|
System.out.println("特征值大小:" + faceFeature.getFeatureData().length);
|
||||||
|
//人脸检测2
|
||||||
|
ImageInfoTwo imageInfo2 = getRGBDataTwo(new File(file));
|
||||||
|
List<FaceInfo> faceInfoList2 = new ArrayList<FaceInfo>();
|
||||||
|
errorCode = faceEngine.detectFaces(imageInfo2.getImageData(), imageInfo2.getWidth(), imageInfo2.getHeight(),
|
||||||
|
imageInfo2.getImageFormat(), faceInfoList2);
|
||||||
|
System.out.println(faceInfoList2);
|
||||||
|
if (faceInfoList2.isEmpty()) {
|
||||||
|
faceEngine.unInit();
|
||||||
|
return "不符合特征值";
|
||||||
|
}
|
||||||
|
|
||||||
|
//特征提取2
|
||||||
|
FaceFeature faceFeature2 = new FaceFeature();
|
||||||
|
errorCode = faceEngine.extractFaceFeature(imageInfo2.getImageData(), imageInfo2.getWidth(), imageInfo2.getHeight(),
|
||||||
|
imageInfo2.getImageFormat(), faceInfoList2.get(0), faceFeature2);
|
||||||
|
System.out.println("特征值大小:" + faceFeature2.getFeatureData().length);
|
||||||
|
|
||||||
|
//特征比对
|
||||||
|
FaceFeature targetFaceFeature = new FaceFeature();
|
||||||
|
targetFaceFeature.setFeatureData(faceFeature.getFeatureData());
|
||||||
|
FaceFeature sourceFaceFeature = new FaceFeature();
|
||||||
|
sourceFaceFeature.setFeatureData(faceFeature2.getFeatureData());
|
||||||
|
FaceSimilar faceSimilar = new FaceSimilar();
|
||||||
|
|
||||||
|
errorCode = faceEngine.compareFaceFeature(targetFaceFeature, sourceFaceFeature, faceSimilar);
|
||||||
|
|
||||||
|
System.out.println("相似度:" + faceSimilar.getScore());
|
||||||
|
|
||||||
|
//设置活体测试
|
||||||
|
errorCode = faceEngine.setLivenessParam(0.5f, 0.7f);
|
||||||
|
//人脸属性检测
|
||||||
|
FunctionConfiguration configuration = new FunctionConfiguration();
|
||||||
|
configuration.setSupportAge(true);
|
||||||
|
configuration.setSupportFace3dAngle(true);
|
||||||
|
configuration.setSupportGender(true);
|
||||||
|
configuration.setSupportLiveness(true);
|
||||||
|
errorCode = faceEngine.process(imageInfo2.getImageData(), imageInfo2.getWidth(), imageInfo2.getHeight(),
|
||||||
|
imageInfo2.getImageFormat(), faceInfoList2, configuration);
|
||||||
|
|
||||||
|
//活体检测
|
||||||
|
List<LivenessInfo> livenessInfoList = new ArrayList<LivenessInfo>();
|
||||||
|
errorCode = faceEngine.getLiveness(livenessInfoList);
|
||||||
|
System.out.println("活体:" + livenessInfoList.get(0).getLiveness());
|
||||||
|
|
||||||
|
if (livenessInfoList.get(0).getLiveness() > 0){
|
||||||
|
if (faceSimilar.getScore() > 0.8){
|
||||||
|
faceEngine.unInit();
|
||||||
|
return "符合特征值";
|
||||||
|
}else{
|
||||||
|
faceEngine.unInit();
|
||||||
|
return "不符合特征值";
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
faceEngine.unInit();
|
||||||
|
return "不符合特征值";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ImageInfoTwo getRGBDataTwo(File file) {
|
||||||
|
if (file == null){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
ImageInfoTwo imageInfo = new ImageInfoTwo();
|
||||||
|
try {
|
||||||
|
//将图片文件加载到内存缓冲区
|
||||||
|
BufferedImage image = ImageIO.read(file);
|
||||||
|
imageInfo = bufferedImage2ImageInfoTwo(image);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return imageInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ImageInfoTwo bufferedImage2ImageInfoTwo(BufferedImage image) {
|
||||||
|
ImageInfoTwo imageInfo = new ImageInfoTwo();
|
||||||
|
int width = image.getWidth();
|
||||||
|
int height = image.getHeight();
|
||||||
|
width &= -4;
|
||||||
|
height &= -4;
|
||||||
|
imageInfo.setWidth(width);
|
||||||
|
imageInfo.setHeight(height);
|
||||||
|
BufferedImage resultImage = new BufferedImage(width, height, image.getType());
|
||||||
|
int[] rgb = image.getRGB(0, 0, width, height, (int[])null, 0, width);
|
||||||
|
resultImage.setRGB(0, 0, width, height, rgb, 0, width);
|
||||||
|
BufferedImage dstImage = new BufferedImage(width, height, 5);
|
||||||
|
if (resultImage.getType() != 5) {
|
||||||
|
ColorSpace cs = ColorSpace.getInstance(1004);
|
||||||
|
ColorConvertOp colorConvertOp = new ColorConvertOp(cs, dstImage.createGraphics().getRenderingHints());
|
||||||
|
colorConvertOp.filter(resultImage, dstImage);
|
||||||
|
} else {
|
||||||
|
dstImage = resultImage;
|
||||||
|
}
|
||||||
|
|
||||||
|
imageInfo.setImageFormat(ImageFormat.CP_PAF_BGR24);
|
||||||
|
imageInfo.setImageData(((DataBufferByte)((DataBufferByte)dstImage.getRaster().getDataBuffer())).getData());
|
||||||
|
return imageInfo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
package com.bonus.canteen.core.customer.utils;
|
||||||
|
|
||||||
|
public class FaceResult {
|
||||||
|
|
||||||
|
private Integer age;
|
||||||
|
private Integer sex;
|
||||||
|
private byte[] features;
|
||||||
|
|
||||||
|
public Integer getAge() {
|
||||||
|
return age;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAge(Integer age) {
|
||||||
|
this.age = age;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getSex() {
|
||||||
|
return sex;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSex(Integer sex) {
|
||||||
|
this.sex = sex;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] getFeatures() {
|
||||||
|
return features;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFeatures(byte[] features) {
|
||||||
|
this.features = features;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
package com.bonus.canteen.core.customer.utils;
|
||||||
|
|
||||||
|
public class ImageInfo {
|
||||||
|
|
||||||
|
private byte[] rgbData;
|
||||||
|
private int width;
|
||||||
|
private int height;
|
||||||
|
|
||||||
|
public byte[] getRgbData() {
|
||||||
|
return rgbData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRgbData(byte[] rgbData) {
|
||||||
|
this.rgbData = rgbData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getWidth() {
|
||||||
|
return width;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWidth(int width) {
|
||||||
|
this.width = width;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getHeight() {
|
||||||
|
return height;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHeight(int height) {
|
||||||
|
this.height = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,56 @@
|
||||||
|
package com.bonus.canteen.core.customer.utils;
|
||||||
|
|
||||||
|
import com.arcsoft.face.enums.ImageFormat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FileName: ImageInfoTwo
|
||||||
|
*
|
||||||
|
* @author tqzhang
|
||||||
|
* Date: 2024/5/21 13:10
|
||||||
|
* Description:
|
||||||
|
*/
|
||||||
|
public class ImageInfoTwo {
|
||||||
|
private byte[] imageData;
|
||||||
|
private Integer width;
|
||||||
|
private Integer height;
|
||||||
|
private ImageFormat imageFormat;
|
||||||
|
|
||||||
|
public ImageInfoTwo() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] getImageData() {
|
||||||
|
if (this.imageData == null) {
|
||||||
|
this.imageData = new byte[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.imageData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setImageData(byte[] imageData) {
|
||||||
|
this.imageData = imageData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getWidth() {
|
||||||
|
return this.width;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWidth(Integer width) {
|
||||||
|
this.width = width;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getHeight() {
|
||||||
|
return this.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHeight(Integer height) {
|
||||||
|
this.height = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ImageFormat getImageFormat() {
|
||||||
|
return this.imageFormat;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setImageFormat(ImageFormat imageFormat) {
|
||||||
|
this.imageFormat = imageFormat;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -8,7 +8,8 @@ public enum FaceVerTypeEnum {
|
||||||
FACE_VER_UF("30", "宇泛闸机"),
|
FACE_VER_UF("30", "宇泛闸机"),
|
||||||
FACE_VER_3288("3288", "旷视3288"),
|
FACE_VER_3288("3288", "旷视3288"),
|
||||||
FACE_VER_3568("3568", "旷视3568"),
|
FACE_VER_3568("3568", "旷视3568"),
|
||||||
FACE_VER_1109("1109", "旷视1109");
|
FACE_VER_1109("1109", "旷视1109"),
|
||||||
|
FACE_VER_ARC("5", "虹软识别");
|
||||||
|
|
||||||
private final String key;
|
private final String key;
|
||||||
private final String desc;
|
private final String desc;
|
||||||
|
|
@ -46,6 +47,6 @@ public enum FaceVerTypeEnum {
|
||||||
|
|
||||||
// $FF: synthetic method
|
// $FF: synthetic method
|
||||||
private static FaceVerTypeEnum[] $values() {
|
private static FaceVerTypeEnum[] $values() {
|
||||||
return new FaceVerTypeEnum[]{FACE_VER_BIT, FACE_VER_UF, FACE_VER_3288, FACE_VER_3568, FACE_VER_1109};
|
return new FaceVerTypeEnum[]{FACE_VER_BIT, FACE_VER_UF, FACE_VER_3288, FACE_VER_3568, FACE_VER_1109,FACE_VER_ARC};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue