master
周宇恒 2024-02-16 18:29:34 +08:00
parent 4e92556e24
commit 384b18e728
22 changed files with 724 additions and 16 deletions

View File

@ -64,6 +64,12 @@
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<exclusions>
<exclusion>
<artifactId>logback-classic</artifactId>
<groupId>ch.qos.logback</groupId>
</exclusion>
</exclusions>
</dependency>
<!-- Hibernate Validator -->
<dependency>
@ -91,17 +97,19 @@
<groupId>com.aliyun</groupId>
<artifactId>dysmsapi20170525</artifactId>
<version>2.0.1</version>
<exclusions>
<exclusion>
<artifactId>bcpkix-jdk15on</artifactId>
<groupId>org.bouncycastle</groupId>
</exclusion>
</exclusions>
</dependency>
<!-- rabbitMQ -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.2.1</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
@ -117,11 +125,7 @@
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
<version>2.8.1</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
@ -129,9 +133,32 @@
</dependency>
<!-- 人脸-->
<dependency>
<groupId>com.baidu.aip</groupId>
<artifactId>java-sdk</artifactId>
<version>4.12.0</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.9.1</version> <!-- 使用你需要的 OkHttp 版本 -->
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.30</version>
</dependency>
</dependencies>

View File

@ -13,6 +13,11 @@ public class RabbitMQQueueNameConstants {
*/
public static final String SEND_SMS_QUEUE_NAME = "send_sms_queue";
/**
*
*/
public static final String FACE_CONTROLS = "face_controls";
/**
*
*/

View File

@ -0,0 +1,17 @@
package com.zyh.common.domain;
import cn.hutool.db.DaoTemplate;
import lombok.Data;
import java.util.Date;
@Data
public class Alarm {
private Integer id;
private String address;
private String name;
private Date time;
private Integer status;
private String cameraId;
}

View File

@ -0,0 +1,20 @@
package com.zyh.common.domain;
import lombok.Data;
import java.util.Date;
@Data
public class FaceControls {
private Integer id;
private String name;
private String object;
private String startTime;
private String endTime;
private Integer type;
private String pic;
private Integer similarity;
private String remark;
}

View File

@ -0,0 +1,79 @@
package com.zyh.common.face;
import com.baidu.aip.util.Base64Util;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class FaceMatchUtil {
public static float matchImages(String imageUrl1, String imageUrl2) {
try {
byte[] bytes1 = readImageFromUrl(imageUrl1);
byte[] bytes2 = readImageFromUrl(imageUrl2);
List<Map<String, Object>> images = new ArrayList<>();
Map<String, Object> map1 = createImageMap(Base64Util.encode(bytes1), "IDCARD");
Map<String, Object> map2 = createImageMap(Base64Util.encode(bytes2), "LIVE");
images.add(map1);
images.add(map2);
String param = GsonUtils.toJson(images);
String accessToken = GetAccessToken.getAuth();
String result = HttpUtil.post("https://aip.baidubce.com/rest/2.0/face/v3/match", accessToken, "application/json", param);
return parseScore(result);
} catch (Exception e) {
e.printStackTrace();
return 0.0f;
}
}
private static byte[] readImageFromUrl(String imageUrl) throws IOException {
URL url = new URL(imageUrl);
try (InputStream inputStream = url.openStream();
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
byteArrayOutputStream.write(buffer, 0, bytesRead);
}
return byteArrayOutputStream.toByteArray();
}
}
private static Map<String, Object> createImageMap(String image, String faceType) {
Map<String, Object> map = new HashMap<>();
map.put("image", image);
map.put("image_type", "BASE64");
map.put("face_type", faceType);
map.put("quality_control", "LOW");
map.put("liveness_control", "NONE");
return map;
}
private static float parseScore(String result) {
try {
Map<String, Object> resultMap = GsonUtils.fromJson(result, Map.class);
Map<String, Object> resultData = (Map<String, Object>) resultMap.get("result");
float score = Float.parseFloat(resultData.get("score").toString());
return score;
} catch (Exception e) {
e.printStackTrace();
return 0.0f;
}
}
}

