欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Springboot實(shí)現(xiàn)人臉識(shí)別與WebSocket長連接的實(shí)現(xiàn)代碼

 更新時(shí)間:2023年11月06日 15:20:17   作者:默默努力的小老弟  
這篇文章主要介紹了Springboot實(shí)現(xiàn)人臉識(shí)別與WebSocket長連接的實(shí)現(xiàn),本文通過示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧

0.什么是WebSocket,由于普通的請(qǐng)求是間斷式發(fā)送的,如果要同一時(shí)間發(fā)生大量的請(qǐng)求,必然導(dǎo)致響應(yīng)速度慢(因?yàn)楦鶕?jù)tcp協(xié)議要經(jīng)過三層握手,如果不持續(xù)發(fā)送,就會(huì)導(dǎo)致n多次握手,關(guān)閉連接,打開連接)

1.業(yè)務(wù)需求: 由于我需要使用java來處理視頻的問題,視頻其實(shí)就是圖片,相當(dāng)于每張圖片就是幀,不停發(fā)送幀去實(shí)現(xiàn)人臉失敗,然后返回處理結(jié)果,(支付寶刷臉支付也是同樣的道理)

2.前端建立WebSocket()對(duì)象,onMessage函數(shù)監(jiān)聽返回的結(jié)果

<!DOCTYPE html>
<html>
<head>
    <title>視頻幀捕獲</title>
</head>
<body>
    <video id="videoElement" autoplay></video>
    <canvas id="canvasElement" style="display: none;"></canvas>
    <script>
     //如果是https協(xié)議的話,就需要改為 wss
           var socket = new WebSocket("ws://localhost:8080/facedetect");
       const video = document.getElementById('videoElement');
        const canvas = document.getElementById('canvasElement');
        const context = canvas.getContext('2d');
    socket.onopen = function() {
          console.log("xxxx");
       // 每1秒發(fā)送一次視頻幀數(shù)據(jù),必須要在這里寫定時(shí)器,因?yàn)榇蜷_連接后才能發(fā)送請(qǐng)求,不然每次都會(huì)報(bào)Websocket close的錯(cuò)誤
          setInterval(captureFrame,10000)
    };
      socket.onmessage = function(event) {
    	var result = event.data;
  	  // 處理服務(wù)器返回的結(jié)果
   	 console.log(result);//打印出結(jié)果
      };
    socket.onclose = function(event) {
        console.log("WebSocket已關(guān)閉");
    };
    socket.onerror = function(event) {
  console.error('WebSocket錯(cuò)誤:', event);
 };
        navigator.mediaDevices.getUserMedia({ video: true })
            .then(stream => {
                video.srcObject = stream;
            })
            .catch(error => {
                console.error('無法訪問攝像頭:', error);
            });
        function captureFrame() {
            context.drawImage(video, 0, 0, canvas.width, canvas.height);
             const imageDataUrl = canvas.toDataURL('image/jpeg', 0.5);
             console.log(imageDataUrl) 
            socket.send(imageDataUrl);
          // 將數(shù)據(jù)URL發(fā)送到WebSocket服務(wù)器
        }
        // 每隔一段時(shí)間捕獲一幀并發(fā)送到Servlet
    </script>
</body>
</html>

3.后端寫配置類,配置websocket的路徑

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
           //錄入人臉數(shù)據(jù)頁面
        registry.addHandler(myHandler(),  "/face").setAllowedOrigins("*");
         //人臉識(shí)別頁面
        registry.addHandler(myHandler1(), "/facedetect").setAllowedOrigins("*");
    }
    @Bean
    public WebSocketHandler myHandler() {
        return new FaceController();
    }
    @Bean
    public WebSocketHandler myHandler1() {
        return new FaceController1();
    }
}

4.寫controller

