529 lines
		
	
	
		
			22 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			529 lines
		
	
	
		
			22 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
| <!DOCTYPE html>
 | |
| <html lang="en" >
 | |
| <head>
 | |
|     <meta charset="UTF-8">
 | |
|     
 | |
|     <title>公共安全技术研究中心算法集</title>
 | |
|     <link rel="stylesheet" href="../static/css/index.css">
 | |
|     <link rel="stylesheet" href="../static/css/reset.css">
 | |
|     <link rel="stylesheet" href="../static/css/element.css">
 | |
|     <script src="../static/js/vue.js"> </script>
 | |
|     <script src="../static/js/element.js"> </script>
 | |
|     <script src="../static/js/axios.min.js"></script>
 | |
|    
 | |
| 
 | |
|    
 | |
|     <style lang="scss">
 | |
|         .custom-file-label {
 | |
|             border: 2px solid whitesmoke;
 | |
|             display: inline-block;
 | |
|             padding: 6px 12px;
 | |
|             cursor: pointer;
 | |
|         }
 | |
|         
 | |
| 
 | |
| 
 | |
| 
 | |
|     </style>
 | |
| </head>
 | |
| <body>
 | |
| 
 | |
|     <div id="particles-js" class="main">
 | |
|         <div class="main_con">
 | |
|             <div class="main_top">
 | |
|                 <div class="main_top_left">
 | |
| 
 | |
|                     <div class="main_top_left_top">
 | |
|                         <img src="../static/images/main_top_left.png" />
 | |
|                         <div class="main_top_left_top_title">输入源选择</div>
 | |
|                         <div class="main_top_left_top_con" type="z-index:100">
 | |
|                             <div class="main_top_left_top_con_left main_top_left_top_con_left">
 | |
| 
 | |
|                                 <div class="my_file_upload">
 | |
|                                     <!-- <div class="my_text">模式一</div> -->
 | |
|                                     <div class="text item"
 | |
|                                         style="display: flex; align-items: center; padding: 0;font-weight: 500; justify-content: center;
 | |
|                             font-size: 20px;margin-left: 15%;
 | |
