528 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
		
		
			
		
	
	
			528 lines
		
	
	
		
			21 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_choose1"> | ||
|  |                                     <!-- <div class="my_text">模式一</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"> | ||
|  |                                                  | ||
|  |                                                     <button type="button" @click="uploadFile" class="webcam-btn">上传</button>   | ||
|  |                                             </el-col> | ||
|  |                                         </el-row> | ||
|  | 
 | ||
|  |                                     </form> | ||
|  |                                     <div v-show="false" id="message-container" class="status-message"></div> | ||
|  |                                 </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: 3vh; margin-left: 1.5vh; margin-right: 1vh"> | ||
|  |                             <form id="selection-form"> | ||
|  |                                 <el-row> | ||
|  |                                     <el-col :span="17">            | ||
|  |                                             <select id="dropdown_cam" name="dropdown_cam" style="font-size : 2.2vh; width:10.5vw;height: 6vh; background-color: transparent;color: #ffffff; "> | ||
|  |                                             </select>          | ||
|  |                                     </el-col> | ||
|  |                                     <el-col :span="7"> | ||
|  |                                         <button type="button" onclick="submitCamera()" class="webcam-btn">确定</button>         | ||
|  |                                 </el-col> | ||
|  |                                 </el-row> | ||
|  |                                  | ||
|  |                                  | ||
|  |                             </form> | ||
|  |                         </div> | ||
|  |                         <div class="my_file_upload_choose"> | ||
|  |                             <!-- <img src="../static/images/camera.png"  style="margin-top: -0.2vw; height : 6vh;width : 6vh" />--> | ||
|  |                             <!-- <div class="my_text" style="margin-top: 5%;">模式二</div> --> | ||
|  |                             <el-row> | ||
|  |                                 <button size="medium" ref="webcam-btn" id="turn-on-webcam-btn" class="webcam-btn1" type="button" | ||
|  |                                     style="margin-left: 1.5vw; font-size : 2.5vh" @click="openWebcam()" type="primary"  | ||
|  |                                     plain>打开相机RTSP</button> | ||
|  |                             </el-row> | ||
|  | 
 | ||
|  |                         </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="http://127.0.0.1:5173/" 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: 70vh;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"> | ||
|  |                              | ||
|  |                             <span v-text="algText" > </span> | ||
|  | 
 | ||
|  |                         </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() | ||
|  | 
 | ||
|  |             },   | ||
|  | 
 | ||
|  |             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 | ||
|  | 
 | ||
|  |                                     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; | ||
|  |         }; | ||
|  | 
 | ||
|  | 
 | ||
|  |         window.onload = function() {   | ||
|  |             var videoFeed = document.getElementById('bg'); | ||
|  |             videoFeed.src = ' '; // 替换为实际的视频文件路径   | ||
|  |         }; | ||
|  |         // 获取数据库的摄像头信息 | ||
|  |         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'); | ||
|  |             console.log("----------"); | ||
|  |             console.log(message); | ||
|  |             console.log("----------"); | ||
|  |             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> |