View File

@ -0,0 +1,58 @@
package com.zyh.common.face;
import okhttp3.*;
import java.io.IOException;
public class GetAccessToken {
private static String accessToken; // 存储缓存的 access_token
private static long tokenExpirationTime; // 存储 access_token 的过期时间
public static final String API_KEY = "w8Pq8koRUlyh9NgHfjzuDdFZ";
public static final String SECRET_KEY = "TbIOz63AWQFXSgbP2urk0v34zdyPUac7";
static final OkHttpClient HTTP_CLIENT = new OkHttpClient().newBuilder().build();
public static void main(String[] args) throws Exception {
String accessToken = getAuth();
System.out.println("Access Token: " + accessToken);
}
public static String getAuth() throws Exception {
if (accessToken != null && System.currentTimeMillis() < tokenExpirationTime) {
// 如果缓存的 access_token 仍然有效,则直接返回缓存的值
return accessToken;
}
// 缓存的 access_token 已过期或为空,重新获取
MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
RequestBody body = RequestBody.create(
mediaType,
"grant_type=client_credentials&client_id=" + API_KEY + "&client_secret=" + SECRET_KEY
);
Request request = new Request.Builder()
.url("https://aip.baidubce.com/oauth/2.0/token")
.post(body)
.addHeader("Content-Type", "application/x-www-form-urlencoded")
.build();
try (Response response = HTTP_CLIENT.newCall(request).execute()) {
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
String responseBody = response.body().string();
accessToken = parseAccessToken(responseBody);
// 设置新的过期时间假设百度AI的 access_token 有效期是30天
tokenExpirationTime = System.currentTimeMillis() + 30 * 24 * 60 * 60 * 1000;
return accessToken;
}
}
private static String parseAccessToken(String responseBody) {
// 使用 JSON 解析库解析响应体,提取出 Access Token
// 这里使用的是 org.json.JSONObject你也可以选择其他 JSON 解析库
org.json.JSONObject jsonObject = new org.json.JSONObject(responseBody);
return jsonObject.getString("access_token");
}
}

View File

@ -0,0 +1,29 @@
/*
* Copyright (C) 2017 Baidu, Inc. All Rights Reserved.
*/
package com.zyh.common.face;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonParseException;
import java.lang.reflect.Type;
/**
* Json.
*/
public class GsonUtils {
private static Gson gson = new GsonBuilder().create();
public static String toJson(Object value) {
return gson.toJson(value);
}
public static <T> T fromJson(String json, Class<T> classOfT) throws JsonParseException {
return gson.fromJson(json, classOfT);
}
public static <T> T fromJson(String json, Type typeOfT) throws JsonParseException {
return (T) gson.fromJson(json, typeOfT);
}
}

View File

@ -0,0 +1,77 @@
package com.zyh.common.face;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;
import java.util.Map;
/**
* http
*/
public class HttpUtil {
public static String post(String requestUrl, String accessToken, String params)
throws Exception {
String contentType = "application/x-www-form-urlencoded";
return HttpUtil.post(requestUrl, accessToken, contentType, params);
}
public static String post(String requestUrl, String accessToken, String contentType, String params)
throws Exception {
String encoding = "UTF-8";
if (requestUrl.contains("nlp")) {
encoding = "GBK";
}
return HttpUtil.post(requestUrl, accessToken, contentType, params, encoding);
}
public static String post(String requestUrl, String accessToken, String contentType, String params, String encoding)
throws Exception {
String url = requestUrl + "?access_token=" + accessToken;
return HttpUtil.postGeneralUrl(url, contentType, params, encoding);
}
public static String postGeneralUrl(String generalUrl, String contentType, String params, String encoding)
throws Exception {
URL url = new URL(generalUrl);
// 打开和URL之间的连接
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
// 设置通用的请求属性
connection.setRequestProperty("Content-Type", contentType);
connection.setRequestProperty("Connection", "Keep-Alive");
connection.setUseCaches(false);
connection.setDoOutput(true);
connection.setDoInput(true);
// 得到请求的输出流对象
DataOutputStream out = new DataOutputStream(connection.getOutputStream());
out.write(params.getBytes(encoding));
out.flush();
out.close();
// 建立实际的连接
connection.connect();
// 获取所有响应头字段
Map<String, List<String>> headers = connection.getHeaderFields();
// 遍历所有的响应头字段
for (String key : headers.keySet()) {
System.err.println(key + "--->" + headers.get(key));
}
// 定义 BufferedReader输入流来读取URL的响应
BufferedReader in = null;
in = new BufferedReader(
new InputStreamReader(connection.getInputStream(), encoding));
String result = "";
String getLine;
while ((getLine = in.readLine()) != null) {
result += getLine;
}
in.close();
System.err.println("result:" + result);
return result;
}
}

