Ver Fonte

人脸识别增加人脸box

lihao16 há 1 ano atrás
pai
commit
b7286724cd

+ 1 - 0
inspur-admin/src/main/resources/application-druid.yml

@@ -9,6 +9,7 @@ spring:
                 url: jdbc:mysql://117.73.3.135:3306/partybuild-admin-dt?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
                 # url: jdbc:mysql://127.0.0.1:3306/partybuild-admin-v1.4?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
                 username: root
+                # password: password
                 password: Hycpb@123
             # 从库数据源
             slave:

+ 14 - 0
inspur-admin/src/main/resources/application.yml

@@ -91,6 +91,20 @@ spring:
         # #连接池最大阻塞等待时间(使用负值表示没有限制)
         max-wait: -1ms
 
+  rabbitmq:
+    host: 117.73.13.40
+    port: 5672
+    username: admin
+    password: Hycpb@123
+    publisher-returns: true
+    template:
+      mandatory: true
+    listener:
+      #最小消息监听线程数
+      concurrency: 2
+      #最大消息监听线程数
+      max-concurrency: 2
+
 # token配置
 token:
     # 令牌自定义标识

+ 6 - 0
inspur-ai/pom.xml

@@ -49,6 +49,12 @@
             <artifactId>chatgpt-java</artifactId>
             <version>1.1.5</version>
         </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-amqp</artifactId>
+        </dependency>
+
     </dependencies>
 
 </project>

+ 54 - 2
inspur-ai/src/main/java/com/inspur/face/service/impl/CompreFaceServiceImpl.java

@@ -29,9 +29,14 @@ import org.springframework.stereotype.Service;
 import org.springframework.util.CollectionUtils;
 import org.springframework.web.multipart.MultipartFile;
 
+import javax.imageio.ImageIO;
+import java.awt.*;
+import java.awt.image.BufferedImage;
 import java.io.File;
+import java.io.IOException;
 import java.math.BigDecimal;
 import java.util.*;
+import java.util.List;
 
 import static com.inspur.common.utils.PageUtils.startPage;
 
@@ -238,6 +243,7 @@ public class CompreFaceServiceImpl implements CompreFaceService {
                 opStatus = 2;
                 log.info("recognizeFace error,file:{},rspMsg:{}",fileMap.get("url"),rspMsg);
             }
