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>
|