当前位置: 首页 > news >正文

AI防摔倒检测系统

结构:

主要的py文件:

import cv2
import threading
import time
import numpy as np
from flask import Flask, Response, render_template, jsonify
from ultralytics import YOLO
import logging
from datetime import datetime
import torch
from collections import deque
import psutil# GPU监控模块
try:import pynvmltry:# 手动指定DLL路径nvml_path = r"C:\Windows\System32\nvml.dll"pynvml.nvmlInit()HAS_GPU = Trueexcept pynvml.NVMLError as e:print("NVML Error")HAS_GPU = False
except ImportError:HAS_GPU = Falsedef get_gpu_usage():if not HAS_GPU:return 0try:handle = pynvml.nvmlDeviceGetHandleByIndex(0)util = pynvml.nvmlDeviceGetUtilizationRates(handle)return util.gpuexcept Exception as e:print(f"获取GPU使用率失败: {str(e)}")return 0# 日志配置
logging.basicConfig(level=logging.INFO,format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',handlers=[logging.StreamHandler()]
)
logger = logging.getLogger('HikVisionPro')app = Flask(__name__)class Config:# 海康威视摄像头RTSP配置模板HIKVISION_RTSP = "rtsp://{user}:{pwd}@{ip}:554/Streaming/Channels/{channel}"# 摄像头配置字典(ID: 配置参数)CAMERAS = {1: {"name": "生产车间东侧","user": "admin","pwd": "beidawqf2025","ip": "192.168.1.70","channel": "101"  # 主码流},2: {"name": "包装流水线","user": "admin","pwd": "beidawqf2025","ip": "192.168.1.68","channel": "101"}}# 视频处理参数DISPLAY_SIZE = (640, 540)  # 显示分辨率MODEL_SIZE = 320  # 模型输入尺寸FPS = 25  # 目标帧率JPEG_QUALITY = 85  # 视频流压缩质量BUFFER_SIZE = 3  # 视频缓冲区大小RECONNECT_INTERVAL = 5  # 重连间隔(秒)# 设备配置DEVICE = 'cuda' if torch.cuda.is_available() else 'cpu'MODEL_PATH = "yolov10s.pt"# YOLO模型初始化
try:logger.info(f"初始化YOLO模型,设备:{Config.DEVICE}")detector = YOLO(Config.MODEL_PATH).to(Config.DEVICE)if Config.DEVICE == 'cuda':detector = detector.half()logger.info(f"模型加载成功:{detector.names}")
except Exception as e:logger.error(f"模型加载失败: {str(e)}")exit(1)class HikVisionProcessor:def __init__(self, cam_id):self.cam_id = cam_idself.config = Config.CAMERAS[cam_id]self.rtsp_url = self._generate_rtsp()self.cap = Noneself.frame = np.zeros((Config.DISPLAY_SIZE[1], Config.DISPLAY_SIZE[0], 3), np.uint8)self.lock = threading.Lock()self.status = "INIT"self.retry_count = 0self.last_active = time.time()self.fps = 0# 检测数据self.detections = deque(maxlen=100)self.current_objects = []# 启动处理线程self.thread = threading.Thread(target=self._processing_loop, daemon=True)self.thread.start()logger.info(f"摄像头{cam_id}处理器启动: {self.rtsp_url}")def _generate_rtsp(self):"""生成海康威视RTSP地址"""return Config.HIKVISION_RTSP.format(user=self.config['user'],pwd=self.config['pwd'],ip=self.config['ip'],channel=self.config['channel'])def _connect(self):"""建立RTSP连接"""self.cap = cv2.VideoCapture(self.rtsp_url, cv2.CAP_FFMPEG)if not self.cap.isOpened():raise ConnectionError("RTSP连接失败")# 设置视频参数self.cap.set(cv2.CAP_PROP_BUFFERSIZE, Config.BUFFER_SIZE)self.cap.set(cv2.CAP_PROP_FPS, Config.FPS)logger.info(f"摄像头{self.cam_id}连接成功")self.status = "CONNECTED"def _reconnect(self):"""断线重连机制"""if self.cap:self.cap.release()self.status = "RECONNECTING"logger.warning(f"摄像头{self.cam_id}尝试重连({self.retry_count})...")try:self._connect()self.retry_count = 0return Trueexcept Exception as e:self.retry_count += 1self.status = f"ERROR: {str(e)}"return Falsedef _processing_loop(self):"""视频处理主循环"""while True:try:# 连接管理if not self.cap or not self.cap.isOpened():if not self._reconnect():time.sleep(Config.RECONNECT_INTERVAL)continue# 读取视频帧ret, frame = self.cap.read()if not ret:raise RuntimeError("视频流中断")# YOLO推理start_time = time.time()if Config.DEVICE == 'cuda':frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)results = detector(frame_rgb, imgsz=Config.MODEL_SIZE, verbose=False, half=True)else:results = detector(frame, imgsz=Config.MODEL_SIZE, verbose=False)# 处理检测结果self._update_detections(results)# 生成显示帧display_frame = results[0].plot()display_frame = cv2.resize(display_frame, Config.DISPLAY_SIZE)# 更新状态with self.lock:self.frame = cv2.cvtColor(display_frame, cv2.COLOR_RGB2BGR)self.fps = 1 / (time.time() - start_time + 1e-6)self.last_active = time.time()self.status = "RUNNING"except Exception as e:logger.error(f"摄像头{self.cam_id}处理异常: {str(e)}")self.status = f"ERROR: {str(e)}"time.sleep(Config.RECONNECT_INTERVAL)self._reconnect()def _update_detections(self, results):"""更新检测数据"""current = []for box in results[0].boxes:current.append({"class": detector.names[int(box.cls)],"confidence": float(box.conf),"timestamp": datetime.now().isoformat()})self.current_objects = currentself.detections.extend(current)def get_frame(self):"""获取当前帧的JPEG数据"""with self.lock:if (time.time() - self.last_active) > Config.RECONNECT_INTERVAL:return None, "CONNECTION_LOST"ret, jpeg = cv2.imencode('.jpg', self.frame, [int(cv2.IMWRITE_JPEG_QUALITY), Config.JPEG_QUALITY])return jpeg.tobytes() if ret else None, self.status# 初始化摄像头系统
camera_system = {}
for cam_id in Config.CAMERAS:try:camera_system[cam_id] = HikVisionProcessor(cam_id)time.sleep(1)  # 避免同时发起大量连接except Exception as e:logger.error(f"摄像头{cam_id}初始化失败: {str(e)}")camera_system[cam_id] = None@app.route('/')
def dashboard():"""监控主面板"""camera_list = []for cam_id, cam in camera_system.items():camera_list.append({"id": cam_id,"name": Config.CAMERAS[cam_id]['name'],"status": cam.status if cam else 'OFFLINE',"fps": round(cam.fps, 1) if cam else 0})return render_template('dashboard8.html',cameras=camera_list,system={"gpu": get_gpu_usage(),"cpu": psutil.cpu_percent(),"memory": psutil.virtual_memory().percent})@app.route('/video/<int:cam_id>')
def video_feed(cam_id):"""视频流端点"""def generate():cam = camera_system.get(cam_id)if not cam:returnwhile True:frame_data, status = cam.get_frame()if frame_data:yield (b'--frame\r\n'b'Content-Type: image/jpeg\r\n\r\n' + frame_data + b'\r\n')else:yield (b'--frame\r\n'b'Content-Type: image/jpeg\r\n\r\n' + cv2.imencode('.jpg', np.zeros((480, 640, 3), np.uint8))[1].tobytes() + b'\r\n')time.sleep(1 / Config.FPS)return Response(generate(), mimetype='multipart/x-mixed-replace; boundary=frame')@app.route('/api/status')
def system_status():"""系统状态API"""status = {"cameras": [],"system": {"cpu": psutil.cpu_percent(),"gpu": get_gpu_usage(),"memory": psutil.virtual_memory().percent}}for cam_id, cam in camera_system.items():if cam:status["cameras"].append({"id": cam_id,"name": Config.CAMERAS[cam_id]['name'],"status": cam.status,"fps": round(cam.fps, 1),"objects": [obj["class"] for obj in cam.current_objects]})else:status["cameras"].append({"id": cam_id,"name": Config.CAMERAS[cam_id]['name'],"status": "OFFLINE","fps": 0,"objects": []})return jsonify(status)if __name__ == '__main__':try:logger.info("启动海康威视多路工业摄像头监控系统")app.run(host='0.0.0.0', port=5050, threaded=True)except KeyboardInterrupt:logger.info("系统正常关闭")

