Java进阶实战:人脸采集识别系统项目完整公开分享
Posted 黑马程序员官方
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java进阶实战:人脸采集识别系统项目完整公开分享相关的知识,希望对你有一定的参考价值。
文章目录
一、人脸采集系统
1.人脸识别
人脸识别技术采用虹软开放平台实现(免费使用)。官网:https://www.arcsoft.com.cn/
1.1、使用说明
使用虹软平台需要先注册开发者账号:https://ai.arcsoft.com.cn/ucenter/user/userlogin
注册完成后进行登录,然后进行创建应用:
创建完成后,需要进行实名认证,否则相关的SDK是不能使用的。
实名认证后即可下载对应平台的SDk,我们需要下载windows以及linux平台。
添加SDK(Linux与Windows平台):
下载SDK,打开解压包,可以看到有提供相应的jar包以及示例代码:
需要特别说明的是:每个账号的SDK包不通用,所以自己要下载自己的SDK包。
1.2、安装jar到本地仓库
进入到libs目录,需要将arcsoft-sdk-face-3.0.0.0.jar安装到本地仓库:
mvn install:install-file -DgroupId=com.arcsoft.face -DartifactId=arcsoft-sdk-face -Dversion=3.0.0.0 -Dpackaging=jar -Dfile=arcsoft-sdk-face-3.0.0.0.jar
安装成功后,即可通过maven坐标引用了:
<dependency>
<groupId>com.arcsoft.face</groupId>
<artifactId>arcsoft-sdk-face</artifactId>
<version>3.0.0.0</version>
<!--<scope>system</scope>-->
<!--如果没有安装到本地仓库,可以将jar包拷贝到工程的lib下面下,直接引用-->
<!--<systemPath>$project.basedir/lib/arcsoft-sdk-face-3.0.0.0.jar</systemPath>-->
</dependency>
1.3、开始使用
说明:虹软的SDK是免费使用的,但是首次使用时需要联网激活,激活后可离线使用。使用周期为1年,1年后需要联网再次激活。
个人免费激活SDK总数量为100。
配置:application.properties
#虹软相关配置(在虹软应用中找到对应的参数)
arcsoft.appid=******************
arcsoft.sdkKey=*****************
arcsoft.libPath=F:\\\\code\\\\WIN64
FaceEngineService:
import com.arcsoft.face.EngineConfiguration;
import com.arcsoft.face.FaceEngine;
import com.arcsoft.face.FaceInfo;
import com.arcsoft.face.FunctionConfiguration;
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 com.arcsoft.face.toolkit.ImageFactory;
import com.arcsoft.face.toolkit.ImageInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
@Service
public class FaceEngineService
private static final Logger LOGGER = LoggerFactory.getLogger(FaceEngineService.class);
@Value("$arcsoft.appid")
private String appid;
@Value("$arcsoft.sdkKey")
private String sdkKey;
@Value("$arcsoft.libPath")
private String libPath;
private FaceEngine faceEngine;
@PostConstruct
public void init()
// 激活并且初始化引擎
FaceEngine faceEngine = new FaceEngine(libPath);
int activeCode = faceEngine.activeOnline(appid, sdkKey);
if (activeCode != ErrorInfo.MOK.getValue() && activeCode != ErrorInfo.MERR_ASF_ALREADY_ACTIVATED.getValue())
LOGGER.error("引擎激活失败");
throw new RuntimeException("引擎激活失败");
//引擎配置
EngineConfiguration engineConfiguration = new EngineConfiguration();
//IMAGE检测模式,用于处理单张的图像数据
engineConfiguration.setDetectMode(DetectMode.ASF_DETECT_MODE_IMAGE);
//人脸检测角度,全角度
engineConfiguration.setDetectFaceOrientPriority(DetectOrient.ASF_OP_ALL_OUT);
//功能配置
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);
//初始化引擎
int initCode = faceEngine.init(engineConfiguration);
if (initCode != ErrorInfo.MOK.getValue())
LOGGER.error("初始化引擎出错!");
throw new RuntimeException("初始化引擎出错!");
this.faceEngine = faceEngine;
/**
* 检测图片是否为人像
*
* @param imageInfo 图像对象
* @return true:人像,false:非人像
*/
public boolean checkIsPortrait(ImageInfo imageInfo)
// 定义人脸列表
List<FaceInfo> faceInfoList = new ArrayList<FaceInfo>();
faceEngine.detectFaces(imageInfo.getImageData(), imageInfo.getWidth(), imageInfo.getHeight(), ImageFormat.CP_PAF_BGR24, faceInfoList);
return !faceInfoList.isEmpty();
public boolean checkIsPortrait(byte[] imageData)
return this.checkIsPortrait(ImageFactory.getRGBData(imageData));
public boolean checkIsPortrait(MultipartFile multipartFile)
try
return this.checkIsPortrait(ImageFactory.getRGBData(multipartFile.getBytes()));
catch(Exception e)
e.printStackTrace();
return false;
public boolean checkIsPortrait(File file)
return this.checkIsPortrait(ImageFactory.getRGBData(file));
#问题:
Caused by: java.lang.UnsatisfiedLinkError: D:\\gongju\\renlian\\haha\\libs\\WIN64\\libarcsoft_face.dll: Can't find dependent libraries
解决:
安装资料中的:vcredist_x64.exe,即可解决。
1.4、测试
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.io.File;
@SpringBootTest
@RunWith(SpringJUnit4ClassRunner.class)
public class TestFaceEngineService
@Autowired
private FaceEngineService faceEngineService;
@Test
public void testCheckIsPortrait()
File file = new File("F:\\\\1.jpg");
boolean checkIsPortrait = this.faceEngineService.checkIsPortrait(file);
System.out.println(checkIsPortrait); // true|false
2.图片上传
2.1、图片存储解决方案
实现图片上传服务,需要有存储的支持,那么我们的解决方案将以下几种:
- 直接将图片保存到服务的硬盘
- 优点:开发便捷,成本低
- 缺点:扩容困难
- 使用分布式文件系统进行存储
- 优点:容易实现扩容
- 缺点:开发复杂度稍大(有成熟的产品可以使用,比如:FastDFS)
- 使用nfs做存储
- 优点:开发较为便捷
- 缺点:需要有一定的运维知识进行部署和维护
- 使用第三方的存储服务
- 优点:开发简单,拥有强大功能,免维护
- 缺点:付费
在本案例中选用阿里云的OSS服务进行图片存储。
2.2、阿里云OSS存储
2.2.1、什么是OSS服务?
地址:https://www.aliyun.com/product/oss
2.2.2、购买服务
使用第三方服务最大的缺点就是需要付费,下面,我们看下如何购买开通服务。
购买下行流量包: (不购买也可以使用,按照流量付费)
说明:OSS的上行流量是免费的,但是下行流量是需要购买的。
2.2.3、创建Bucket
使用OSS,首先需要创建Bucket,Bucket翻译成中文是水桶的意思,把存储的图片资源看做是水,想要盛水必须得有桶,就是这个意思了。
进入控制台,https://oss.console.aliyun.com/overview
选择Bucket后,即可看到对应的信息,如:url、消耗流量等 :
文件管理:
查看文件:
2.2.2.4、创建用户
打开访问控制,需要设置oss权限。
2.2.3、导入依赖
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>2.8.3</version>
</dependency>
2.2.4、OSS配置
aliyun.properties:
aliyun.endpoint = http://oss-cn-beijing.aliyuncs.com
aliyun.accessKeyId = LTAI5tKy8djwYHDaQ3QjpcKJ
aliyun.accessKeySecret = hYSDMNLsEIOqdjsnPtIlzmnfdWB0y11
aliyun.bucketName= itcast-face
aliyun.urlPrefix=http://itcast-face.oss-cn-beijing.aliyuncs.com
AliyunConfig:
import com.aliyun.oss.OSSClient;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
@Configuration
@PropertySource("classpath:aliyun.properties")
@ConfigurationProperties(prefix = "aliyun")
@Data
public class AliyunConfig
private String endpoint;
private String accessKeyId;
private String accessKeySecret;
private String bucketName;
private String urlPrefix;
@Bean
public OSSClient oSSClient()
return new OSSClient(endpoint, accessKeyId, accessKeySecret);
2.2.5、PicUploadService
import com.aliyun.oss.OSSClient;
import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.ByteArrayInputStream;
@Service
public class PicUploadService
// 允许上传的格式
private static final String[] IMAGE_TYPE = new String[]".bmp", ".jpg",
".jpeg", ".gif", ".png";
@Autowired
private OSSClient ossClient;
@Autowired
private AliyunConfig aliyunConfig;
public PicUploadResult upload(MultipartFile uploadFile)
PicUploadResult fileUploadResult = new PicUploadResult();
//图片做校验,对后缀名
boolean isLegal = false;
for (String type : IMAGE_TYPE)
if (StringUtils.endsWithIgnoreCase(uploadFile.getOriginalFilename(),
type))
isLegal = true;
break;
if (!isLegal)
fileUploadResult.setStatus("error");
return fileUploadResult;
// 文件新路径
String fileName = uploadFile.getOriginalFilename();
String filePath = getFilePath(fileName);
// 上传到阿里云
try
// 目录结构:images/2018/12/29/xxxx.jpg
ossClient.putObject(aliyunConfig.getBucketName(), filePath, new
ByteArrayInputStream(uploadFile.getBytes()));
catch (Exception e)
e.printStackTrace();
//上传失败
fileUploadResult.setStatus("error");
return fileUploadResult;
// 上传成功
fileUploadResult.setStatus("done");
fileUploadResult.setName(this.aliyunConfig.getUrlPrefix() + filePath);
fileUploadResult.setUid(String.valueOf(System.currentTimeMillis()));
return fileUploadResult;
private String getFilePath(String sourceFileName)
DateTime dateTime = new DateTime();
return "/images/" + dateTime.toString("yyyy")
+ "/" + dateTime.toString("MM") + "/"
+ dateTime.toString("dd") + "/" + System.currentTimeMillis() +
RandomUtils.nextInt(100, 9999) + "." +
StringUtils.substringAfterLast(sourceFileName, ".");
所需其他的代码:
PicUploadResult:
import lombok.Data;
@Data
public class PicUploadResult
// 文件唯一标识
private String uid;
// 文件名
private String name;
// 状态有:uploading done error removed
private String status;
// 服务端响应内容,如:'"status": "success"'
private String response;
2.2.6、PicUploadController
import com.tanhua.sso.service.PicUploadService;
import com.tanhua.sso.vo.PicUploadResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
@RequestMapping("pic/upload")
@Controller
public class PicUploadController
@Autowired
private PicUploadService picUploadService;
@PostMapping
@ResponseBody
public PicUploadResult upload(@RequestParam("file") MultipartFile multipartFile)
return this.picUploadService.upload(multipartFile);
2.2.7、测试
极智项目 | 实战pytorch arcface人脸识别