+            this.box(reqParam.toJSONString(),rspMsg);
         }catch (Exception e) {
             opStatus = 2;
             rspMsg = e.getMessage();
@@ -441,6 +447,52 @@ public class CompreFaceServiceImpl implements CompreFaceService {
         log.info("download file success,file path : {}:" ,filePath);
         return new File(filePath);
     }
-
-
+    private String box(String reqParam, String rspMsg) throws IOException {
+        // PartyFaceRecognition partyFaceRecognition = partyFaceRecognitionMapper.selectPartyFaceRecognitionById(id);
+        JSONObject reqParamJson = JSON.parseObject(reqParam);
+        String sourceFilePath = reqParamJson.getString("filePath");
+        RecognizeFaceRsp result = JSON.parseObject(rspMsg, RecognizeFaceRsp.class);
+        List<RecognizeFaceRspResult> faceRspList = result.getResult();
+        // 加载原始图片
+        BufferedImage originalImage = ImageIO.read(new File(sourceFilePath));
+        // 创建一个和原始图片同样大小的BufferedImage用于绘图
+        BufferedImage resultImage = new BufferedImage(originalImage.getWidth(), originalImage.getHeight(), originalImage.getType());
+        Graphics2D g2d = resultImage.createGraphics();
+        // 将原始图片绘制到结果图片上(如果需要保留原图内容)
+        g2d.drawImage(originalImage, 0, 0, null);
+        // 绘制人脸框
+        for (RecognizeFaceRspResult faceRsp : faceRspList) {
+            RecognizeFaceRspResultBox box = faceRsp.getBox();
+            // 设置线条颜色为红色
+            g2d.setColor(Color.RED);
+            // 设置线条粗细
+            g2d.setStroke(new java.awt.BasicStroke(1));
+            // 横向
+            g2d.drawLine(box.getX_min(),box.getY_min(),box.getX_max(),box.getY_min());
+            g2d.drawLine(box.getX_min(),box.getY_max(),box.getX_max(),box.getY_max());
+            // 竖向
+            g2d.drawLine(box.getX_min(),box.getY_min(),box.getX_min(),box.getY_max());
+            g2d.drawLine(box.getX_max(),box.getY_min(),box.getX_max(),box.getY_max());
+            RecognizeFaceRspResultSubject subject = faceRsp.getSubjects().get(0);
+            BigDecimal similarity = subject.getSimilarity();
+            String subjectName = "";
+            if (similarity.compareTo(new BigDecimal(0.95)) < 0) {
+                subjectName = "未识别";
+            }else {
+                subjectName = subject.getSubject().split("_")[1] + ":" + similarity;
+            }
+            // 设置字体颜色为红色
+            g2d.setColor(Color.RED);
+            // 设置字体大小
+            g2d.setFont(new Font("宋体", Font.BOLD, 20));
+            g2d.drawString(subjectName, box.getX_min(), box.getY_min());
+        }
+        // 保存图片
+        String outputFilePath = sourceFilePath + ".1.png";
+        File outputFile = new File(outputFilePath);
+        ImageIO.write(resultImage, "png", outputFile);
+        // 释放资源(在实际应用中,你可能需要更仔细地管理这些资源)
+        g2d.dispose();
+        return outputFilePath;
+    }
 }

+ 40 - 0
inspur-ai/src/main/java/com/inspur/rabbitmq/MsgTestController.java

@@ -0,0 +1,40 @@
+package com.inspur.rabbitmq;
+
+import com.alibaba.fastjson2.JSON;
+import com.inspur.common.annotation.Anonymous;
+import com.inspur.common.core.domain.AjaxResult;
+import com.inspur.rabbitmq.domain.PartyMQMessage;
+import com.inspur.rabbitmq.producer.PartyMessageProducer;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * 消息发生 test
+ *
+ * @author lihao16
+ */
+@RestController
+@RequestMapping("/mq/test")
+public class MsgTestController {
+
+    @Autowired
+    private PartyMessageProducer partyMessageProducer;
+
+    @PostMapping
+    @Anonymous
+    public AjaxResult producerTest(@RequestBody PartyMQMessage partyMQMessage) {
+        partyMessageProducer.sendMsg(JSON.toJSONString(partyMQMessage));
+        return AjaxResult.success();
+    }
+
+    @PostMapping("tts")
+    @Anonymous
+    public AjaxResult producerTest4Tts(@RequestBody PartyMQMessage partyMQMessage) {
+        partyMessageProducer.sendMsg(JSON.toJSONString(partyMQMessage));
+        return AjaxResult.success();
+    }
+
+}

+ 83 - 0
inspur-ai/src/main/java/com/inspur/rabbitmq/config/RabbitMQConfiguration.java

