centeros域名解析失败

本文记录了一次使用wget命令从阿里云镜像站点下载CentOS-Base.repo文件时遇到的网络问题。由于无法解析mirrors.aliyun.com的域名,导致wget命令无法完成文件下载。这可能是由于DNS配置错误或网络连接问题引起的。

[root@localhost ~]# sudo wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-6.repo
--2019-03-09 12:38:26--  http://mirrors.aliyun.com/repo/Centos-6.repo
正在解析主机 mirrors.aliyun.com... 失败:域名解析暂时失败。
wget: 无法解析主机地址 “mirrors.aliyun.com”

 

这个是没有网络导致

# 确保安装所有依赖:pip install flask flask-cors ultralytics opencv-python numpy from flask import Flask, request, jsonify, send_from_directory from flask_cors import CORS from ultralytics import YOLO import cv2 import numpy as np import base64 import os import time app = Flask(__name__) # 允许所有域名跨域请求(开发环境) CORS(app) # 配置路径 - 请根据实际情况修改 MODEL_PATH = 'D:\\AI实训\\ultralytics-main\\my_test\\runs\\detect\\train2\\weights\\best.pt' DATASET_PATH = 'D:\\AI实训\\ultralytics-main\\mydatasets\\vitiligo\\images' os.makedirs(DATASET_PATH, exist_ok=True) # 加载模型 try: model = YOLO(MODEL_PATH) print("✅ 白癜风检测模型加载成功") except Exception as e: print(f"❌ 模型加载失败: {e}") model = None @app.route('/dataset/list', methods=['GET']) def get_dataset_list(): try: if not os.path.exists(DATASET_PATH): return jsonify({"status": "error", "message": f"数据集目录不存在: {DATASET_PATH}"}), 404 image_extensions = ['.jpg', '.jpeg', '.png', '.bmp'] image_files = [ f for f in os.listdir(DATASET_PATH) if os.path.isfile(os.path.join(DATASET_PATH, f)) and os.path.splitext(f)[1].lower() in image_extensions ] return jsonify({ "status": "success", "count": len(image_files), "images": image_files }) except Exception as e: print(f"获取数据集列表出错: {e}") return jsonify({"status": "error", "message": str(e)}), 500 @app.route('/dataset/image/<filename>', methods=['GET']) def get_dataset_image(filename): try: file_path = os.path.join(DATASET_PATH, filename) if not os.path.exists(file_path) or not os.path.isfile(file_path): return jsonify({"status": "error", "message": f"图片不存在: {filename}"}), 404 return send_from_directory(DATASET_PATH, filename) except Exception as e: print(f"获取图片出错: {e}") return jsonify({"status": "error", "message": str(e)}), 500 @app.route('/detect', methods=['POST']) def detect_image(): start_time = time.time() print("🔍 接收到白癜风检测请求") try: if not model: return jsonify({"status": "error", "message": f"模型未加载,请检查路径: {MODEL_PATH}"}), 500 if 'image' not in request.files: return jsonify({"status": "error", "message": "未上传图片"}), 400 file = request.files['image'] file_bytes = np.asarray(bytearray(file.read()), dtype=np.uint8) img = cv2.imdecode(file_bytes, cv2.IMREAD_COLOR) if img is None: return jsonify({"status": "error", "message": "无法解析图片,请确保上传的是有效图片文件"}), 400 print(f"✅ 成功加载图片,尺寸: {img.shape}") # 执行检测 results = model(img) annotated_frame = results[0].plot() # 绘制检测框 print(f"✅ 检测完成,识别到 {len(results[0].boxes)} 个目标区域") # 处理检测结果 _, encoded_img = cv2.imencode('.jpg', annotated_frame) base64_img = base64.b64encode(encoded_img).decode('utf-8') detections = [] for box in results[0].boxes: cls_id = int(box.cls[0]) conf = float(box.conf[0]) bbox = [int(coord) for coord in box.xyxy[0].tolist()] area = (bbox[2] - bbox[0]) * (bbox[3] - bbox[1]) detections.append({ "category": model.names[cls_id], "confidence": f"{conf:.2f}", "confidence_value": round(conf, 4), "bounding_box": bbox, "area_pixels": area, "position": f"({bbox[0]},{bbox[1]})-({bbox[2]},{bbox[3]})" }) detection_time = round(time.time() - start_time, 2) print(f"⏱️ 检测耗时: {detection_time}秒") return jsonify({ "status": "success", "annotated_image": base64_img, "detections": detections, "detection_count": len(detections), "detection_time": f"{detection_time}秒", "message": "白癜风区域检测完成" }) except Exception as e: end_time = time.time() print(f"❌ 检测过程出错: {e},耗时: {end_time - start_time:.2f}秒") return jsonify({"status": "error", "message": str(e)}), 500 @app.route('/health', methods=['GET']) def health_check(): return jsonify({ "status": "healthy", "model_loaded": model is not None, "dataset_available": os.path.exists(DATASET_PATH) }) if __name__ == '__main__': print("=== 白癜风医疗目标检测服务 ===") print("已注册的路由:") for rule in app.url_map.iter_rules(): print(f"URL: {rule.rule}, 方法: {rule.methods}") print(f"数据集路径: {DATASET_PATH}") print(f"模型路径: {MODEL_PATH}") app.run(host='0.0.0.0', port=5000, debug=True)这是我图片分析的后端代码<template> <div class="image-detection-container"> <!-- 图片显示区域 --> <div class="image-section"> <!-- 原图 --> <div class="image-box"> <h3>原图</h3> <div class="image-display"> <img :src="originalImageUrl" alt="Original Image" v-if="originalImageUrl" :style="{ transform: `scale(${zoomLevel})` }" /> <div class="placeholder" v-else>等待加载图片...</div> </div> </div> <!-- 结果图 --> <div class="image-box"> <h3>结果图</h3> <div class="image-display"> <img :src="resultImageUrl" alt="Result Image" v-if="resultImageUrl" :style="{ transform: `scale(${zoomLevel})` }" /> <div class="placeholder" v-else-if="isDetecting">检测中...</div> <div class="placeholder" v-else>未检测</div> </div> </div> <!-- 结果数据 --> <div class="result-data-box"> <h3>结果数据</h3> <div class="result-data"> <div v-if="detectionResults.length"> <div v-for="(result, index) in detectionResults" :key="index" class="result-item"> <p><strong>分类:</strong> {{ result.category }}</p> <p><strong>置信度:</strong> {{ (result.confidence * 100).toFixed(1) }}%</p> <p><strong>矩形框位置:</strong> {{ formatBoundingBox(result.boundingBox) }}</p> </div> </div> <div v-else-if="isDetecting"> <p>正在检测,请稍候...</p> </div> <div v-else> <p>无检测结果</p> </div> </div> </div> </div> <!-- 操作按钮区域 --> <div class="button-section"> <button class="action-button" @click="selectImage">选择图片</button> <button class="action-button" @click="detectImage" :disabled="!originalImageUrl || isDetecting">识别结果</button> <button class="action-button" @click="prevImage" :disabled="currentImageIndex <= 0">上一张</button> <button class="action-button" @click="nextImage" :disabled="currentImageIndex >= imageList.length - 1">下一张</button> <button class="action-button" @click="zoomIn" :disabled="zoomLevel >= maxZoomLevel">放大</button> <button class="action-button" @click="zoomOut" :disabled="zoomLevel <= minZoomLevel">缩小</button> <button class="action-button" @click="resetImage">重置</button> </div> <!-- 文件选择器 --> <input type="file" ref="fileInput" accept="image/*" style="display: none;" @change="handleFileSelect" /> </div> </template> <script> import axios from 'axios'; export default { name: 'ImageDetectionApp', data() { return { // 图片相关数据 originalImageUrl: '', resultImageUrl: '', imageList: [], currentImageIndex: -1, selectedFile: null, // 检测结果数据 detectionResults: [], isDetecting: false, // 缩放相关数据 zoomLevel: 1, minZoomLevel: 0.5, maxZoomLevel: 3, }; }, methods: { // 选择图片 selectImage() { this.$refs.fileInput.click(); }, // 处理文件选择 handleFileSelect(event) { const file = event.target.files[0]; if (!file) return; if (!file.type.match('image.*')) { this.$message.error('请选择图片文件'); return; } this.selectedFile = file; const reader = new FileReader(); reader.onload = (e) => { this.originalImageUrl = e.target.result; // 维护图片列表 if (!this.imageList.includes(this.originalImageUrl)) { this.imageList.push(this.originalImageUrl); this.currentImageIndex = this.imageList.length - 1; } // 重置检测结果 this.resultImageUrl = ''; this.detectionResults = []; }; reader.onerror = () => { console.error('文件读取失败'); this.$message.error('图片加载失败,请重新选择'); }; reader.readAsDataURL(file); // 清空input值,允许重复选择同一文件 event.target.value = ''; }, // 检测图片(删除所有.response.data中的.data) async detectImage() { if (!this.originalImageUrl || this.isDetecting) return; this.isDetecting = true; this.resultImageUrl = ''; this.detectionResults = []; try { const formData = new FormData(); if (this.selectedFile) { // 本地上传的图片 formData.append('image', this.selectedFile); } else { // 从图片列表加载的图片(增加错误捕获) try { const fetchRes = await fetch(this.originalImageUrl); if (!fetchRes.ok) throw new Error(`图片加载失败: ${fetchRes.statusText}`); const blob = await fetchRes.blob(); formData.append('image', blob, 'detect-image.jpg'); } catch (fetchError) { console.error('图片转blob失败:', fetchError); this.$message.error('无法处理图片,请重新选择'); this.isDetecting = false; return; } } // 发送请求 const response = await axios.post(`/detect`, formData); // 验证响应结构 if (!response) { throw new Error('后端返回格式异常(无有效数据)'); } console.log('后端响应完整数据:', response); if (response.status === 'success') { // 处理检测结果图片 if (response.annotated_image) { const base64Str = response.annotated_image.startsWith('data:image') ? response.annotated_image : `data:image/jpeg;base64,${response.annotated_image}`; this.resultImageUrl = base64Str; } else { console.error('后端未返回带检测框的图片'); this.$message.error('未获取到检测结果图片'); } // 处理检测结果列表 if (response.detections && response.detections.length > 0) { this.detectionResults = response.detections.map(item => ({ category: item.category || '未知类别', confidence: item.confidence_value || parseFloat(item.confidence) || 0, boundingBox: item.bounding_box || [] })); this.$message.success(`成功检测到 ${this.detectionResults.length} 个目标区域`); } else { this.detectionResults = []; this.$message.info('未检测到目标区域'); } } else { this.$message.error(`检测失败: ${response.message || '未知错误'}`); } } catch (error) { console.error('检测出错详情:', error); if (error.response) { // 服务器返回错误状态码 this.$message.error(`服务器错误 ${error.response.status}: ${error.response.data?.message || '未知错误'}`); } else if (error.request) { // 请求已发送但无响应 this.$message.error('无法连接到服务器,请检查后端是否运行'); } else { // 其他错误(如图片加载失败) this.$message.error(`操作失败: ${error.message}`); } } finally { this.isDetecting = false; } }, // 上一张图片 prevImage() { if (this.imageList.length === 0) { this.$message.info('暂无图片列表'); return; } if (this.currentImageIndex > 0) { this.currentImageIndex--; this.originalImageUrl = this.imageList[this.currentImageIndex]; this.resultImageUrl = ''; this.detectionResults = []; this.selectedFile = null; } else { this.$message.info('已经是第一张图片'); } }, // 下一张图片 nextImage() { if (this.imageList.length === 0) { this.$message.info('暂无图片列表'); return; } if (this.currentImageIndex < this.imageList.length - 1) { this.currentImageIndex++; this.originalImageUrl = this.imageList[this.currentImageIndex]; this.resultImageUrl = ''; this.detectionResults = []; this.selectedFile = null; } else { this.$message.info('已经是最后一张图片'); } }, // 放大图片 zoomIn() { if (this.zoomLevel < this.maxZoomLevel) { this.zoomLevel = parseFloat((this.zoomLevel + 0.2).toFixed(1)); } }, // 缩小图片 zoomOut() { if (this.zoomLevel > this.minZoomLevel) { this.zoomLevel = parseFloat((this.zoomLevel - 0.2).toFixed(1)); } }, // 重置图片和缩放 resetImage() { this.zoomLevel = 1; this.resultImageUrl = ''; this.detectionResults = []; }, // 格式化边界框显示 formatBoundingBox(box) { if (Array.isArray(box) && box.length === 4) { return `x1: ${box[0]}, y1: ${box[1]}, x2: ${box[2]}, y2: ${box[3]}`; } return box || '未知'; } }, mounted() { // 初始化时检查本地存储的图片列表 const savedImages = localStorage.getItem('detectionImages'); if (savedImages) { try { this.imageList = JSON.parse(savedImages); this.currentImageIndex = this.imageList.length - 1; if (this.imageList.length > 0) { this.originalImageUrl = this.imageList[this.currentImageIndex]; } } catch (e) { console.error('加载历史图片失败:', e); this.imageList = []; } } }, watch: { // 保存图片列表到本地存储 imageList(newVal) { localStorage.setItem('detectionImages', JSON.stringify(newVal)); } } }; </script> <style scoped> .image-detection-container { max-width: 1200px; margin: 0 auto; padding: 20px; font-family: Arial, sans-serif; } .image-section { display: flex; justify-content: space-between; margin-bottom: 20px; flex-wrap: wrap; } .image-box { flex: 1; min-width: 300px; margin: 0 10px 20px; text-align: center; } .image-display { border: 1px solid #ccc; padding: 10px; min-height: 300px; display: flex; justify-content: center; align-items: center; overflow: auto; background-color: #f9f9f9; } .image-display img { max-width: 100%; max-height: 400px; transition: transform 0.3s ease; } .placeholder { color: #666; font-size: 14px; } .result-data-box { flex: 0.5; min-width: 300px; margin: 0 10px 20px; text-align: left; } .result-data { border: 1px solid #ccc; padding: 10px; min-height: 300px; background-color: #fff; } .result-item { padding: 10px; border-bottom: 1px dashed #eee; margin-bottom: 10px; } .result-item:last-child { border-bottom: none; margin-bottom: 0; } .button-section { display: flex; justify-content: center; gap: 10px; flex-wrap: wrap; margin-top: 10px; } .action-button { padding: 10px 20px; background-color: #007bff; color: white; border: none; cursor: pointer; border-radius: 4px; transition: background-color 0.3s; font-size: 14px; } .action-button:hover { background-color: #0056b3; } .action-button:disabled { background-color: #ccc; cursor: not-allowed; opacity: 0.7; } @media (max-width: 768px) { .image-section { flex-direction: column; } } </style>这是我图片检测的前端代码<template> <div class="data-analysis-container"> <h2>数据分析</h2> <table class="data-table"> <thead> <tr> <th>编号</th> <th>类别</th> <th>置信度</th> <th>坐标</th> <th>图片</th> <th>时长</th> <th>来源</th> </tr> </thead> <tbody> <!-- 表格内容将通过数据绑定动态生成 --> </tbody> </table> </div> </template> <script> export default { name: 'DataAnalysis', data() { return { // 表格数据将在这里定义 } } } </script> <style scoped> .data-analysis-container { max-width: 1200px; margin: 0 auto; padding: 20px; } h2 { text-align: center; margin-bottom: 20px; } .data-table { width: 100%; border-collapse: collapse; } .data-table th, .data-table td { border: 1px solid #000; padding: 8px; text-align: center; } .data-table th { background-color: #f2f2f2; } </style>这是我数据分析的ui界面前端代码,现在我需要你帮我把这三个结合起来,在不改变我ui界面的前提下,使我在使用图片检测的时候,会有对应的数据返回到我数据分析的ui界面上,给我完整的前后端代码
07-18
### 图片检测与数据分析界面的整合方案 为了实现将基于YOLO的图片检测功能与数据分析界面集成,并使检测结果自动显示在数据分析页面,需要从前端、后端和数据流三个方面进行系统性设计。 #### 前端开发 前端采用Vue框架构建UI组件,其中包含两个主要部分:图像上传/检测区域和数据分析展示区域。用户上传图像后,通过HTTP请求将图像发送至Flask后端[^2]。以下是一个简化的Vue组件示例代码: ```vue <template> <div> <input type="file" @change="uploadImage" /> <button @click="submitImage">提交</button> <img :src="imagePreview" v-if="imagePreview" /> <div v-if="detectionResult"> <h3>检测结果:</h3> <p>{{ detectionResult }}</p> </div> <div v-if="analysisData"> <h3>数据分析:</h3> <p>{{ analysisData }}</p> </div> </div> </template> <script> export default { data() { return { imageFile: null, imagePreview: null, detectionResult: null, analysisData: null }; }, methods: { uploadImage(event) { this.imageFile = event.target.files[0]; this.imagePreview = URL.createObjectURL(this.imageFile); }, async submitImage() { const formData = new FormData(); formData.append('image', this.imageFile); // 发送图像到Flask后端 const response = await fetch('/api/detect', { method: 'POST', body: formData }); const result = await response.json(); this.detectionResult = result; // 获取分析数据 const analysisResponse = await fetch(`/api/analyze/${result.id}`); const analysisResult = await analysisResponse.json(); this.analysisData = analysisResult; } } }; </script> ``` #### 后端开发 后端由Flask API组成,负责接收图像上传请求,调用YOLO模型进行目标检测,并将检测结果存储到MySQL数据库中。此外,还需提供一个API用于获取特定ID对应的分析数据[^1]。 ```python from flask import Flask, request, jsonify import os from werkzeug.utils import secure_filename from yolov11 import YOLOv11Model # 假设已经有一个封装好的YOLOv11模型类 app = Flask(__name__) UPLOAD_FOLDER = './uploads' ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg'} # 初始化YOLO模型 model = YOLOv11Model() def allowed_file(filename): return '.' in filename and \ filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS @app.route('/api/detect', methods=['POST']) def detect(): if 'image' not in request.files: return jsonify({'error': 'No file part'}), 400 file = request.files['image'] if file.filename == '': return jsonify({'error': 'No selected file'}), 400 if file and allowed_file(file.filename): filename = secure_filename(file.filename) filepath = os.path.join(UPLOAD_FOLDER, filename) file.save(filepath) # 使用YOLO模型进行检测 result = model.detect(filepath) # 存储检测结果到数据库 result_id = save_to_database(result) return jsonify({'id': result_id, 'result': result}), 200 @app.route('/api/analyze/<string:result_id>', methods=['GET']) def analyze(result_id): # 根据result_id从数据库获取分析数据 analysis_data = get_analysis_data(result_id) return jsonify(analysis_data), 200 if __name__ == '__main__': app.run(debug=True) ``` #### 数据库设计 使用MySQL作为数据库来存储检测结果及其对应的分析数据。可以创建一张表来保存每次检测的结果信息,包括唯一标识符、原始图像路径、检测详情等字段。 ```sql CREATE TABLE detection_results ( id VARCHAR(255) PRIMARY KEY, image_path TEXT NOT NULL, detection_details JSON, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); ``` #### 视频处理与扩展 虽然当前需求是针对图片检测,但考虑到未来可能需要支持视频流检测,可以在系统架构中预留对FFmpeg的支持,以便于后续扩展[^2]。 #### 安全性和性能优化 确保所有文件上传操作都经过严格的安全检查,防止恶意文件注入。同时,对于大规模并发访问场景,考虑引入缓存机制(如Redis)来提高响应速度,减少数据库查询压力。 #### 用户体验优化 为了提升用户体验,可以在前端添加加载动画或进度条提示用户等待检测完成。另外,在检测结果返回后,可以通过图表库(如ECharts)将分析数据以可视化形式呈现给用户。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值