View File

@ -23,9 +23,4 @@ spring:
fileExtension: yml
shared-configs:
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
# Elasticsearch
#es:
# host: 152.136.54.230
# port: 9200
# scheme: http

View File

@ -52,6 +52,13 @@ public class ComprefaceServicempl implements ComprefaceService {
});
rabbitTemplate.convertAndSend(RabbitMQQueueNameConstants.FACE_CONTROLS, bytes, message -> {
message.getMessageProperties().setMessageId(UUID.randomUUID().toString().replaceAll("-", ""));
message.getMessageProperties().setHeader("cameraId", cameraId); // 设置消息头中的相机ID
return message;
});
return Result.success(data);
}

View File

@ -40,7 +40,6 @@
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- Mybatis 依赖配置 -->
<dependency>

View File

@ -0,0 +1,29 @@
package com.zyh.system.controller;
import com.zyh.common.domain.Alarm;
import com.zyh.common.result.Result;
import com.zyh.system.service.AlarmService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("alarm")
public class AlarmController {
@Autowired
private AlarmService alarmService;
//查询告警
@PostMapping("getAlarm")
public Result<List<Alarm>> getAlarm() {
return alarmService.getAlarm();
}
//删除告警
@PostMapping("deleteAlarm")
public Result deleteAlarm(@RequestParam Integer id) {
return alarmService.deleteAlarm(id);
}
}

View File

@ -0,0 +1,45 @@
package com.zyh.system.controller;
import com.zyh.common.domain.FaceControls;
import com.zyh.common.result.Result;
import com.zyh.system.service.FaceControlsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("face")
public class FaceControlsController {
@Autowired
private FaceControlsService faceControlsService;
// 添加人脸控制
@PostMapping("addFaceControls")
public Result addFaceControls(@RequestBody FaceControls faceControls) {
return faceControlsService.addFaceControls(faceControls);
}
// 删除人脸控制
@PostMapping("deleteFaceControls")
public Result deleteFaceControls(@RequestParam Integer id) {
return faceControlsService.deleteFaceControls(id);
}
// 修改人脸控制
@PostMapping("updateFaceControls")
public Result updateFaceControls(@RequestBody FaceControls faceControls) {
return faceControlsService.updateFaceControls(faceControls);
}
// 查询人脸控制
@PostMapping("getFaceControls")
public Result<List<FaceControls>> getFaceControls() {
return faceControlsService.getFaceControls();
}
}

View File

@ -0,0 +1,19 @@
package com.zyh.system.mapper;
import com.zyh.common.domain.Alarm;
import com.zyh.common.domain.Camera;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface AlarmMapper {
List<Alarm> getAlarm();
Integer addAlarm(Alarm alarm);
Camera selectCamera(@Param("cameraId") String cameraId);
Integer deleteAlarm(@Param("id") Integer id);
}

View File

@ -0,0 +1,21 @@
package com.zyh.system.mapper;
import com.zyh.common.domain.FaceControls;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface FaceControlsMapper {
Integer addFaceControls(FaceControls faceControls);
Integer deleteFaceControls(@Param("id") Integer id);
Integer updateFaceControls(FaceControls faceControls);
List<FaceControls> getFaceControls();
List<String> getFaceControlsPic();
}