@@ -0,0 +1,83 @@
+package com.inspur.rabbitmq.config;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.amqp.core.*;
+import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
+import org.springframework.amqp.rabbit.connection.ConnectionFactory;
+import org.springframework.amqp.rabbit.core.RabbitTemplate;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.beans.factory.config.ConfigurableBeanFactory;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Scope;
+
+/**
+ * rabbitmq config
+ *
+ * @author lihao16
+ */
+@Configuration
+@Slf4j
+public class RabbitMQConfiguration {
+
+    @Value("${spring.rabbitmq.host}")
+    private String host;
+
+    @Value("${spring.rabbitmq.port}")
+    private int port;
+
+    @Value("${spring.rabbitmq.username}")
+    private String username;
+
+    @Value("${spring.rabbitmq.password}")
+    private String password;
+
+    public static final String PARTY_MQ_EXCHANGE = "party-mq-exchange";
+
+    public static final String PARTY_MQ_QUEUE = "party-mq-queue";
+
+    public static final String PARTY_MQ_ROUTINGKEY = "party-mq-routingKey";
+
+    @Bean
+    public ConnectionFactory connectionFactory() {
+        CachingConnectionFactory connectionFactory = new CachingConnectionFactory(host, port);
+        connectionFactory.setUsername(username);
+        connectionFactory.setPassword(password);
+        connectionFactory.setVirtualHost("/");
+        connectionFactory.setPublisherConfirms(true);
+        return connectionFactory;
+    }
+
+    @Bean
+    @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
+    public RabbitTemplate rabbitTemplate() {
+        RabbitTemplate template = new RabbitTemplate(connectionFactory());
+        return template;
+    }
+
+    @Bean
+    public DirectExchange defaultExchange() {
+        return new DirectExchange(PARTY_MQ_EXCHANGE);
+    }
+
+    /**
+     * 获取队列A
+     *
+     * @return
+     */
+    @Bean
+    public Queue queueA() {
+        // 队列持久
+        return new Queue(PARTY_MQ_QUEUE, true);
+    }
+
+    /**
+     * 一个交换机可以绑定多个消息队列,也就是消息通过一个交换机,可以分发到不同的队列当中去。
+     *
+     * @return
+     */
+    @Bean
+    public Binding binding() {
+        return BindingBuilder.bind(queueA()).to(defaultExchange()).with(RabbitMQConfiguration.PARTY_MQ_ROUTINGKEY);
+    }
+}

+ 22 - 0
inspur-ai/src/main/java/com/inspur/rabbitmq/consumer/PartyMessageConsumer.java

@@ -0,0 +1,22 @@
+package com.inspur.rabbitmq.consumer;
+
+import com.inspur.rabbitmq.config.RabbitMQConfiguration;
+import org.springframework.amqp.rabbit.annotation.RabbitHandler;
+import org.springframework.amqp.rabbit.annotation.RabbitListener;
+import org.springframework.stereotype.Component;
+
+/**
+ * 党建 MQ 消费者
+ *
+ * @author lihao16
+ */
+// @Component
+// @RabbitListener(queues = RabbitMQConfiguration.PARTY_MQ_QUEUE)
+public class PartyMessageConsumer {
+
+    /*@RabbitHandler
+    public void process(String content) {
+        System.out.println("接收处理队列A当中的消息: " + content);
+    }*/
+
+}

+ 18 - 0
inspur-ai/src/main/java/com/inspur/rabbitmq/domain/PartyMQMessage.java

@@ -0,0 +1,18 @@
+package com.inspur.rabbitmq.domain;
+
+import com.alibaba.fastjson2.JSONObject;
+import lombok.Data;
+
+/**
+ * 党建MQ消息
+ *
+ * @author lihao16
+ */
+@Data
+public class PartyMQMessage {
+
+    private String messageType;
+
+    private JSONObject messageData;
+
+}

+ 57 - 0
inspur-ai/src/main/java/com/inspur/rabbitmq/producer/PartyMessageProducer.java