HTML文件:

<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>智能安防监控系统 | SecureVision Pro</title><link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet"><script src="https://cdn.jsdelivr.net/npm/chart.js"></script><style>:root {--primary-color: #2A5CAA;--secondary-color: #3AB0FF;--success-color: #30C172;--danger-color: #FF4D4D;--dark-color: #1A2330;--light-color: #F5F7FA;--transition-speed: 0.3s;}body {font-family: 'Segoe UI', system-ui, -apple-system, sans-serif;background: var(--dark-color);color: var(--light-color);margin: 0;padding: 20px;line-height: 1.6;}.dashboard-container {max-width: 1800px;margin: 0 auto;}.system-header {background: linear-gradient(135deg, var(--primary-color), #1E3A5F);padding: 2rem;border-radius: 16px;margin-bottom: 2rem;box-shadow: 0 8px 24px rgba(0,0,0,0.2);position: relative;overflow: hidden;}.system-header::before {content: "";position: absolute;top: -50%;right: -30%;width: 600px;height: 600px;background: radial-gradient(rgba(255,255,255,0.1) 10%, transparent 60%);}.stats-grid {display: grid;grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));gap: 1.5rem;margin-bottom: 2rem;}.stat-card {background: rgba(255,255,255,0.05);padding: 1.5rem;border-radius: 12px;backdrop-filter: blur(10px);transition: transform var(--transition-speed) ease;border: 1px solid rgba(255,255,255,0.1);}.stat-card:hover {transform: translateY(-5px);background: rgba(255,255,255,0.08);}.camera-grid {display: grid;grid-template-columns: repeat(auto-fit, minmax(480px, 1fr));gap: 2rem;margin-bottom: 3rem;}.camera-card {background: rgba(255,255,255,0.05);border-radius: 16px;overflow: hidden;transition: all var(--transition-speed) cubic-bezier(0.4, 0, 0.2, 1);box-shadow: 0 6px 20px rgba(0,0,0,0.2);position: relative;border: 1px solid rgba(255,255,255,0.1);}.camera-card:hover {transform: translateY(-5px);box-shadow: 0 12px 30px rgba(0,0,0,0.3);}.camera-header {padding: 1.2rem;background: rgba(0,0,0,0.3);display: flex;justify-content: space-between;align-items: center;}.camera-title {font-weight: 600;font-size: 1.1em;display: flex;align-items: center;gap: 10px;}.status-indicator {width: 12px;height: 12px;border-radius: 50%;margin-right: 8px;position: relative;}.online {background: var(--success-color);box-shadow: 0 0 12px rgba(46, 204, 113, 0.3);animation: pulse 1.5s infinite;}.offline {background: var(--danger-color);opacity: 0.7;}@keyframes pulse {0% { box-shadow: 0 0 0 0 rgba(46, 204, 113, 0.3); }70% { box-shadow: 0 0 0 10px rgba(46, 204, 113, 0); }100% { box-shadow: 0 0 0 0 rgba(46, 204, 113, 0); }}.video-container {position: relative;padding-bottom: 56.25%;background: #000;}.video-feed {width: 100%;height: 100%;object-fit: cover;position: absolute;top: 0;left: 0;transition: opacity 0.5s ease;}.object-list {padding: 1rem;background: rgba(0,0,0,0.3);margin: 0;font-size: 0.9em;color: var(--secondary-color);min-height: 60px;display: flex;align-items: center;flex-wrap: wrap;gap: 8px;}.object-tag {background: rgba(58, 176, 255, 0.15);padding: 4px 12px;border-radius: 20px;border: 1px solid var(--secondary-color);font-size: 0.85em;}.performance-badge {position: absolute;bottom: 15px;left: 15px;background: rgba(0,0,0,0.7);padding: 6px 12px;border-radius: 20px;font-size: 0.8em;display: flex;align-items: center;gap: 8px;}.system-title {font-size: 2.5rem;font-weight: 700;margin: 0;letter-spacing: -0.5px;display: flex;align-items: center;gap: 15px;}.metric-value {font-size: 1.8rem;font-weight: 600;margin: 8px 0;color: var(--secondary-color);}.metric-label {color: rgba(255,255,255,0.7);font-size: 0.9em;display: flex;align-items: center;gap: 8px;}.alert-badge {position: absolute;top: 15px;right: 15px;background: var(--danger-color);color: white;padding: 6px 12px;border-radius: 20px;font-size: 0.85em;animation: alert-pulse 1s infinite;}@keyframes alert-pulse {0% { transform: scale(1); }50% { transform: scale(1.05); }100% { transform: scale(1); }}.loading-overlay {position: absolute;top: 0;left: 0;right: 0;bottom: 0;background: rgba(0,0,0,0.8);display: flex;align-items: center;justify-content: center;flex-direction: column;gap: 15px;}.loading-spinner {width: 40px;height: 40px;border: 3px solid rgba(255,255,255,0.2);border-top-color: var(--secondary-color);border-radius: 50%;animation: spin 1s linear infinite;}@keyframes spin {to { transform: rotate(360deg); }}.camera-card.phone-alert {animation: phone-alert 1s infinite;position: relative;overflow: hidden;}@keyframes phone-alert {0% { border-color: rgba(255,77,77,0); }50% { border-color: var(--danger-color); }100% { border-color: rgba(255,77,77,0); }}.phone-alert::before {content: "";position: absolute;top: 0;left: 0;right: 0;bottom: 0;border: 3px solid var(--danger-color);border-radius: 16px;animation: phone-glow 1.5s infinite;z-index: 1;}@keyframes phone-glow {0% { opacity: 0; box-shadow: 0 0 10px rgba(255,77,77,0); }50% { opacity: 1; box-shadow: 0 0 20px rgba(255,77,77,0.5); }100% { opacity: 0; box-shadow: 0 0 10px rgba(255,77,77,0); }}.alert-summary {cursor: pointer;transition: all 0.3s ease;}.alert-summary:hover {background: rgba(255, 77, 77, 0.1);}.alert-count {font-size: 1.8rem;font-weight: 600;margin: 8px 0;}.no-alert {color: var(--success-color);}.has-alert {color: var(--danger-color);animation: alert-pulse 1.5s infinite;}.modal {display: none;position: fixed;z-index: 100;left: 0;top: 0;width: 100%;height: 100%;background-color: rgba(0, 0, 0, 0.8);overflow: auto;}.modal-content {background: linear-gradient(135deg, #1A2330, #0E131A);margin: 5% auto;padding: 2rem;border-radius: 16px;width: 80%;max-width: 1200px;box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);border: 1px solid rgba(255, 255, 255, 0.1);}.modal-header {display: flex;justify-content: space-between;align-items: center;margin-bottom: 1.5rem;padding-bottom: 1rem;border-bottom: 1px solid rgba(255, 255, 255, 0.1);}.modal-title {font-size: 1.5rem;font-weight: 600;color: var(--secondary-color);}.close-modal {color: rgba(255, 255, 255, 0.7);font-size: 1.5rem;cursor: pointer;transition: color 0.3s;}.close-modal:hover {color: var(--danger-color);}.alert-list {display: grid;gap: 1.5rem;}.alert-item {background: rgba(255, 77, 77, 0.1);padding: 1.5rem;border-radius: 12px;border-left: 4px solid var(--danger-color);}.system-footer {margin-top: 2rem;}.resource-grid {display: grid;gap: 1rem;}.resource-item {display: flex;align-items: center;gap: 10px;}.resource-label {width: 60px;font-size: 0.9em;color: rgba(255, 255, 255, 0.7);}.resource-bar {flex: 1;height: 10px;background: rgba(255, 255, 255, 0.1);border-radius: 5px;overflow: hidden;}.resource-fill {height: 100%;border-radius: 5px;transition: all 0.5s ease;}.resource-value {width: 40px;text-align: right;font-size: 0.8em;color: var(--secondary-color);}.no-alert {text-align: center;padding: 2rem;color: var(--success-color);}.alert-source, .alert-time, .alert-objects {display: flex;align-items: center;gap: 8px;margin-bottom: 8px;}</style>
</head>
<body><div class="dashboard-container"><div class="system-header"><div class="system-title"><i class="fas fa-shield-alt"></i>Ai方摔倒检测监控系统</div><div class="stats-grid"><div class="stat-card"><div class="metric-label"><i class="fas fa-microchip"></i>计算设备</div><div class="metric-value">{{ device|upper }}</div></div><div class="stat-card"><div class="metric-label"><i class="fas fa-video"></i>在线摄像头</div><div class="metric-value" id="online-cams"><span id="online-count">0</span>/{{ cameras|length }}</div></div><div class="stat-card"><div class="metric-label"><i class="fas fa-clock"></i>系统时间</div><div class="metric-value" id="live-clock">{{ server_time }}</div></div><div class="stat-card alert-summary" id="alert-summary"><div class="metric-label"><i class="fas fa-exclamation-triangle"></i>手机检测警告</div><div class="alert-count no-alert" id="alert-count">0</div><div class="metric-label"><span id="alert-status">系统正常</span></div></div></div></div><div class="camera-grid">{% for camera in cameras %}<div class="camera-card" id="cam-{{ camera.id }}"><div class="camera-header"><a href="/camera_detail/{{ camera.id }}" style="text-decoration: none; color: inherit;"><div class="camera-title"><span class="status-indicator {% if camera.status == '运行中' %}online{% else %}offline{% endif %}"></span>{{ camera.name }}</div></a><div class="camera-meta"><span class="fps-badge">{{ camera.status }}</span></div></div><div class="video-container"><img class="video-feed" src="{{ url_for('video_feed', cam_id=camera.id) }}"><div class="performance-badge"><i class="fas fa-tachometer-alt"></i><span id="fps-{{ camera.id }}">-</span> FPS</div></div><div class="object-list" id="objects-{{ camera.id }}"><div class="loading-overlay"><div class="loading-spinner"></div><span>连接中...</span></div></div></div>{% endfor %}</div><div class="system-footer"><div class="stat-card"><div class="metric-label"><i class="fas fa-database"></i>系统资源监控</div><div class="resource-grid"><div class="resource-item"><span class="resource-label">CPU:</span><div class="resource-bar"><div class="resource-fill" id="cpu-usage"></div></div><span class="resource-value" id="cpu-value">0%</span></div><div class="resource-item"><span class="resource-label">GPU:</span><div class="resource-bar"><div class="resource-fill" id="gpu-usage"></div></div><span class="resource-value" id="gpu-value">0%</span></div><div class="resource-item"><span class="resource-label">内存:</span><div class="resource-bar"><div class="resource-fill" id="mem-usage"></div></div><span class="resource-value" id="mem-value">0%</span></div></div></div></div></div><div id="alert-modal" class="modal"><div class="modal-content"><div class="modal-header"><div class="modal-title"><i class="fas fa-exclamation-triangle"></i><span id="modal-title">手机检测分析报告</span></div><span class="close-modal">&times;</span></div><div class="alert-list" id="alert-details"><!-- 动态内容将在这里填充 --></div></div></div><script>let currentAlerts = [];let gpuAvailable = {% if device == 'cuda' %}true{% else %}false{% endif %};function updateDashboard() {fetch('/api/status').then(response => {if (!response.ok) throw new Error('网络响应异常');return response.json();}).then(data => {data.cameras.forEach(camera => {const camElement = document.getElementById(`cam-${camera.id}`);const statusIndicator = camElement.querySelector('.status-indicator');const objectList = document.getElementById(`objects-${camera.id}`);const fpsElement = document.getElementById(`fps-${camera.id}`);const hasPhone = camera.objects.some(obj =>obj.toLowerCase().includes('phone') ||obj.toLowerCase().includes('mobile'));statusIndicator.className = `status-indicator ${camera.status === '运行中' ? 'online' : 'offline'}`;if (hasPhone) {camElement.classList.add('phone-alert');if (!currentAlerts.some(a => a.cameraId === camera.id)) {currentAlerts.push({cameraId: camera.id,cameraName: camera.name,timestamp: new Date().toLocaleTimeString(),objects: camera.objects});}} else {camElement.classList.remove('phone-alert');currentAlerts = currentAlerts.filter(a => a.cameraId !== camera.id);}objectList.innerHTML = camera.objects.length > 0? camera.objects.map(obj => `<div class="object-tag">${obj}</div>`).join(''): '<div class="object-tag">无检测目标</div>';fpsElement.textContent = camera.fps || '-';});const onlineCount = data.cameras.filter(c => c.status === '运行中').length;document.getElementById('online-count').textContent = onlineCount;// 更新资源监控updateResource('cpu', data.system.cpu, 'CPU');if (gpuAvailable) {updateResource('gpu', data.system.gpu, 'GPU');}updateResource('mem', data.system.memory, '内存');updateAlertSummary();}).catch(error => {console.error('监控数据更新失败:', error);document.getElementById('gpu-usage').style.background = '#666';document.getElementById('gpu-value').textContent = 'N/A';});}function updateResource(type, value, name) {const fill = document.getElementById(`${type}-usage`);const valueElement = document.getElementById(`${type}-value`);// 数值有效性检查if (isNaN(value) || value < 0 || value > 100) {console.warn(`无效的${name}使用率:`, value);fill.style.background = '#666';valueElement.textContent = 'ERR';return;}// 平滑过渡fill.style.transition = 'width 0.5s ease, background 0.5s ease';fill.style.width = `${value}%`;valueElement.textContent = `${Math.round(value)}%`;// 动态颜色if (value > 85) {fill.style.background = 'linear-gradient(90deg, #ff4444, #cc0000)';valueElement.style.color = '#ff4444';} else if (value > 65) {fill.style.background = 'linear-gradient(90deg, #ffd700, #ffaa00)';valueElement.style.color = '#ffd700';} else {fill.style.background = 'linear-gradient(90deg, #3AB0FF, #2A5CAA)';valueElement.style.color = '#3AB0FF';}// GPU特殊处理if (type === 'gpu' && value === 0 && gpuAvailable) {fill.style.background = 'linear-gradient(90deg, #666, #444)';valueElement.textContent = '待机';}}function updateAlertSummary() {const alertCountElement = document.getElementById('alert-count');const alertStatusElement = document.getElementById('alert-status');const summaryCard = document.getElementById('alert-summary');if (currentAlerts.length > 0) {alertCountElement.textContent = currentAlerts.length;alertCountElement.className = 'alert-count has-alert';alertStatusElement.textContent = '检测到手机设备';alertStatusElement.style.color = 'var(--danger-color)';summaryCard.style.borderColor = 'rgba(255, 77, 77, 0.3)';} else {alertCountElement.textContent = '0';alertCountElement.className = 'alert-count no-alert';alertStatusElement.textContent = '系统正常';alertStatusElement.style.color = 'var(--success-color)';summaryCard.style.borderColor = 'rgba(255, 255, 255, 0.1)';}}async function showAlertDetails() {const modal = document.getElementById('alert-modal');const alertDetails = document.getElementById('alert-details');alertDetails.innerHTML = `<div class="alert-list-header"><h3><i class="fas fa-exclamation-circle"></i> 当前活动警报</h3></div>`;if (currentAlerts.length === 0) {alertDetails.innerHTML += `<div class="no-alert"><i class="fas fa-check-circle"></i><p>当前没有活动警报</p></div>`;} else {currentAlerts.forEach(alert => {const alertItem = document.createElement('div');alertItem.className = 'alert-item';alertItem.innerHTML = `<div class="alert-source"><i class="fas fa-video"></i>摄像头: ${alert.cameraName} (ID: ${alert.cameraId})</div><div class="alert-time"><i class="fas fa-clock"></i>首次检测时间: ${alert.timestamp}</div><div class="alert-objects"><i class="fas fa-tag"></i>检测目标: ${alert.objects.join(', ')}</div>`;alertDetails.appendChild(alertItem);});}modal.style.display = 'block';}function closeModal() {document.getElementById('alert-modal').style.display = 'none';}function updateClock() {document.getElementById('live-clock').textContent =new Date().toLocaleString('zh-CN', {year: 'numeric',month: '2-digit',day: '2-digit',hour: '2-digit',minute: '2-digit',second: '2-digit'});}document.getElementById('alert-summary').addEventListener('click', showAlertDetails);document.querySelector('.close-modal').addEventListener('click', closeModal);window.addEventListener('click', (event) => {if (event.target === document.getElementById('alert-modal')) {closeModal();}});setInterval(updateDashboard, 2000);setInterval(updateClock, 1000);updateDashboard();updateClock();</script>
</body>
</html>

还有一个yolov10s模型:

运行结果

http://www.xdnf.cn/news/211609.html

相关文章:

  • 实验七:基于89C51和DS18B20的温度采集与显示
  • 【从滚动条缺失到布局体系:前端布局问题的系统性思考】
  • pytorch 一些常用语法
  • 图漾官网Sample_V1版本C++语言完整参考例子---单相机版本
  • 企业办公协同平台安全一体化生态入住技术架构与接口标准分析报告
  • ubnuntu使用conda进行虚拟环境迁移,复制,克隆
  • Dify 使用模版转换实现更丰富的输入格式支持
  • linux FTP服务器搭建
  • 通信协议——SPI通信协议
  • Go语言中的错误处理
  • CSS:编写位置分类
  • PDF编辑器:Foxit PDF Editor Pro 版功能解析
  • JVM对象存储格式
  • 解决调用Claude 3.7接口 403 Request not allowed问题
  • 贝叶斯优化RF预测模型
  • 轻松实现CI/CD: 用Go编写的命令行工具简化Jenkins构建
  • 处理pdf文件的常用库unstructured和PyPDF2
  • 【PyTorch动态计算图原理精讲】从入门到灵活应用
  • vscode 配置qt
  • WEB漏洞--CSRF及SSRF案例
  • 可靠性工程:加速因子与筛选度计算模型解析
  • 修改输入框选择框颜色
  • jspm老年体检信息管理系统(源码+lw+部署文档+讲解),源码可白嫖!
  • 【论文阅读/复现】RT-DETR的网络结构/训练/推理/验证/导出模型
  • 如何让自己保持一定的神秘感--deepseek
  • k8s部署
  • Vim 中替换字符或文本
  • 水利三维可视化平台怎么做?快速上手的3步指南
  • CMA软件实验室评审政策解读
  • Fortran如何写注释?