View File

@ -0,0 +1,79 @@
package com.zyh.system.mq;
import com.baidu.aip.util.Base64Util;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.rabbitmq.client.Channel;
import com.zyh.common.constants.RabbitMQQueueNameConstants;
import com.zyh.common.domain.Alarm;
import com.zyh.common.domain.CompreFaceApiResponse;
import com.zyh.common.face.FaceMatchUtil;
import com.zyh.common.result.Result;
import com.zyh.common.util.ComprefaceUtils;
import com.zyh.system.service.AlarmService;
import com.zyh.system.service.FaceControlsService;
import lombok.extern.log4j.Log4j2;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import java.util.List;
@Component
@Log4j2
public class FaceControlsConsumer {
@Autowired
private AlarmService alarmService;
@Autowired
private FaceControlsService faceControlsService;
@Autowired
RedisTemplate<String, String> redisTemplate;
@RabbitListener(queuesToDeclare = {@Queue(RabbitMQQueueNameConstants.FACE_CONTROLS)})
public void SendCodeMq(byte[] bytes, Message message, Channel channel) throws JsonProcessingException {
long l = System.currentTimeMillis();
log.info("短信消费者队列开始消费...,消费内容为:{}", bytes);
String messageId = message.getMessageProperties().getMessageId();
String cameraId = message.getMessageProperties().getHeaders().get("cameraId").toString();
try {
Long count = redisTemplate.opsForSet().add(RabbitMQQueueNameConstants.FACE_CONTROLS, messageId);
if (count == 1) {
float num = 0;
Result<CompreFaceApiResponse.Result> result = ComprefaceUtils.recognizeFace(bytes);
CompreFaceApiResponse.Result data = result.getData();
String encode = Base64Util.encode(bytes);
List<String> pics = faceControlsService.getFaceControlsPic();
for (String pic : pics) {
float v = FaceMatchUtil.matchImages(encode, pic);
if (v > num) { // 如果当前v的值大于num则更新num的值为v
num = v;
}
}
if (num > 0.95) {
alarmService.addAlarm(data,cameraId);
}
log.info("短信消费者队列消费成功,耗时:{}毫秒!", System.currentTimeMillis()-l);
}else{
log.info("短信消费者队列重复消费,消费内容为:{}", bytes);
}
} catch (Exception e) {
log.info("短信消费者队列消费失败,异常内容为:{}", e.getMessage());
redisTemplate.opsForSet().remove(RabbitMQQueueNameConstants.FACE_CONTROLS, messageId);
try {
channel.basicReject(message.getMessageProperties().getDeliveryTag(),true);
} catch (Exception ex) {
log.info("短信消费者队列回退失败,异常内容为:{}", ex.getMessage());
}
}
}
}

View File

@ -0,0 +1,15 @@
package com.zyh.system.service;
import com.zyh.common.domain.Alarm;
import com.zyh.common.domain.CompreFaceApiResponse;
import com.zyh.common.result.Result;
import java.util.List;
public interface AlarmService {
Result<List<Alarm>> getAlarm();
Result addAlarm(CompreFaceApiResponse.Result data,String cameraId);
Result deleteAlarm(Integer id);
}

View File

@ -0,0 +1,19 @@
package com.zyh.system.service;
import com.zyh.common.domain.FaceControls;
import com.zyh.common.result.Result;
import java.util.List;
public interface FaceControlsService {
Result addFaceControls(FaceControls faceControls);
Result deleteFaceControls(Integer id);
Result updateFaceControls(FaceControls faceControls);
Result<List<FaceControls>> getFaceControls();
List<String> getFaceControlsPic();
}

View File