|                             font-family: '黑体', 'SimHei', sans-serif; background: linear-gradient(to bottom, #00e6ff,#feffff ,#00e6ff);
 | |
|                              -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; text-fill-color: transparent;">
 | |
|                                         模式一
 | |
|                                     </div>
 | |
|                                     <form id="upload-form" enctype="multipart/form-data">
 | |
| 
 | |
|                                         <el-row :gutter="10">
 | |
| 
 | |
|                                             <el-col :span="21">
 | |
|                                                 <label class="custom-file-label" for="file-input">选择图片或视频</label>
 | |
|                                                 <input id="file-input" class="file-input" type="file" name="file">
 | |
|                                             </el-col>
 | |
| 
 | |
|                                             <el-col :span="2">
 | |
|                                                 <el-button size="mini" @click="uploadFile" type="primary"
 | |
|                                                     plain>上传</el-button>
 | |
|                                             </el-col>
 | |
|                                         </el-row>
 | |
| 
 | |
|                                     </form>
 | |
|                                 </div>
 | |
| 
 | |
|                                 <div class="my_file_upload">
 | |
|                                     <div class="text item"
 | |
|                                         style="display: flex; align-items: center; padding: 0;font-weight: 500; justify-content: center;
 | |
|                                 font-size: 20px;margin-top: 5%; margin-left: 15%;
 | |
|                                 font-family: '黑体', 'SimHei', sans-serif; background: linear-gradient(to bottom, #00e6ff,#feffff ,#00e6ff);
 | |
|                                  -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; text-fill-color: transparent;">
 | |
|                                         模式二
 | |
|                                     </div>
 | |
|                                     <!-- <div class="my_text" style="margin-top: 5%;">模式二</div> -->
 | |
|                                     <el-row>
 | |
|                                         <el-button size="small" ref="webcam-btn" id="turn-on-webcam-btn"
 | |
|                                             style="margin-left: 15%;" @click="openWebcam()" type="primary"
 | |
|                                             plain>打开相机RTSP</el-button>
 | |
|                                     </el-row>
 | |
| 
 | |
|                                 </div>
 | |
| 
 | |
|                             </div>
 | |
|                         </div>
 | |
| 
 | |
|                     </div>
 | |
|                     <div class="main_top_left_top main_top_left_bottom">
 | |
|                         <img src="../static/images/main_top_left.png" />
 | |
|                         <div class="main_top_left_top_title">摄像机选择</div>
 | |
|                         <div class="my_file_upload" style="margin-top: 10%;">
 | |
|                             <form id="selection-form">
 | |
|                                 <el-row>
 | |
|                                     <el-col :span="17">           
 | |
|                                             <select id="dropdown_cam" name="dropdown_cam" class="select-text">
 | |
|                                             </select>         
 | |
|                                     </el-col>
 | |
|                                     <el-col :span="7">
 | |
|                                         <button type="button" onclick="submitCamera()" class="webcam-btn">确定</button>        
 | |
|                                 </el-col>
 | |
|                                 </el-row>
 | |
|                                 
 | |
|                                 
 | |
|                             </form>
 | |
|                         </div>
 | |
|                     </div>
 | |
|                 </div>
 | |
|                 <div class="main_top_middle">
 | |
|                     
 | |
|                     <div class="main_top_middle_top_title" >
 | |
|                         <img class="title_bg" src="../static/images/title_bg.png">
 | |
|                         
 | |
|                         
 | |
|                         <span v-text="algName"> </span>算法-算法展示
 | |
|                         
 | |
|                         
 | |
|                         <a class="title_web" href="https://gitee.com/iGaoWei/big-data-view" target="blank">管理系统</a>
 | |
|                         <a class="title_admin" href="https://gitee.com/iGaoWei/big-data-view" target="blank">web网页</a>
 | |
|                         <div style="width: 88%;height: 500px;margin: 5px auto;">
 | |
|                             
 | |
|                             <el-row>
 | |
|                                 <el-col>
 | |
|                                     
 | |
|                                     <div class="grid-content bg-purple" >
 | |
|                                         <img id="bg" src="{{url_for('video_feed')}}" autoplay loop muted playsinline style="width: 100%; height: auto;z-index:10"> 
 | |
|                                     </div>
 | |
|                                 </el-col>
 | |
|                                 </el-row>
 | |
|                         </div>
 | |
|                     </div>
 | |
|                 
 | |
|         
 | |
| 
 | |
|                 </div>
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
|                 <div class="main_top_left main_top_right">
 | |
|                     <div class="main_top_left_top">
 | |
|                         <img src="../static/images/main_top_left.png" />
 | |
|                         <div class="main_top_left_top_title">算法描述</div>
 | |
|                         <div class="main_top_left_top_con">
 | |
|                             <div class="main_top_left_top_con">
 | |
|                             <span v-text="algText" > </span>
 | |
| 
 | |
|                         </div>
 | |
|                         <div id="message-container" class="status-message"></div>
 | |
|                     </div>
 | |
|                     <div class="main_top_left_top main_top_left_bottom">
 | |
|                         <img src="../static/images/main_top_left.png" />
 | |
|                         <div class="main_top_left_top_title">检测到的结果为</div>
 | |
|                         <div class="main_top_left_top_con" >
 | |
|                             
 | |
|                             <span v-text="resText" > </span>
 | |
| 
 | |
|                         </div>
 | |
| 
 | |
|                         </div>
 | |
|                         </div>
 | |
| 
 | |
|                     </div>
 | |
|                 </div>
 | |
| 
 | |
| 
 | |
| 
 | |
|             </div>
 | |
|         </div>
 | |
| 
 | |
| 
 | |
|     </div>
 | |
|     </div>
 | |
|     
 | |
|         
 | |
| 
 | |
| 
 | |
|     
 | |
| 
 | |
|     <script>
 | |
|         new Vue({
 | |
|             el: '#particles-js',
 | |
|             data() {
 | |
|                 return{
 | |
|                     resText:'无',
 | |
|                     accuracy: 1,
 | |
|                     getUseCam: false,
 | |
|                     getUseVideo: false,
 | |
|                     options: [],
 | |
|                     selectValue: '',
 | |
|                     algName: '行人检测',
 | |
|                     algText: '行人检测',
 | |
| 
 | |
| 
 | |
|                     getSpeechSegRes: '',
 | |
|                     voiceUrl:'',
 | |
|                 }
 | |
|                 }, 
 | |
|             created() {
 | |
|                 this.fetchAlgData()
 | |
|                 this.fetchAlgDataNew()
 | |
| 
 | |
|             },  
 | |
|             computed: {
 | |
|                 dataAlgName :{
 | |
|                     get() {
 | |
|                     return this.algName;
 | |
|                 }
 | |
|                 }
 | |
|                 
 | |
|                     },
 | |
|             methods: {
 | |
| 
 | |
| 
 | |
| 
 | |
|                 
 | |
|                 openWebcam() {
 | |
|                     var webcamBtn = document.getElementById('turn-on-webcam-btn');
 | |
|                     var videoFeed = document.getElementById('bg');
 | |
|                     var formData = new FormData();
 | |
|                     var that = this
 | |
| 
 | |
|                     
 | |
|                     if (webcamBtn.innerHTML === '相机RTSP') {
 | |
|                         that.getUseCam = true;
 | |
|                         //console.log(that.getUseCam+'相机RTSP');
 | |
| 
 | |
|                         videoFeed.src = "{{ url_for('use_webcam') }}?" + new Date().getTime();
 | |
|                         webcamBtn.innerHTML = '关闭相机RTSP';
 | |
|                         webcamBtn.classList.add('webcam-btn-active');
 | |
|                                                 
 | |
|                     } else {
 | |
|                         that.getUseCam = false;
 | |
|                         videoFeed.src = ''; // Turn off the webcam
 | |
|                         that.resText = '无';
 | |
|                         webcamBtn.innerHTML = '相机RTSP';
 | |
|                         //console.log(that.getUseCam+'相机1RTSP');
 | |
|                         webcamBtn.classList.remove('webcam-btn-active');
 | |
|                         
 | |
|                     }
 | |
|                     if(that.getUseCam == true){
 | |
|                         fetch('/use_webcam')
 | |
|                             .then(response => {
 | |
|                                 const reader = response.body.getReader();
 | |
|                                 const decoder = new TextDecoder('utf-8');
 | |
| 
 | |
|                                 function readStream() {
 | |
|                                     let buffer = '';
 | |
|                                     let jsonEndIndex; // 声明 jsonEndIndex 变量
 | |
|                                     return reader.read().then(({ done, value }) => {
 | |
|                                         if (done || that.getUseCam == false) {
 | |
|                                             that.resText = '无';
 | |
|                                             console.log('Stream ended');
 | |
|                                             return;
 | |
|                                         }
 | |
| 
 | |
|                                         buffer += decoder.decode(value);
 | |
|                                         const resTextIndex = buffer.indexOf('--resText');
 | |
|                                         if (resTextIndex !== -1) {
 | |
|                                         const jsonStartIndex = buffer.indexOf('\r\n\r\n', resTextIndex) + 4;
 | |
|                                         jsonEndIndex = buffer.indexOf('\r\n\r\n', jsonStartIndex); // 移除 const
 | |
|                                         // 真正的resText
 | |
|                                         const json = buffer.slice(jsonStartIndex, jsonEndIndex);
 | |
| 
 | |
|                                         try {
 | |
|                                             //console.log(JSON.parse(json))
 | |
|                                             const { resText } = JSON.parse(json);
 | |
|                                             that.resText = resText
 | |
|                                             //console.log(that.resText);
 | |
|                                         } catch (error) {
 | |
|                                             that.resText = '无'
 | |
|                                             console.error('Invalid JSON:', error);
 | |
|                                         }
 | |
|                                         }
 | |
|                                         // 剩余的数据继续读取
 | |
|                                         buffer = buffer.slice(jsonEndIndex + 4);
 | |
|                                         return readStream();
 | |
|                                     });
 | |
|                                 }
 | |
| 
 | |
|                                 return readStream();
 | |
|                             })
 | |
|                             .catch(error => console.error('Error:', error)
 | |
|                         );
 | |
| 
 | |
| 
 | |
|                     }
 | |
|                 },
 | |
|                
 | |
|                 async fetchAlgData() {
 | |
|                     const response = await fetch('/getSqlAlg', {method:'Get'});
 | |
|                     const data = await response.json();
 | |
|                     this.options = data;
 | |
|                     this.selectValue = this.options[0][1];
 | |
| 
 | |
|                 },
 | |
|                 async fetchAlgDataNew() {
 | |
|                     const response = await fetch('/getSelectAlg', {method:'Get'});
 | |
|                     const data = await response.json();
 | |
|                     this.algName = data[0];
 | |
|                     this.algText = data[1];
 | |
|                     console.log(data);
 | |
| 
 | |
|                 },
 | |
|                 submitForm() {
 | |
|                     // console.log(this.selectValue);
 | |
|                     var formData = new FormData();
 | |
|                     formData.append('selectAlgorithm',this.selectValue);
 | |
|                     fetch('/getSelectAlgorithm', {
 | |
|                             method: 'POST',
 | |
|                             body: formData
 | |
|                         }).then(response => {
 | |
| 
 | |
|                             if (!response.ok) {
 | |
|                                 return response.text().then(text => { throw new Error(text || 'Response not OK') });
 | |
|                             }
 | |
| 
 | |
|                         })
 | |
| 
 | |
|                 },
 | |
|                 
 | |
| 
 | |
|                 
 | |
|                 handleImageUpload(event) {
 | |
|                     var that = this
 | |
|                     var file = event.target.files[0];
 | |
|                     that.uploadedImage = event.target.files[0];
 | |
|                     // 在这里处理图像上传逻辑
 | |
|                     that.voiceUrl = URL.createObjectURL(file)
 | |
|                     var formData = new FormData();
 | |
|                     var that = this;
 | |
|                     if (that.uploadedImage!=null) {
 | |
|                         formData.append('uploadImage', that.uploadedImage);
 | |
| 
 | |
|                         axios({
 | |
|                             method: "post",
 | |
|                             url: "/imageSeg",
 | |
|                             data: formData,
 | |
|                             headers: {
 | |
|                                 'Content-Type': 'multipart/form-data'
 | |
|                             }
 | |
|                         }).then(res=>{
 | |
|                             that.resText=res.data['speechSegRes'];
 | |
|                         })
 | |
| 
 | |
|                     // fetch('/imageSeg', {
 | |
|                     //         method: 'POST',
 | |
|                     //         body: formData
 | |
|                     //     })
 | |
|                     //     .then((data)=>{
 | |
|                     //         return data.json();
 | |
|                     //     }).then((ret)=>{
 | |
|                     //         that.resText = ret['speechSegRes'];
 | |
|                     //     });
 | |
| 
 | |
|                     } else {
 | |
|                         showMessage('Please select a file first.', true);
 | |
|                     }
 | |
| 
 | |
|                 },
 | |
| 
 | |
|                 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
|                 uploadFile() {
 | |
|                     var formData = new FormData();
 | |
|                     var fileInput = document.getElementById('file-input');
 | |
|                     var that = this;
 | |
|                     if (fileInput.files.length > 0) {
 | |
|                         formData.append('file', fileInput.files[0]);
 | |
|                         fetch('/upload', {
 | |
|                                 method: 'POST',
 | |
|                                 body: formData
 | |
|                             })
 | |
|                             .then(response => {
 | |
|                                 if (!response.ok) {
 | |
|                                     return response.text().then(text => { throw new Error(text || 'Response not OK') });
 | |
|                                 }
 | |
|                                 return response.json();
 | |
|                             })
 | |
|                             .then(result => {
 | |
|                                 showMessage(result.message);
 | |
|                                 if (result.message.includes('uploaded successfully')) {
 | |
|                                     that.loadVideoFeed();
 | |
|                                     
 | |
|                                 }
 | |
|                             })
 | |
|                             .catch(error => {
 | |
|                                 showMessage('Upload failed: ' + error.message, true);
 | |
|                             });
 | |
| 
 | |
|                     } else {
 | |
|                         showMessage('Please select a file first.', true);
 | |
|                     }
 | |
|                 },
 | |
|                 loadVideoFeed() {
 | |
|                     var that = this;
 | |
|                     var videoFeed = document.getElementById('bg');
 | |
|                     videoFeed.src = "{{ url_for('video_feed') }}?" + new Date().getTime();
 | |
|                     that.getUseVideo = true;
 | |
|                     // console.log(that.getUseVideo)
 | |
|                     if(that.getUseVideo == true){
 | |
|                         fetch('/video_feed')
 | |
|                             .then(response => {
 | |
|                                 const reader = response.body.getReader();
 | |
|                                 const decoder = new TextDecoder('utf-8');
 | |
| 
 | |
|                                 function readStream() {
 | |
|                                 let buffer = '';
 | |
|                                 let jsonEndIndex; // 声明 jsonEndIndex 变量
 | |
| 
 | |
|                                 return reader.read().then(({ done, value }) => {
 | |
|                                     if (done || that.getUseVideo == false) {
 | |
|                                         that.resTextIndex = '无';
 | |
|                                         console.log('Stream ended');
 | |
|                                     return;
 | |
|                                     }
 | |
|                                     buffer += decoder.decode(value);
 | |
|                                     const resTextIndex = buffer.indexOf('--resText');
 | |
|                                     if (resTextIndex !== -1) {
 | |
|                                     const jsonStartIndex = buffer.indexOf('\r\n\r\n', resTextIndex) + 4;
 | |
|                                     jsonEndIndex = buffer.indexOf('\r\n\r\n', jsonStartIndex); // 移除 const
 | |
|                                     const json = buffer.slice(jsonStartIndex, jsonEndIndex);
 | |
| 
 | |
|                                     try {
 | |
|                                         //console.log(JSON.parse(json))
 | |
|                                         const { resText } = JSON.parse(json);
 | |
|                                         that.resText = resText
 | |
|                                         //console.log(that.numPeople);
 | |
|                                     } catch (error) {
 | |
|                                         that.resText = '无'
 | |
|                                         console.error('Invalid JSON:', error);
 | |
|                                     }
 | |
|                                     }
 | |
|                                     // 剩余的数据继续读取
 | |
|                                     buffer = buffer.slice(jsonEndIndex + 4);
 | |
|                                     return readStream();
 | |
|                                 });
 | |
|                                 }
 | |
| 
 | |
|                                 return readStream();
 | |
|                             })
 | |
|                             .catch(error => console.error('Error:', error)
 | |
|                         );
 | |
|                     }
 | |
|                 }
 | |
|             },
 | |
|         })
 | |
|                 // Update the label text with the selected file name
 | |
|         document.getElementById('file-input').onchange = function () {
 | |
|             document.querySelector('.custom-file-label').textContent = this.files[0].name;
 | |
|         };
 | |
| 
 | |
| 
 | |
|         
 | |
|         // 获取数据库的摄像头信息
 | |
|         function getCameraData() {
 | |
|             return new Promise((resolve, reject) => {
 | |
|                 fetch('/getSqlCamera', {
 | |
|                     method: 'GET',
 | |
|                 })
 | |
|                 .then(response => response.json())
 | |
|                 .then(data => {
 | |
|                     resolve(data);
 | |
|                 })
 | |
|                 .catch(error => {
 | |
|                     reject(error);
 | |
|                 });
 | |
|             });
 | |
|         }
 | |
|         // 根据摄像头信息显示摄像头的所有选项
 | |
|         getCameraData().then(data => {
 | |
|             const dropdown = document.getElementById('dropdown_cam');
 | |
|             dropdown.innerHTML = ''; // 清空现有选项
 | |
| 
 | |
|             data.forEach(optionValue => {
 | |
|                 const option = document.createElement('option');
 | |
|                 option.value = optionValue[0];
 | |
|                 option.text = optionValue[2];
 | |
|                 dropdown.appendChild(option);
 | |
|             });
 | |
|         }).catch(error => {
 | |
|             console.error('获取摄像头数据出错:', error);
 | |
|         });
 | |
|         
 | |
|         // 确定选择的摄像头,并传回后端
 | |
|         function submitCamera() {
 | |
|             var selectCamera = document.getElementById('dropdown_cam').value;
 | |
|             
 | |
|             // 在这里执行您需要的操作,可以使用选定的选项进行相应的处理
 | |
|             var formData = new FormData();
 | |
|             formData.append('camID',selectCamera);
 | |
|             fetch('/getFrontCamera', {
 | |
|                     method: 'POST',
 | |
|                     body: formData
 | |
|                 }).then(response => {
 | |
| 
 | |
|                     if (!response.ok) {
 | |
|                         return response.text().then(text => { throw new Error(text || 'Response not OK') });
 | |
|                     }
 | |
| 
 | |
|                 })
 | |
|         }
 | |
|         
 | |
|         function showMessage(message, isError = false) {
 | |
|             var messageDiv = document.getElementById('message-container');
 | |
|             messageDiv.innerHTML = message;
 | |
|             messageDiv.className = isError ? 'status-message error' : 'status-message success';
 | |
| 
 | |
|             // Hide the message after 5 seconds
 | |
|             setTimeout(() => {
 | |
|                 messageDiv.innerHTML = '';
 | |
|                 messageDiv.className = '';
 | |
|             }, 2000);
 | |
|         }
 | |
| 
 | |
|         
 | |
| 
 | |
|     </script>
 | |
| </body>
 | |
| 
 | |
| </html>
 |