一、前言
- 建議使用低版本 SDK : Baidu_Face_Offline_SDK_Windows_Java_6.1.3
- 目前已知8.x版本對服務端不兼容,存在運行程序中,第一次呼叫sdk能夠正常執行,第二次時出現JVM例外,
- SDK不支持多執行緒,一般都用于設備端,如人臉閘機上的面板機設備,
- 自定義庫檔案路徑,與專案分離,
- 整合springBoot專案,實作啟動初始化SDK,按需呼叫,
二、SDK 引入并配置
- 解壓程式,查看對應作業系統的檔案夾,將src目錄下的檔案移動到我們的專案中,請不要修改此目錄結構,
- 給Face.java類添加注解,實作條件實體化,
@Slf4j
@Component
@Conditional(FaceSdkEnableCondition.class)
public class Face {
// *******以下為人臉sdk api介面*********
- 修改Face.java類加載庫的方式,以及初始化,
- 新增 Environment 類動態獲取庫路徑,
- 更換 System.load() 加載庫檔案,
- 使用
@PostConstruct注解,當類物件被創建時,自動完成初始化作業, - 使用
@PreDestroy注解,當類物件被銷毀時,自動完成釋放記憶體作業,
// ********* 以下為系統加載庫檔案及opencv **********
private static String libPath;
public Face(){ }
@Autowired
public Face(Environment env) {
// 初始化libPath
libPath = env.getProperty("face-sdk.libPath",String.class);
// 加載dll檔案
System.load(libPath + "BaiduFaceApi.dll");
System.load(libPath + "opencv_java320.dll");
}
Face api = null;
/* sdk初始化 */
@PostConstruct
public void init() {
log.info("離線SDK開始初始化");
log.info("SDK路徑:{}",libPath);
api = new Face();
int res = api.sdkInit(libPath);
if (res != 0) {
log.info("sdk init fail and error = {}\n", res);
return;
}
log.info("離線SDK初始化完成");
}
/* sdk釋放記憶體 */
@PreDestroy
private void destroy() {
if(api != null){
api.sdkDestroy();
}
log.info("離線SDK銷毀");
}
- 配置條件啟動類相關
package cn.dyina.config;
public class FaceSdkEnableCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
Environment env = context.getEnvironment();
// 根據face-sdk.enable屬性來決定是否創建 Face bean
return "true".equals(env.getProperty("face-sdk.enable"));
}
}
-
配置路徑存放庫檔案
face-sdk: enable: true # 路徑請務必使用雙斜桿 libPath: D:\\FaceLib\\ imagesPath: D:\\FaceImages\\- 請將SDK檔案的所有.dll檔案拷貝到
libPath目錄下, - 請將SDK檔案下的opencv-jar、models、license檔案夾拷貝到
libPath目錄下, - 請登錄 百度智能云 控制中心,注冊并獲取離線識別SDK序列號,替換license\license.key內的序列號,
- 請將SDK檔案的所有.dll檔案拷貝到
-
安裝maven依賴,以解決打包例外
- 請修改并在專案終端執行以下的命令,將opencv-jar下的opencv-320.jar依賴安裝到maven倉庫,
mvn install:install-file -DgroupId=cn.dyina(jar包的groupId) -DartifactId=opencv-jar(jar包的artifactId) -Dversion=1.0(jar的版本號) -Dpackaging=jar -Dfile=D:\FaceLib\opencv-jar\opencv-320.jar(jar包的具體路徑)- 添加maven依賴
<!-- 本地依賴 opencv-jar--> <dependency> <groupId>cn.dyina</groupId> <artifactId>opencv-jar</artifactId> <version>1.0</version> </dependency>
三、專案使用
- 在SpringBoot啟動類上,添加包掃描,
@SpringBootApplication(scanBasePackages = {"cn.dyina","com.jni"})
public class SpringBootBaiDuFaceSdkApplication {
//...
}
- 撰寫service、controller,(以下示例代碼僅提供參考,請根據自己的業務需求進行撰寫,)
@Slf4j
@Service
public class FaceService {
@Value("${face-sdk.imagesPath}")
String imagesPath;
public String registerFace(String fileName, String nickName) {
// 注冊人臉圖片
String ip_nickName = fileName.replaceFirst("[.][^.]+$", "");
// 獲取人臉特征值
Mat mat = Imgcodecs.imread(imagesPath + fileName);
long matAddr = mat.getNativeObjAddr();
// 填充人臉資訊 后期將從資料庫獲取
String userInfo = nickName;
String userId = ip_nickName.replace(".","");
String groupId = "Face";
// 用人臉特征值注冊
JSONObject res = JSONObject.parseObject(Face.userAddByMat(matAddr, userId, groupId, userInfo));
log.info("user add result is:{}", res);
return res.getString("msg");
}
public String identifyFace(String fileName) {
// 呼叫人臉sdkAPI
Face.loadDbFace();
Mat mat1 = Imgcodecs.imread(imagesPath + fileName);
long mat1Addr = mat1.getNativeObjAddr();
int type = 0;
// 和人臉庫里面的人臉特征值比較(人臉識別)
JSONObject res = JSONObject.parseObject(Face.identifyWithAllByMat(mat1Addr, type));
log.info("identify res is:{}", res);
if (!res.getString("errno").equals("0")) {
return res.getString("msg");
}
// 獲取人臉識別資訊
double score = res.getJSONObject("data")
.getJSONArray("result")
.getJSONObject(0)
.getDouble("score");
String userId = res.getJSONObject("data")
.getJSONArray("result")
.getJSONObject(0)
.getString("user_id");
if (score > 80) {
String nickName = userId.split("_")[1];
return nickName;
} else {
log.info("根據圖片獲取人員資訊失敗");
return "Match score is low";
}
}
}
/**
* 人臉識別 頁面相關介面
*/
@Slf4j
@RestController
@CrossOrigin(origins = "*", maxAge = 3600)
public class FaceController {
@Autowired
private FaceService faceService;
@Value("${face-sdk.imagesPath}")
String imagesPath;
/**
* 人臉注冊
* @param file
* @param ip
* @param nickName
* @return
* @throws IOException
*/
@PostMapping("/faceRegister")
public R<String> faceRegister(@RequestParam("photo") MultipartFile file,
@RequestParam("ip") String ip,
@RequestParam("nickName") String nickName) throws IOException {
String photo = Base64.getEncoder().encodeToString(file.getBytes());
String fileName = ip + "_" + nickName + ".jpg";
Base64ToImage.saveImage(imagesPath, fileName, photo);
// 人臉注冊
String res = faceService.registerFace(fileName, nickName);
if(!res.equals("success")){
return R.error(res,null);
}
return R.success(null);
}
/**
* 檢測人臉
* @param photo
* @param ip
* @return
*/
@PostMapping("/faceDetection")
public R<String> faceDetection(@RequestParam("photo") String photo, @RequestParam("ip") String ip) {
String fileName = ip +".jpg"; // 臨時存盤,用于檢測
Base64ToImage.saveImage(imagesPath, fileName, photo);
String res = faceService.identifyFace(fileName);
return R.success(res);
}
/**
* 查詢用戶組人臉
* @param groupId
* @return
*/
@GetMapping("/getAllFace")
public R<List> getAllFace(@RequestParam("groupId") String groupId){
log.info("====>> getAllFace");
List<String> userIdList = faceService.getAllFace(groupId);
return R.success(userIdList);
}
}
后記
-
com.jni.face包下,除了Face.java類,其他都是示例程式,可以視情況洗掉, -
models 檔案夾里的模型可以按情況洗掉,詳細可以查看檔案,
-
專案啟動后,你的控制臺應該會收到SDK初始化的資訊,并且你的
libPath目錄下應該生成db檔案夾,人臉資料將存盤在這里,(db檔案夾將生成在庫檔案所在目錄,洗掉face.db后,初始化SDK時會自動生成,不需要額外操作,) -
有生產需求的,但設備量不多,可以咸魚買序列號,(官網最低100個起購)
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/554753.html
標籤:其他
上一篇:Angular4 教程_編程入門自學教程_菜鳥教程-免費教程分享
下一篇:返回列表