@ -0,0 +1,52 @@
package com.zyh.system.service.impl;
import com.zyh.common.domain.Alarm;
import com.zyh.common.domain.Camera;
import com.zyh.common.domain.CompreFaceApiResponse;
import com.zyh.common.result.Result;
import com.zyh.system.mapper.AlarmMapper;
import com.zyh.system.service.AlarmService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class AlarmServicempl implements AlarmService {
@Autowired
private AlarmMapper alarmMapper;
@Override
public Result<List<Alarm>> getAlarm() {
List<Alarm> list = alarmMapper.getAlarm();
if (list.size() == 0) {
return Result.error("未查询到数据");
}
return Result.success(list);
}
@Override
public Result addAlarm(CompreFaceApiResponse.Result data, String cameraId) {
Camera camera = alarmMapper.selectCamera(cameraId);
Alarm alarm = new Alarm();
alarm.setName(data.getSubjects().get(0).getSubject());
alarm.setAddress(camera.getAddress());
alarm.setCameraId(cameraId);
Integer integer = alarmMapper.addAlarm(alarm);
if (integer > 0) {
return Result.success("添加成功");
}
return Result.error("添加失败");
}
@Override
public Result deleteAlarm(Integer id) {
Integer integer = alarmMapper.deleteAlarm(id);
if (integer > 0) {
return Result.success("删除成功");
}
return Result.error("删除失败");
}
}

View File

@ -0,0 +1,60 @@
package com.zyh.system.service.impl;
import com.zyh.common.domain.FaceControls;
import com.zyh.common.result.Result;
import com.zyh.system.mapper.FaceControlsMapper;
import com.zyh.system.service.FaceControlsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class FaceControlsServicempl implements FaceControlsService {
@Autowired
private FaceControlsMapper faceControlsMapper;
@Override
public Result addFaceControls(FaceControls faceControls) {
Integer add=faceControlsMapper.addFaceControls(faceControls);
if(add>0){
return Result.success("新增成功");
}
return Result.error("新增失败");
}
@Override
public Result deleteFaceControls(Integer id) {
Integer delete=faceControlsMapper.deleteFaceControls(id);
if(delete>0){
return Result.success("删除成功");
}
return Result.error("删除失败");
}
@Override
public Result updateFaceControls(FaceControls faceControls) {
Integer update=faceControlsMapper.updateFaceControls(faceControls);
if(update>0){
return Result.success("修改成功");
}
return Result.error("修改失败");
}
@Override
public Result<List<FaceControls>> getFaceControls() {
List<FaceControls> faceControls=faceControlsMapper.getFaceControls();
if(faceControls!=null){
return Result.success(faceControls,"查询成功");
}
return Result.error("查询失败");
}
@Override
public List<String> getFaceControlsPic() {
return faceControlsMapper.getFaceControlsPic();
}
}

View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.zyh.system.mapper.AlarmMapper">
<insert id="addAlarm">
insert into alarm
values (0,
#{address},
#{name},
now(),
1)
</insert>
<delete id="deleteAlarm">
delete from alarm where id=#{id}
</delete>
<select id="getAlarm" resultType="com.zyh.common.domain.Alarm">
select * from alarm
</select>
<select id="selectCamera" resultType="com.zyh.common.domain.Camera">
select * from camera where camera_id=#{cameraId}
</select>
</mapper>

View File

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.zyh.system.mapper.FaceControlsMapper">
<insert id="addFaceControls">
insert into facecontrols
values (0,
#{name},
#{object},
#{startTime},
#{endTime},
#{type},
#{pic},
#{similarity},
#{remark})
</insert>
<update id="updateFaceControls">
update facecontrols set
name=#{name},object=#{object},start_time=#{startTime},end_time=#{endTime},type=#{type},pic=#{pic},similarity=#{similarity},remark=#{remark}
where id=#{id}
</update>
<delete id="deleteFaceControls">
delete from facecontrols where id=#{id}
</delete>
<select id="getFaceControls" resultType="com.zyh.common.domain.FaceControls">
select * from facecontrols
</select>
<select id="getFaceControlsPic" resultType="java.lang.String">
select pic from facecontrols
</select>
</mapper>