@@ -0,0 +1,57 @@
+package com.inspur.rabbitmq.producer;
+
+import com.inspur.common.utils.uuid.UUID;
+import com.inspur.rabbitmq.config.RabbitMQConfiguration;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.amqp.rabbit.connection.CorrelationData;
+import org.springframework.amqp.rabbit.core.RabbitTemplate;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+
+/**
+ * MQ消息生成者
+ *
+ * @author lihao16
+ */
+@Slf4j
+@Component
+public class PartyMessageProducer implements RabbitTemplate.ConfirmCallback{
+
+
+    /**
+     * 由于rabbitTemplate的scope属性设置为ConfigurableBeanFactory.SCOPE_PROTOTYPE,所以不能自动注入
+     */
+    private RabbitTemplate rabbitTemplate;
+
+    /**
+     * 构造方法注入rabbitTemplate
+     */
+    @Autowired
+    public PartyMessageProducer(RabbitTemplate rabbitTemplate) {
+        this.rabbitTemplate = rabbitTemplate;
+        rabbitTemplate.setConfirmCallback(this);
+    }
+
+    public void sendMsg(String content) {
+        CorrelationData correlationId = new CorrelationData(UUID.randomUUID().toString());
+        System.out.println("队列的值: " + content);
+        System.out.println(correlationId.toString());
+        //把消息放入PARTY_TTS_ROUTINGKEY对应的队列当中去,对应的是队列A
+        rabbitTemplate.convertAndSend(RabbitMQConfiguration.PARTY_MQ_EXCHANGE, RabbitMQConfiguration.PARTY_MQ_ROUTINGKEY, content, correlationId);
+    }
+
+    /**
+     * 回调
+     */
+    @Override
+    public void confirm(CorrelationData correlationData, boolean ack, String cause) {
+        log.info(" 回调id:" + correlationData);
+        if (ack) {
+            log.info("消息成功消费");
+        } else {
+            log.info("消息消费失败:" + cause);
+        }
+    }
+
+}

+ 61 - 4
inspur-party/src/main/java/com/inspur/service/partywork/impl/PartyMeetingInfoServiceImpl.java

@@ -3,6 +3,7 @@ package com.inspur.service.partywork.impl;
 import cn.hutool.http.HttpRequest;
 import cn.hutool.http.HttpResponse;
 import cn.hutool.http.HttpStatus;
+import com.alibaba.fastjson2.JSON;
 import com.alibaba.fastjson2.JSONObject;
 import com.google.zxing.BarcodeFormat;
 import com.google.zxing.WriterException;
@@ -23,10 +24,7 @@ import com.inspur.domain.partyscreen.PartyMenu;
 import com.inspur.domain.partywork.*;
 import com.inspur.domain.screen.MenuDataReqVo;
 import com.inspur.face.common.FaceConstant;
-import com.inspur.face.domain.PartyFaceRecognition;
-import com.inspur.face.domain.RecognizeFaceRsp;
-import com.inspur.face.domain.RecognizeFaceRspResult;
-import com.inspur.face.domain.RecognizeFaceRspResultSubject;
+import com.inspur.face.domain.*;
 import com.inspur.face.mapper.PartyFaceRecognitionMapper;
 import com.inspur.face.service.impl.CompreFaceServiceImpl;
 import com.inspur.framework.config.ServerConfig;
@@ -61,6 +59,9 @@ import org.springframework.util.CollectionUtils;
 import org.springframework.web.multipart.MultipartFile;
 import org.springframework.web.multipart.commons.CommonsMultipartFile;
 
+import javax.imageio.ImageIO;
+import java.awt.*;
+import java.awt.image.BufferedImage;
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
@@ -69,6 +70,7 @@ import java.math.BigDecimal;
 import java.nio.file.FileSystems;
 import java.nio.file.Path;
 import java.util.*;
+import java.util.List;
 import java.util.stream.Collectors;
 
 import static com.inspur.common.utils.PageUtils.startPage;
@@ -1125,6 +1127,7 @@ public class PartyMeetingInfoServiceImpl implements IPartyMeetingInfoService
                 opStatus = 2;
                 log.info("recognizeFace error,file:{},rspMsg:{}",fileMap.get("url"),rspMsg);
             }
+            this.box(reqParam.toJSONString(),rspMsg);
         }catch (Exception e) {
             opStatus = 2;
             rspMsg = e.getMessage();
@@ -1175,4 +1178,58 @@ public class PartyMeetingInfoServiceImpl implements IPartyMeetingInfoService
         return userTableId;
     }
 