//人臉錄入的controller
@Controller
@RequestMapping("/face")
@CrossOrigin
public class FaceController extends TextWebSocketHandler {
private WebSocketSession session;
    // 處理WebSocket連接請(qǐng)求
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        System.out.println("WebSocket連接已建立");
        // 保存WebSocket會(huì)話
        this.session = session;
    }
    // 處理WebSocket文本消息
    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        String text = message.getPayload();
        System.out.println(text);
        text = text.replaceFirst("^data:image/[^;]+;base64,?\\s*", "");
        text = text.replaceAll("[^A-Za-z0-9+/=]", "");
        System.out.println(text);
        byte[] imageBytes = Base64.getDecoder().decode(text);
        if (imageBytes != null) {
            try {
                // 讀取字節(jié)數(shù)組并返回BufferedImage對(duì)象
                ByteArrayInputStream bis = new ByteArrayInputStream(imageBytes);
                BufferedImage bufferedImage = ImageIO.read(bis);
                if (bufferedImage != null) {
                    // 示例:顯示圖像寬度和高度
                    int width = bufferedImage.getWidth();
                    int height = bufferedImage.getHeight();
                    System.out.println("圖像寬度:" + width);
                    System.out.println("圖像高度:" + height);
               //錄入人臉
                    Employee e1 = HRService.addEmp(UUID.randomUUID().toString().substring(0,10), bufferedImage);
                    ImageService.saveFaceImage(bufferedImage, e1.getCode());// 保存員工照片文件
                    System.out.println(e1.getCode());
                    // 在這里可以對(duì)BufferedImage對(duì)象進(jìn)行其他操作
                } else {
                    System.out.println("無法讀取圖像");
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            System.out.println("無效的base64數(shù)據(jù)");
        }
    }
        // 根據(jù)接收到的文本消息進(jìn)行相應(yīng)的處理
}
//人臉檢測的控制器
@Controller
@RequestMapping("/facedetect")
@CrossOrigin
public class FaceController1 extends TextWebSocketHandler {
private WebSocketSession session;
    // 處理WebSocket連接請(qǐng)求
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        System.out.println("WebSocket連接已建立");
        // 保存WebSocket會(huì)話
        this.session = session;
    }
    // 處理WebSocket文本消息
    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        System.out.println("detect");
        String text = message.getPayload();
        System.out.println(text);
        text = text.replaceFirst("^data:image/[^;]+;base64,?\\s*", "");
        text = text.replaceAll("[^A-Za-z0-9+/=]", "");
        System.out.println(text);
        byte[] imageBytes = Base64.getDecoder().decode(text);
        if (imageBytes != null) {
            try {
                // 讀取字節(jié)數(shù)組并返回BufferedImage對(duì)象
                ByteArrayInputStream bis = new ByteArrayInputStream(imageBytes);
                BufferedImage bufferedImage = ImageIO.read(bis);
                if (bufferedImage != null) {
                    FaceEngineService.loadAllFaceFeature();
                    FaceFeature faceFeature = FaceEngineService.getFaceFeature(bufferedImage);
                    // 獲取當(dāng)前幀中出現(xiàn)的人臉對(duì)應(yīng)的特征碼
                  String code = FaceEngineService.detectFace(faceFeature);
                    System.out.println(code);
                    if (code != null) {// 如果特征碼不為null,表明畫面中存在某員工的人臉
                        Employee e = HRService.getEmp(code);// 根據(jù)特征碼獲取員工對(duì)象
                        HRService.addClockInRecord(e);// 為此員工添加打卡記錄
                        // 文本域添加提示信息
                        session.sendMessage(new TextMessage("打卡成功"));
                    }
                    // 在這里可以對(duì)BufferedImage對(duì)象進(jìn)行其他操作
                } else {
                    session.sendMessage(new TextMessage("打卡成功"));
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            System.out.println("無效的base64數(shù)據(jù)");
        }
    }
        // 根據(jù)接收到的文本消息進(jìn)行相應(yīng)的處理
}

到此這篇關(guān)于Springboot實(shí)現(xiàn)人臉識(shí)別與WebSocket長連接的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Springboot WebSocket長連接內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java+selenium 網(wǎng)易云音樂刷累計(jì)聽歌數(shù)的方法

    java+selenium 網(wǎng)易云音樂刷累計(jì)聽歌數(shù)的方法

    這篇文章主要介紹了java+selenium 網(wǎng)易云音樂刷累計(jì)聽歌數(shù)的方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-06-06
  • mybatis的xml中使用@符號(hào)調(diào)用類方法示例

    mybatis的xml中使用@符號(hào)調(diào)用類方法示例

    這篇文章主要為大家介紹了mybatis的xml中使用@符號(hào)調(diào)用類方法示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-12-12
  • Java自然排序Comparable使用方法解析

    Java自然排序Comparable使用方法解析

    這篇文章主要介紹了Java自然排序Comparable使用方法解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-04-04
  • java封裝全局異常處理深入詳解

    java封裝全局異常處理深入詳解

    這篇文章主要為大家介紹了java封裝全局異常處理的深入詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-09-09
  • Spring中存取Bean的相關(guān)注解舉例詳解

    Spring中存取Bean的相關(guān)注解舉例詳解

    這篇文章主要給大家介紹了關(guān)于Spring中存取Bean的相關(guān)注解,在沒有使用注解獲取對(duì)象之前,我們需要在配置文件中通過添加bean來將對(duì)象存儲(chǔ)到Spring容器中,這對(duì)于我們來說是比較麻煩的,需要的朋友可以參考下
    2023-10-10
  • java.lang.AbstractMethodError: org.apache.xerces.dom.DocumentImpl.setXmlVersion問題解決方法

    java.lang.AbstractMethodError: org.apache.xerces.dom.Documen

    這篇文章主要介紹了java.lang.AbstractMethodError: org.apache.xerces.dom.DocumentImpl.setXmlVersion問題解決方法,導(dǎo)致本文問題的原因是缺少一個(gè)xerces.jar jar包,需要的朋友可以參考下
    2015-03-03
  • java利用delayedQueue實(shí)現(xiàn)本地的延遲隊(duì)列

    java利用delayedQueue實(shí)現(xiàn)本地的延遲隊(duì)列

    這篇文章主要給大家介紹了java利用delayedQueue實(shí)現(xiàn)本地的延遲隊(duì)列的相關(guān)資料,文中介紹的非常詳細(xì),相信對(duì)大家具有一定的參考價(jià)值,需要的朋友們下面來一起看看吧。
    2017-04-04
  • java控制臺(tái)實(shí)現(xiàn)學(xué)生信息管理系統(tǒng)

    java控制臺(tái)實(shí)現(xiàn)學(xué)生信息管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了java控制臺(tái)實(shí)現(xiàn)學(xué)生信息管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • 關(guān)于springboot使用rocketmq?RocketMQMessageListener參數(shù)問題

    關(guān)于springboot使用rocketmq?RocketMQMessageListener參數(shù)問題

    這篇文章主要介紹了springboot使用rocketmq?RocketMQMessageListener參數(shù)問題,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值需要的朋友可以參考下
    2022-11-11
  • Java設(shè)計(jì)模式之策略模式示例詳解

    Java設(shè)計(jì)模式之策略模式示例詳解

    這篇文章主要為大家詳細(xì)介紹了Java的策略模式,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-03-03

最新評(píng)論