SANS critical control(强烈推荐互联网公司参考)

本文提供了关键的安全控制措施,旨在帮助组织机构评估其信息安全状态并改进现有的防护策略。
https://www.sans.org/critical-security-controls/
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>简约图片轮播展示器</title> <style> /* 全局重置 */ * { margin: 0; padding: 0; box-sizing: border-box; } /* 页面基础样式 */ body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; background: #f0f2f5; /* 简约的浅灰色背景 */ min-height: 100vh; display: flex; justify-content: center; align-items: center; padding: 0px; } /* 轮播主容器 */ .carousel-container { max-width: 80%; width: 100%; overflow: hidden; border-radius: 12px; box-shadow: 0 5px 15px rgba(0, 0, 0, 0.08); /* 微妙的阴影 */ margin: 0 auto; } /* 轮播轨道 */ .carousel { display: flex; transition: transform 0.6s cubic-bezier(0.25, 0.1, 0.25, 1); height: 400px; } /* 轮播项 */ .carousel-item { min-width: 25%; /* 默认每屏显示4张 */ height: 100%; position: relative; overflow: hidden; transition: transform 0.3s; } /* 图片悬停效果 */ .carousel-item:hover { transform: scale(1.03); z-index: 2; } /* 图片样式 */ .carousel-item img { width: 100%; height: 100%; object-fit: cover; display: block; } /* 图片信息面板 */ .image-info { position: absolute; height: 190px; /* 统一高度 */ bottom: 0; left: 0; right: 0; background: rgba(0, 0, 0, 0.75); color: white; padding: 15px; transform: translateY(0); transition: transform 0.3s ease; } /* 悬停时显示信息 */ .carousel-item:hover .image-info { transform: translateY(100%); } /* 信息标题 */ .image-info h3 { margin-bottom: 5px; font-size: 1.1rem; font-weight: 600; } /* 信息描述 */ .image-info p { font-size: 0.9rem; opacity: 0.9; } /* 控制按钮容器 */ .carousel-controls { display: flex; justify-content: center; gap: 15px; margin-top: 25px; } /* 简约按钮样式 */ .control-btn { background: #000; color: #fff; border: 2px solid #e0e0e0; padding: 10px 25px; border-radius: 8px; cursor: pointer; font-size: 0.95rem; font-weight: 600; transition: all 0.3s; min-width: 120px; } /* 按钮悬停效果 */ .control-btn:hover { background: #fff; border-color: #000; color: #000; } /* 按钮活动状态 */ .control-btn:active { transform: translateY(1px); } /* 指示器容器 */ .indicator { display: flex; justify-content: center; gap: 10px; margin-top: 20px; padding: 5px; } /* 指示点样式 */ .indicator-dot { width: 12px; height: 12px; border-radius: 50%; background: #fff; cursor: pointer; transition: all 0.3s; } /* 当前激活的指示点 */ .indicator-dot.active { background: #000; transform: scale(1.2); } /* 响应式设计 */ @media (max-width: 900px) { .carousel-item { min-width: 33.333%; /* 中等屏幕每屏显示3张 */ } } @media (max-width: 700px) { .carousel-item { min-width: 50%; /* 小屏幕每屏显示2张 */ } .carousel { height: 350px; } } @media (max-width: 500px) { .carousel-item { min-width: 100%; /* 超小屏幕每屏显示1张 */ } .carousel { height: 300px; } .carousel-controls { flex-wrap: wrap; } .control-btn { min-width: 100px; padding: 8px 15px; } } </style> </head> <body> <!-- 轮播主容器 --> <div class="carousel-container"> <!-- 轮播轨道 --> <div class="carousel"> <!-- 轮播项1 --> <div class="carousel-item"> <img src="https://www.fetchingpack.com/wp-content/uploads/2025/06/Lamination-Gloss_Matte1_compressed.png" alt="Lamination (Gloss/Matte)"> <div class="image-info"> <h3>Lamination (Gloss/Matte)</h3> <p>– Applying a thin plastic film over the printed sheet to enhance scratch resistance, moisture protection and overall durability. Gloss lamination yields a shiny surface, while matte lamination gives a low-sheen, soft-touch effect.</p> </div> </div> <!-- 轮播项2 --> <div class="carousel-item"> <img src="https://www.fetchingpack.com/wp-content/uploads/2025/06/UV-Coating-Spot_Overall_compressed.png" alt="UV Coating (Spot/Overall)"> <div class="image-info"> <h3>UV Coating (Spot/Overall)</h3> <p>– Spreading a liquid UV-curable varnish onto either selected areas (spot UV) or the entire sheet, then instantly curing it under UV light. Creates high gloss and tactile contrast.</p> </div> </div> <!-- 轮播项3 --> <div class="carousel-item"> <img src="https://www.fetchingpack.com/wp-content/uploads/2025/06/Hot-Foil-Stamping_compressed.png" alt="Hot Foil Stamping"> <div class="image-info"> <h3>Hot Foil Stamping</h3> <p>– Transferring metallic or pigmented foil onto specific areas of the print using heat and pressure. Delivers a premium metallic sheen (gold, silver, colored foils) for logos or decorative accents.</p> </div> </div> <!-- 轮播项4 --> <div class="carousel-item"> <img src="https://www.fetchingpack.com/wp-content/uploads/2025/06/Embossing-_-Debossing1_compressed.png" alt="Embossing / Debossing"> <div class="image-info"> <h3>Embossing / Debossing</h3> <p>– Pressing the paper between male and female dies to create a raised (emboss) or recessed (deboss) 3D relief. Adds tactile interest and a sense of depth.</p> </div> </div> <!-- 轮播项5 --> <div class="carousel-item"> <img src="https://www.fetchingpack.com/wp-content/uploads/2025/06/Die-Cutting_compressed.png" alt="Die-Cutting"> <div class="image-info"> <h3>Die-Cutting</h3> <p>– Using a custom-made metal die to cut the printed sheet into precise shapes or create windows/slots. Essential for producing custom box shapes, hang-tabs, or intricate cut-outs.</p> </div> </div> <!-- 轮播项6 --> <div class="carousel-item"> <img src="https://www.fetchingpack.com/wp-content/uploads/2025/06/Creasing-Folding-Crease_compressed.png" alt="Creasing (Folding Crease)"> <div class="image-info"> <h3>Creasing (Folding Crease)</h3> <p>– Impressing a crease line on the sheet to facilitate clean, accurate folds without cracking the coating or ink. Critical for boxes, folders, and other folded structures.</p> </div> </div> <!-- 轮播项7 --> <div class="carousel-item"> <img src="https://www.fetchingpack.com/wp-content/uploads/2025/06/Spot-UV-Emboss-Combination_compressed.png" alt="Spot UV + Emboss Combination"> <div class="image-info"> <h3>Spot UV + Emboss Combination</h3> <p>– First applying spot UV coating, then embossing the same area to create a shiny, raised element. Enhances both visual shine and tactile relief simultaneously.</p> </div> </div> <!-- 轮播项8 --> <div class="carousel-item"> <img src="https://www.fetchingpack.com/wp-content/uploads/2025/06/Laser-Finishing-Holographic-Etch-Combination_compressed.png" alt="Laser Finishing + Holographic Etch Combination"> <div class="image-info"> <h3>Laser Finishing + Holographic Etch Combination</h3> <p>– First using a focused laser beam to engrave microscopic holographic patterns onto foil or film, then sealing the treated surface through heat or UV curing to lock in the effect. Creates vivid, color-shifting visuals that shimmer with every change in viewing angle and imparts subtle textural relief, adding a futuristic premium look and an effective anti-counterfeiting feature.</p> <p>• Pearlescent varnish for shimmering, iridescent highlights</p> <p>• Matte varnish for a soft, low-gloss finish</p> <p>• Scented varnish that releases fragrance when touched</p> </div> </div> </div> <!-- 控制按钮 --> <div class="carousel-controls"> <button class="control-btn" id="prevBtn">Previous</button> <button class="control-btn" id="nextBtn">next</button> <button class="control-btn" id="autoBtn">暂停轮播</button> </div> <!-- 指示器 --> <div class="indicator"> <div class="indicator-dot active" data-index="0"></div> <div class="indicator-dot" data-index="1"></div> <div class="indicator-dot" data-index="2"></div> <div class="indicator-dot" data-index="3"></div> </div> </div> <script> // 当文档加载完成后执行 document.addEventListener('DOMContentLoaded', function() { // 获取DOM元素 const carousel = document.querySelector('.carousel'); const items = document.querySelectorAll('.carousel-item'); const prevBtn = document.getElementById('prevBtn'); const nextBtn = document.getElementById('nextBtn'); const autoBtn = document.getElementById('autoBtn'); const dots = document.querySelectorAll('.indicator-dot'); // 初始化变量 let currentIndex = 0; let itemsPerView = calculateItemsPerView(); let autoPlayInterval; let isAutoPlay = true; // 计算当前视图显示的项目数 function calculateItemsPerView() { const width = window.innerWidth; if (width <= 500) return 1; if (width <= 700) return 2; if (width <= 900) return 3; return 4; } // 更新轮播位置 function updateCarousel() { // 计算每个项目的宽度百分比 const itemWidth = 100 / itemsPerView; // 计算偏移量 const offset = -currentIndex * itemWidth; // 应用转换效果 carousel.style.transform = `translateX(${offset}%)`; // 更新指示点状态 dots.forEach((dot, index) => { dot.classList.toggle('active', index === currentIndex); }); } // 下一张 function nextSlide() { // 计算最大索引 const maxIndex = items.length - itemsPerView; // 更新当前索引(循环) currentIndex = currentIndex >= maxIndex ? 0 : currentIndex + 1; updateCarousel(); } // 上一张 function prevSlide() { // 计算最大索引 const maxIndex = items.length - itemsPerView; // 更新当前索引(循环) currentIndex = currentIndex <= 0 ? maxIndex : currentIndex - 1; updateCarousel(); } // 自动轮播 function startAutoPlay() { if (isAutoPlay) { // 设置轮播间隔 autoPlayInterval = setInterval(nextSlide, 3000); // 更新按钮文本 autoBtn.textContent = 'stop'; } } // 停止自动轮播 function stopAutoPlay() { // 清除轮播间隔 clearInterval(autoPlayInterval); // 更新按钮文本 autoBtn.textContent = 'start'; } // 切换自动轮播状态 function toggleAutoPlay() { // 反转自动播放状态 isAutoPlay = !isAutoPlay; if (isAutoPlay) { startAutoPlay(); } else { stopAutoPlay(); } } // 初始化轮播 function init() { // 计算每屏显示数量 itemsPerView = calculateItemsPerView(); // 更新轮播位置 updateCarousel(); // 开始自动播放 startAutoPlay(); } // 事件监听器 nextBtn.addEventListener('click', () => { nextSlide(); // 如果自动播放已暂停,则停止轮播 if (!isAutoPlay) stopAutoPlay(); }); prevBtn.addEventListener('click', () => { prevSlide(); // 如果自动播放已暂停,则停止轮播 if (!isAutoPlay) stopAutoPlay(); }); autoBtn.addEventListener('click', toggleAutoPlay); // 为每个指示点添加点击事件 dots.forEach(dot => { dot.addEventListener('click', () => { // 获取并设置当前索引 currentIndex = parseInt(dot.getAttribute('data-index')); updateCarousel(); // 如果自动播放已暂停,则停止轮播 if (!isAutoPlay) stopAutoPlay(); }); }); // 窗口大小变化时重新计算 window.addEventListener('resize', () => { // 重新计算每屏显示数量 itemsPerView = calculateItemsPerView(); // 更新轮播位置 updateCarousel(); }); // 初始化轮播 init(); }); </script> </body> </html> 这个代码为什么修改了网页的字体样式,怎么修改可以让这个代码不影响网页的字体样式
06-14
在pyqt界面上添加按钮,实现中英切换,import sys import cv2 import numpy as np import json import os import time import datetime from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QLabel, QVBoxLayout, QHBoxLayout, QPushButton, QMessageBox, QLineEdit, QSizePolicy, QGroupBox, QFrame, QStackedLayout) from PyQt5.QtCore import Qt, pyqtSignal, QThread, QMutex, QMutexLocker, QTimer from PyQt5.QtGui import QImage, QPixmap, QIntValidator, QFont, QColor, QPalette from ultralytics import YOLO from PyQt5.QtNetwork import QTcpSocket, QAbstractSocket # 配置参数 CAPTURE_INDEX = 0 OBJ_LIST = ['without-safetybelt', 'safetybelt'] # 修改为安全带类别 DETECTOR_PATH = 'C:/weights/safetybelt/best.pt' # 双语文本字典 TEXT = { "main_title": ["AI智能安全带检测系统", "AI Smart Safety Belt Detection System"], "video_title": ["实时监控画面", "Live Monitoring"], "network_settings": ["网络设置", "Network Settings"], "server_ip": ["服务器IP:", "Server IP:"], "port": ["端口号:", "Port:"], "set_network": ["设置网络", "Set Network"], "connection_status": ["连接状态", "Connection Status"], "not_connected": ["未连接", "Not Connected"], "connected": ["已连接", "Connected"], "disconnected": ["断开连接", "Disconnected"], "detection_status": ["检测状态", "Detection Status"], "belt_status": ["安全带佩戴状态", "Safety Belt Status"], "waiting_detection": ["-- 等待检测 --", "-- Waiting for Detection --"], "safe_state": ["安全状态", "Safe State"], "danger_state": ["危险状态!", "Danger State!"], "no_person": ["未检测到人员", "No Person Detected"], "status_explanation": ["状态说明:", "Status Explanation:"], "safe_explanation": ["安全: 所有人员佩戴安全带", "Safe: All personnel wearing safety belts"], "danger_explanation": ["危险: 检测到未佩戴安全带", "Danger: Detected personnel not wearing safety belts"], "info_explanation": ["信息: 未检测到人员", "Info: No personnel detected"], "loading_camera": ["正在加载摄像头...", "Loading camera..."], "system_started": ["系统已启动,正在初始化...", "System started, initializing..."], "sending_status": ["发送状态", "Sending Status"], "not_sent": ["未发送", "Not Sent"], "preparing_send": ["准备发送...", "Preparing to send..."], "send_success": ["发送成功", "Send Successful"], "send_failed": ["发送失败", "Send Failed"], "error": ["错误", "Error"], "invalid_ip": ["无效的IP地址格式", "Invalid IP address format"], "invalid_port": ["端口号必须为1-65535之间的整数", "Port must be an integer between 1-65535"], "settings_success": ["设置成功", "Settings Successful"], "network_updated": ["已更新网络设置", "Network settings updated"], "config_error": ["配置错误", "Configuration Error"], "config_failed": ["配置文件格式错误,已使用默认配置", "Configuration file format error, using default settings"], "connecting": ["正在连接", "Connecting to"], "last_update": ["最后更新", "Last update"], "connecting_status": ["正在连接...", "Connecting..."] } # 样式常量 - 现代深色主题 MAIN_BG_COLOR = "#1e1e2e" # 深蓝紫色背景 PANEL_BG_COLOR = "#252536" # 面板背景 BUTTON_COLOR = "#4169E1" # 皇家蓝按钮 BUTTON_HOVER_COLOR = "#5a7df1" # 浅蓝色悬停 BUTTON_PRESSED_COLOR = "#2a4fc0" # 深蓝色按下 STATUS_SAFE_COLOR = "#32CD32" # 安全绿色 STATUS_DANGER_COLOR = "#FF4500" # 危险橙色 STATUS_INFO_COLOR = "#1E90FF" # 信息蓝色 TEXT_COLOR = "#e0e0ff" # 浅紫色文本 BORDER_COLOR = "#4a4a6a" # 边框颜色 ACCENT_COLOR = "#9370DB" # 强调色(紫色) # 语言设置 (0=中文, 1=英文) LANGUAGE = 0 # 默认中文 def tr(key): """翻译函数,根据LANGUAGE设置返回对应语言的文本""" return TEXT[key][LANGUAGE] if key in TEXT else key # TCP客户端线程 class TCPClientThread(QThread): connectionStateChanged = pyqtSignal(str) def __init__(self, server_ip, server_port=7978): super().__init__() self.server_ip = server_ip self.server_port = server_port self.running = True self.client_socket = None def run(self): while self.running: self.client_socket = QTcpSocket() self.client_socket.connectToHost(self.server_ip, self.server_port) if self.client_socket.waitForConnected(1000): self.connectionStateChanged.emit(tr("connected")) while self.running and self.client_socket.state() == QAbstractSocket.ConnectedState: self.msleep(100) else: self.connectionStateChanged.emit(tr("disconnected")) time.sleep(5) def send_data(self, message): if not (self.client_socket and self.client_socket.state() == QAbstractSocket.ConnectedState): return -1 try: byte_written = self.client_socket.write(message.encode('utf-8')) if byte_written > 0: self.client_socket.waitForBytesWritten(1000) return byte_written return -1 except Exception as e: print(f"发送异常: {str(e)}") return -1 def stop(self): self.running = False if self.client_socket: self.client_socket.abort() self.wait() # 视频处理线程 class VideoThread(QThread): update_signal = pyqtSignal(np.ndarray, str) def __init__(self): super().__init__() self._run_flag = True self.cap = cv2.VideoCapture(0) self.model_belt = YOLO(DETECTOR_PATH) # 修改变量名为安全带检测 self.data_lock = QMutex() self.current_data = {'safety': 'without-safetybelt'} # 默认状态为未佩戴安全带 # FPS相关属性 self.frame_count = 0 self.start_time = time.time() self.fps = 0 def run(self): while self._run_flag: ret, frame = self.cap.read() if ret: # 安全带检测 results_belt = self.model_belt(frame) # 修改变量名 annotated_frame = frame.copy() # 初始化安全状态 has_belt = False has_no_belt = False # 安全带检测逻辑 if results_belt[0].boxes is not None: # 修改变量名 boxes_belt = results_belt[0].boxes # 修改变量名 valid_boxes_belt = [box for box in boxes_belt if box.conf.item() > 0.5] # 修改变量名 for box in valid_boxes_belt: # 修改变量名 cls_id = int(box.cls) cls_name = self.model_belt.names[cls_id] # 修改变量名 if cls_name in OBJ_LIST: x1, y1, x2, y2 = map(int, box.xyxy[0]) # 根据是否佩戴安全带设置不同颜色 if cls_name == 'safetybelt': # 佩戴安全带 color = (0, 255, 0) # 绿色 has_belt = True else: # 未佩戴安全带 color = (0, 0, 255) # 红色 has_no_belt = True # 绘制检测框 cv2.rectangle(annotated_frame, (x1, y1), (x2, y2), color, 2) cv2.putText(annotated_frame, cls_name, (x1, y1-10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 2) # 确定整体安全状态 if has_no_belt: safety_status = 'without-safetybelt' # 只要有一个人未佩戴安全带 elif has_belt: safety_status = 'safetybelt' # 所有人都佩戴了安全带 else: safety_status = '' # 未检测到人员 # 计算并显示FPS(在视频帧上绘制) self.frame_count += 1 if (time.time() - self.start_time) > 1.0: self.fps = self.frame_count / (time.time() - self.start_time) self.frame_count = 0 self.start_time = time.time() # 在视频帧上绘制FPS fps_text = f"FPS: {self.fps:.1f}" cv2.putText(annotated_frame, fps_text, (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 1, cv2.LINE_AA) self.update_signal.emit(annotated_frame, safety_status) self.update_data(safety_status) def update_data(self, safety): with QMutexLocker(self.data_lock): self.current_data.update({ 'safety': safety or 'without-safetybelt' }) def stop(self): self._run_flag = False self.cap.release() self.wait() # 主窗口类 class MainWindow(QMainWindow): def __init__(self, server_ip='127.0.0.1', server_port=7978): super().__init__() self.setWindowTitle(tr("main_title")) # 修改标题为安全带检测 self.setGeometry(100, 100, 1200, 750) # 设置主窗口样式 self.setStyleSheet(f""" background-color: {MAIN_BG_COLOR}; color: {TEXT_COLOR}; font-family: 'Segoe UI', Arial, sans-serif; """) # 初始化成员变量 self.video_thread = None self.tcp_client = None self.first_frame_received = False # 标记是否接收到第一帧 # 初始化界面 main_widget = QWidget() main_layout = QHBoxLayout(main_widget) main_layout.setContentsMargins(20, 20, 20, 20) main_layout.setSpacing(20) # 左侧视频显示区域 video_frame = QFrame() video_frame.setFrameShape(QFrame.StyledPanel) video_frame.setStyleSheet(f""" background-color: {PANEL_BG_COLOR}; border-radius: 12px; border: 1px solid {BORDER_COLOR}; """) video_layout = QVBoxLayout(video_frame) video_layout.setContentsMargins(15, 15, 15, 15) video_layout.setSpacing(15) # 视频标题 video_title = QLabel(tr("video_title")) video_title.setAlignment(Qt.AlignCenter) video_title.setStyleSheet(""" font-size: 20px; font-weight: bold; color: #b0b0ff; padding: 8px; border-bottom: 2px solid #4a4a6a; """) video_layout.addWidget(video_title) # 视频显示标签 self.video_label = QLabel() self.video_label.setAlignment(Qt.AlignCenter) self.video_label.setMinimumSize(720, 540) self.video_label.setStyleSheet(""" background-color: #000000; border-radius: 8px; border: 1px solid #4a4a6a; """) # 添加摄像头加载提示(直接覆盖在视频标签上) self.camera_status_label = QLabel(tr("loading_camera")) self.camera_status_label.setAlignment(Qt.AlignCenter) self.camera_status_label.setStyleSheet(""" font-size: 24px; font-weight: bold; color: #9370DB; background-color: rgba(30, 30, 46, 180); border-radius: 8px; padding: 20px; """) self.camera_status_label.setVisible(True) # 初始显示加载提示 # 使用布局将提示标签覆盖在视频标签上 video_container = QWidget() video_container_layout = QStackedLayout(video_container) video_container_layout.setStackingMode(QStackedLayout.StackAll) video_container_layout.addWidget(self.video_label) video_container_layout.addWidget(self.camera_status_label) video_layout.addWidget(video_container, 1) main_layout.addWidget(video_frame, 70) # 右侧控制面板 control_frame = QFrame() control_frame.setStyleSheet(f""" background-color: {PANEL_BG_COLOR}; border-radius: 12px; border: 1px solid {BORDER_COLOR}; """) control_layout = QVBoxLayout(control_frame) control_layout.setContentsMargins(20, 20, 20, 20) control_layout.setSpacing(20) # 系统标题 title_label = QLabel(tr("main_title")) # 修改为安全带检测 title_label.setAlignment(Qt.AlignCenter) title_label.setStyleSheet(""" font-size: 24px; font-weight: bold; color: {ACCENT_COLOR}; padding: 10px 0; border-bottom: 2px solid #4a4a6a; """.format(ACCENT_COLOR=ACCENT_COLOR)) control_layout.addWidget(title_label) # 网络设置组 network_group = QGroupBox(tr("network_settings")) network_group.setStyleSheet(f""" QGroupBox {{ font-size: 18px; font-weight: bold; color: {TEXT_COLOR}; border: none; }} QGroupBox::title {{ subcontrol-origin: margin; left: 10px; padding: 0 5px; color: {ACCENT_COLOR}; }} """) network_layout = QVBoxLayout(network_group) network_layout.setSpacing(15) network_layout.setContentsMargins(15, 25, 15, 15) # IP地址行 ip_row = QHBoxLayout() ip_label = QLabel(tr("server_ip")) ip_label.setStyleSheet("font-size: 16px;") self.ip_line_edit = QLineEdit(server_ip) self.ip_line_edit.setStyleSheet(f""" QLineEdit {{ background-color: #1e1e2e; color: {TEXT_COLOR}; border: 1px solid {BORDER_COLOR}; border-radius: 6px; padding: 8px 12px; font-size: 16px; selection-background-color: {ACCENT_COLOR}; }} QLineEdit:focus {{ border: 2px solid {ACCENT_COLOR}; }} """) ip_row.addWidget(ip_label) ip_row.addWidget(self.ip_line_edit, 1) network_layout.addLayout(ip_row) # 端口行 port_row = QHBoxLayout() port_label = QLabel(tr("port")) port_label.setStyleSheet("font-size: 16px;") self.port_line_edit = QLineEdit(str(server_port)) self.port_line_edit.setValidator(QIntValidator(1, 65535, self)) self.port_line_edit.setStyleSheet(f""" QLineEdit {{ background-color: #1e1e2e; color: {TEXT_COLOR}; border: 1px solid {BORDER_COLOR}; border-radius: 6px; padding: 8px 12px; font-size: 16px; selection-background-color: {ACCENT_COLOR}; }} QLineEdit:focus {{ border: 2px solid {ACCENT_COLOR}; }} """) port_row.addWidget(port_label) port_row.addWidget(self.port_line_edit, 1) network_layout.addLayout(port_row) # 按钮行 button_row = QHBoxLayout() button_row.setSpacing(15) self.set_network_button = QPushButton(tr("set_network")) self.set_network_button.setCursor(Qt.PointingHandCursor) self.set_network_button.setStyleSheet(f""" QPushButton {{ background-color: {BUTTON_COLOR}; color: white; border: none; border-radius: 8px; padding: 12px 20px; font-size: 16px; font-weight: bold; min-width: 120px; }} QPushButton:hover {{ background-color: {BUTTON_HOVER_COLOR}; }} QPushButton:pressed {{ background-color: {BUTTON_PRESSED_COLOR}; }} """) # 连接状态显示 self.connect_label = QLabel(f"{tr('connection_status')}: {tr('not_connected')}") self.connect_label.setStyleSheet(""" font-size: 16px; font-weight: bold; padding: 10px; background-color: #1e1e2e; border-radius: 8px; border: 1px solid #4a4a6a; """) button_row.addWidget(self.set_network_button) button_row.addWidget(self.connect_label, 1) network_layout.addLayout(button_row) control_layout.addWidget(network_group) # 状态显示组 status_group = QGroupBox(tr("detection_status")) status_group.setStyleSheet(f""" QGroupBox {{ font-size: 18px; font-weight: bold; color: {TEXT_COLOR}; border: none; }} QGroupBox::title {{ subcontrol-origin: margin; left: 10px; padding: 0 5px; color: {ACCENT_COLOR}; }} """) status_layout = QVBoxLayout(status_group) status_layout.setSpacing(15) status_layout.setContentsMargins(15, 25, 15, 15) # 安全带状态显示 status_box = QFrame() status_box.setStyleSheet(f""" background-color: #1e1e2e; border-radius: 12px; border: 1px solid #4a4a6a; """) status_box_layout = QVBoxLayout(status_box) status_box_layout.setContentsMargins(20, 20, 20, 20) status_box_layout.setSpacing(15) status_title = QLabel(tr("belt_status")) # 修改为安全带 status_title.setStyleSheet(""" font-size: 18px; font-weight: bold; color: #b0b0ff; padding-bottom: 5px; border-bottom: 1px solid #4a4a6a; """) status_title.setAlignment(Qt.AlignCenter) status_box_layout.addWidget(status_title) self.belt_display = QLabel(tr("waiting_detection")) # 修改变量名 self.belt_display.setAlignment(Qt.AlignCenter) self.belt_display.setStyleSheet(f""" font-size: 28px; font-weight: bold; padding: 25px 0; border-radius: 8px; background-color: #2a2a3a; """) status_box_layout.addWidget(self.belt_display) # 状态说明 status_info = QLabel(tr("status_explanation")) status_info.setStyleSheet("font-size: 16px; font-weight: bold;") # 状态指示器 status_indicator = QWidget() indicator_layout = QVBoxLayout(status_indicator) indicator_layout.setSpacing(5) # 安全状态 safe_indicator = QHBoxLayout() safe_label = QLabel(tr("safe_explanation")) # 修改为安全带 safe_label.setStyleSheet("font-size: 14px;") safe_dot = QLabel("●") safe_dot.setStyleSheet(f"color: {STATUS_SAFE_COLOR}; font-size: 20px;") safe_indicator.addWidget(safe_dot) safe_indicator.addWidget(safe_label) safe_indicator.addStretch() indicator_layout.addLayout(safe_indicator) # 危险状态 danger_indicator = QHBoxLayout() danger_label = QLabel(tr("danger_explanation")) # 修改为安全带 danger_label.setStyleSheet("font-size: 14px;") danger_dot = QLabel("●") danger_dot.setStyleSheet(f"color: {STATUS_DANGER_COLOR}; font-size: 20px;") danger_indicator.addWidget(danger_dot) danger_indicator.addWidget(danger_label) danger_indicator.addStretch() indicator_layout.addLayout(danger_indicator) # 信息状态 info_indicator = QHBoxLayout() info_label = QLabel(tr("info_explanation")) info_label.setStyleSheet("font-size: 14px;") info_dot = QLabel("●") info_dot.setStyleSheet(f"color: {STATUS_INFO_COLOR}; font-size: 20px;") info_indicator.addWidget(info_dot) info_indicator.addWidget(info_label) info_indicator.addStretch() indicator_layout.addLayout(info_indicator) status_box_layout.addWidget(status_info) status_box_layout.addWidget(status_indicator) status_layout.addWidget(status_box) control_layout.addWidget(status_group) # 添加控制面板到主布局 main_layout.addWidget(control_frame, 30) self.setCentralWidget(main_widget) # 连接设置网络按钮的信号 self.set_network_button.clicked.connect(self.update_network) self.load_config() # 加载配置文件 self.setup_tcp() # 建立TCP连接 # 初始化视频线程 self.video_thread = VideoThread() self.video_thread.update_signal.connect(self.update_frame) self.video_thread.start() # 状态栏初始化 self.statusBar().setStyleSheet(f""" background-color: {PANEL_BG_COLOR}; color: {TEXT_COLOR}; border-top: 1px solid {BORDER_COLOR}; font-size: 12px; padding: 4px; """) self.statusBar().showMessage(tr("system_started")) self.send_status_label = QLabel(f"{tr('sending_status')}: {tr('not_sent')}") self.statusBar().addPermanentWidget(self.send_status_label) self.setup_timers() # 初始化定时器 def update_send_status(self, message, color="white"): """更新发送状态显示""" color_map = { "green": STATUS_SAFE_COLOR, "red": STATUS_DANGER_COLOR, "blue": STATUS_INFO_COLOR, "orange": "#ff8c00", "white": TEXT_COLOR } hex_color = color_map.get(color.lower(), TEXT_COLOR) self.send_status_label.setStyleSheet(f"color: {hex_color}; font-size: 12px; font-weight: bold;") self.send_status_label.setText(f"{tr('sending_status')}: {message}") # 状态栏更新 current_time = datetime.datetime.now().strftime('%H:%M:%S') self.statusBar().showMessage(f"{tr('last_update')}: {current_time} - {message}", 3000) def send_class_data(self): """发送检测数据""" self.update_send_status(tr("preparing_send"), "blue") sent_bytes = -1 try: # 基础校验 if not hasattr(self, 'tcp_client') or not self.tcp_client.client_socket: self.update_send_status(tr("not_connected"), "red") return if self.tcp_client.client_socket.state() != QAbstractSocket.ConnectedState: self.update_send_status(tr("not_connected"), "red") return # 获取数据 with QMutexLocker(self.video_thread.data_lock): data = self.video_thread.current_data.copy() # 生成报告 xml_data = self.generate_report(data) # 执行发送 sent_bytes = self.tcp_client.send_data(xml_data) expected_bytes = len(xml_data.encode('utf-8')) # 结果处理 if sent_bytes == expected_bytes: status_msg = tr("send_success") else: status_msg = f"{tr('send_failed')} ({sent_bytes}/{expected_bytes} {tr('bytes') if LANGUAGE == 0 else 'bytes'})" color = "green" if sent_bytes == expected_bytes else "orange" self.update_send_status(status_msg, color) except Exception as e: error_msg = f"{tr('send_failed')}: {str(e)} | {tr('sent_bytes') if LANGUAGE == 0 else 'Sent'}: {sent_bytes}{tr('bytes') if LANGUAGE == 0 else 'bytes'}" print(error_msg) self.update_send_status(error_msg[:40], "red") # 异常时强制重置连接 if hasattr(self, 'tcp_client'): self.tcp_client.stop() def generate_report(self, data): """生成报告字符串""" # 判断安全模式(safetybelt=1,其他=0) mode = 1 if data.get('safety') == 'safetybelt' else 0 # 修改为安全带检测 # 构建字符串 report_str = ( "{json;report;" f"mode:{mode};}}" ) return report_str def update_network(self): """更新网络设置""" new_ip = self.ip_line_edit.text() new_port = self.port_line_edit.text() # 输入验证 if not self.validate_ip(new_ip): QMessageBox.critical(self, tr("error"), tr("invalid_ip")) return try: port = int(new_port) if not (1 <= port <= 65535): raise ValueError except ValueError: QMessageBox.critical(self, tr("error"), tr("invalid_port")) return # 更新界面显示 self.ip_line_edit.setText(new_ip) self.port_line_edit.setText(str(port)) # 重启TCP连接 self.setup_tcp() # 保存配置 self.save_config() # 显示成功消息 QMessageBox.information(self, tr("settings_success"), f"{tr('network_updated')}:\nIP: {new_ip}\n{tr('port')}: {port}", QMessageBox.Ok) def save_config(self): """保存配置到文件""" config_folder = 'C:/config' if not os.path.exists(config_folder): os.makedirs(config_folder) config_path = os.path.join(config_folder, 'config.txt') with open(config_path, 'w') as f: f.write("\n".join([ self.ip_line_edit.text(), self.port_line_edit.text() ])) def validate_ip(self, ip): """IP地址验证方法""" try: parts = ip.split('.') if len(parts) != 4: return False return all(0 <= int(part) < 256 for part in parts) except: return False def setup_timers(self): """设置定时器""" self.class_timer = QTimer() self.class_timer.setInterval(1000) # 每秒发送一次数据 self.class_timer.timeout.connect(self.send_class_data) self.class_timer.start() def setup_tcp(self): """创建TCP连接""" # 获取当前IP current_ip = self.ip_line_edit.text() try: current_port = int(self.port_line_edit.text()) except ValueError: current_port = 7978 # 如果已有连接,先停止 if hasattr(self, 'tcp_client') and self.tcp_client: self.tcp_client.stop() self.tcp_client.wait() # 创建新连接 self.tcp_client = TCPClientThread(current_ip, current_port) self.tcp_client.connectionStateChanged.connect(self.update_connection_status) self.tcp_client.start() self.statusBar().showMessage(f"{tr('connecting')} {current_ip}...", 3000) def load_config(self): """加载配置文件""" config_folder = 'C:/config' config_path = os.path.join(config_folder, 'config.txt') try: if os.path.exists(config_path): with open(config_path, 'r') as f: lines = [line.strip() for line in f.readlines()] # 读取IP地址(第1行)和端口(第2行) if len(lines) >= 1: self.ip_line_edit.setText(lines[0]) if len(lines) >= 2: self.port_line_edit.setText(lines[1]) print(f"配置加载成功:IP={lines[0]}") except Exception as e: print(f"配置加载失败: {str(e)}") QMessageBox.warning(self, tr("config_error"), f"{tr('config_failed')}\n{tr('error')}:{str(e)}") def update_frame(self, frame, safety_status): # 如果是第一帧,隐藏提示 if not self.first_frame_received: self.camera_status_label.setVisible(False) self.first_frame_received = True # 更新安全带状态显示 if safety_status == 'safetybelt': # 佩戴安全带 self.belt_display.setText(tr("safe_state")) # 修改为安全带状态 self.belt_display.setStyleSheet(f""" font-size: 28px; font-weight: bold; color: {STATUS_SAFE_COLOR}; padding: 25px 0; border-radius: 8px; background-color: #2a2a3a; border: 2px solid {STATUS_SAFE_COLOR}; """) elif safety_status == 'without-safetybelt': # 未佩戴安全带 self.belt_display.setText(tr("danger_state")) self.belt_display.setStyleSheet(f""" font-size: 28px; font-weight: bold; color: {STATUS_DANGER_COLOR}; padding: 25px 0; border-radius: 8px; background-color: #2a2a3a; border: 2px solid {STATUS_DANGER_COLOR}; """) else: # 未检测到人员 self.belt_display.setText(tr("no_person")) self.belt_display.setStyleSheet(f""" font-size: 28px; font-weight: bold; color: {STATUS_INFO_COLOR}; padding: 25px 0; border-radius: 8px; background-color: #2a2a3a; border: 2px solid {STATUS_INFO_COLOR}; """) # 显示视频帧(包含FPS信息) rgb_image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) h, w, ch = rgb_image.shape qt_image = QImage(rgb_image.data, w, h, ch * w, QImage.Format_RGB888) pixmap = QPixmap.fromImage(qt_image) self.video_label.setPixmap(pixmap.scaled( self.video_label.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation)) def update_connection_status(self, status): """更新连接状态显示""" self.connect_label.setText(f"{tr('connection_status')}: {status}") if status == tr("connected"): self.connect_label.setStyleSheet(f""" font-size: 16px; font-weight: bold; color: {STATUS_SAFE_COLOR}; padding: 10px; background-color: #1e1e2e; border-radius: 8px; border: 2px solid {STATUS_SAFE_COLOR}; """) else: self.connect_label.setStyleSheet(f""" font-size: 16px; font-weight: bold; color: {STATUS_DANGER_COLOR}; padding: 10px; background-color: #1e1e2e; border-radius: 8px; border: 2px solid {STATUS_DANGER_COLOR}; """) def closeEvent(self, event): """关闭事件处理""" self.video_thread.stop() if hasattr(self, 'tcp_client'): self.tcp_client.stop() if hasattr(self, 'class_timer') and self.class_timer.isActive(): self.class_timer.stop() event.accept() if __name__ == "__main__": app = QApplication(sys.argv) # 设置应用字体 font = QFont("Segoe UI", 10) app.setFont(font) # 从配置文件加载初始端口 config_folder = 'C:/config' config_path = os.path.join(config_folder, 'config.txt') default_port = 7978 # 如果配置文件不存在,创建配置目录 if not os.path.exists(config_folder): os.makedirs(config_folder) # 尝试加载配置 if os.path.exists(config_path): try: with open(config_path, 'r') as f: lines = f.readlines() if len(lines) >= 2: default_port = int(lines[1].strip()) except: pass window = MainWindow(server_port=default_port) window.show() sys.exit(app.exec_())
08-21
内容概要:本文系统介绍了算术优化算法(AOA)的基本原理、核心思想及Python实现方法,并通过图像分割的实际案例展示了其应用价值。AOA是一种基于种群的元启发式算法,其核心思想来源于四则运算,利用乘除运算进行全局勘探,加减运算进行局部开发,通过数学优化器加速函数(MOA)和数学优化概率(MOP)动态控制搜索过程,在全局探索与局部开发之间实现平衡。文章详细解析了算法的初始化、勘探与开发阶段的更新策略,并提供了完整的Python代码实现,结合Rastrigin函数进行测试验证。进一步地,以Flask框架搭建前后端分离系统,将AOA应用于图像分割任务,展示了其在实际工程中的可行性与高效性。最后,通过收敛速度、寻优精度等指标评估算法性能,并提出自适应参数调整、模型优化和并行计算等改进策略。; 适合人群:具备一定Python编程基础和优化算法基础知识的高校学生、科研人员及工程技术人员,尤其适合从事人工智能、图像处理、智能优化等领域的从业者;; 使用场景及目标:①理解元启发式算法的设计思想与实现机制;②掌握AOA在函数优化、图像分割等实际问题中的建模与求解方法;③学习如何将优化算法集成到Web系统中实现工程化应用;④为算法性能评估与改进提供实践参考; 阅读建议:建议读者结合代码逐行调试,深入理解算法流程中MOA与MOP的作用机制,尝试在不同测试函数上运行算法以观察性能差异,并可进一步扩展图像分割模块,引入更复杂的预处理或后处理技术以提升分割效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值