+    private String box(String reqParam, String rspMsg) throws IOException {
+        // PartyFaceRecognition partyFaceRecognition = partyFaceRecognitionMapper.selectPartyFaceRecognitionById(id);
+        try {
+            JSONObject reqParamJson = JSON.parseObject(reqParam);
+            String sourceFilePath = reqParamJson.getString("filePath");
+            RecognizeFaceRsp result = JSON.parseObject(rspMsg, RecognizeFaceRsp.class);
+            List<RecognizeFaceRspResult> faceRspList = result.getResult();
+            // 加载原始图片
+            BufferedImage originalImage = ImageIO.read(new File(sourceFilePath));
+            // 创建一个和原始图片同样大小的BufferedImage用于绘图
+            BufferedImage resultImage = new BufferedImage(originalImage.getWidth(), originalImage.getHeight(), originalImage.getType());
+            Graphics2D g2d = resultImage.createGraphics();
+            // 将原始图片绘制到结果图片上(如果需要保留原图内容)
+            g2d.drawImage(originalImage, 0, 0, null);
+            // 绘制人脸框
+            for (RecognizeFaceRspResult faceRsp : faceRspList) {
+                RecognizeFaceRspResultBox box = faceRsp.getBox();
+                // 设置线条颜色为红色
+                g2d.setColor(Color.RED);
+                // 设置线条粗细
+                g2d.setStroke(new java.awt.BasicStroke(1));
+                // 横向
+                g2d.drawLine(box.getX_min(), box.getY_min(), box.getX_max(), box.getY_min());
+                g2d.drawLine(box.getX_min(), box.getY_max(), box.getX_max(), box.getY_max());
+                // 竖向
+                g2d.drawLine(box.getX_min(), box.getY_min(), box.getX_min(), box.getY_max());
+                g2d.drawLine(box.getX_max(), box.getY_min(), box.getX_max(), box.getY_max());
+                RecognizeFaceRspResultSubject subject = faceRsp.getSubjects().get(0);
+                BigDecimal similarity = subject.getSimilarity();
+                String subjectName = "";
+                if (similarity.compareTo(new BigDecimal(0.95)) < 0) {
+                    subjectName = "未识别";
+                } else {
+                    subjectName = subject.getSubject().split("_")[1] + ":" + similarity;
+                }
+                // 设置字体颜色为红色
+                g2d.setColor(Color.RED);
+                // 设置字体大小
+                g2d.setFont(new Font("宋体", Font.BOLD, 20));
+                g2d.drawString(subjectName, box.getX_min(), box.getY_min());
+            }
+            // 保存图片
+            String outputFilePath = sourceFilePath + ".1.png";
+            File outputFile = new File(outputFilePath);
+            ImageIO.write(resultImage, "png", outputFile);
+            // 释放资源(在实际应用中,你可能需要更仔细地管理这些资源)
+            g2d.dispose();
+            return outputFilePath;
+        }catch (Exception e) {
+            log.info("draw box have exception: {}", e.getMessage());
+            return "";
+        }
+    }
+
 }

+ 3 - 0
inspur-ui/src/views/party_work/face/record.vue

@@ -98,6 +98,9 @@ export default {
           item.opStatus = item.opStatus === 1 ? "成功" : "失败";
           let reqParam = JSON.parse(item.reqParam);
           item.picPath = reqParam.url;
+          if (item.rspCode === "200") {
+            item.picPath = item.picPath + "," + item.picPath + ".1.png";
+          }
         });
       });
     },

+ 5 - 1
inspur-ui/src/views/party_work/meeting/info.vue

@@ -272,7 +272,11 @@ export default {
       }
       photoSignRecord(param).then(response => {
         let reqParam = JSON.parse(response.data.reqParam);
-        this.faceSignUrl = reqParam.url;
+        if (response.data.rspCode === "200") {
+          this.faceSignUrl = reqParam.url + ".1.png";
+        }else {
+          this.faceSignUrl = reqParam.url;
+        }
         this.getAttendanceList();
       });
     },