从文件夹中随机读取一张图片(文件)并显示(打印)

本文介绍了一个Python脚本,用于从指定文件夹中随机读取一张图片并显示。通过修改文件路径,可以轻松应用于不同场景。代码利用OpenCV库进行图片读取和展示。

记录一下常使用的代码段.这个是用于从文件夹中随机读取一张图片或者一个文件.
使用时只需要更改get_picture_dir("/home/wsb/桌面/test") 中的地址.读取文件时将图片读取和显示的代码注释掉.

import cv2
import os
from random import randint
def get_picture_dir(file_dir):
    filelist = os.listdir(file_dir) #获取文件路径
    total_num=len(filelist)
    idx = randint(0,total_num)
    image_path=filelist[idx]
    picture_path = os.path.join(os.path.abspath(file_dir), image_path)
    img=cv2.imread(picture_path)
    cv2.imshow("img",img)
    cv2.waitKey(0)
get_picture_dir("/home/wsb/桌面/test")   

import cv2 import os import time import shutil import threading import queue from pathlib import Path from collections import defaultdict from ultralytics import YOLO 配置参数 class Config: 模型路径 MODEL_PATH = r"F:\yolov8\ultralytics-main\best.pt" # 初始模型路径 NEW_MODEL_DIR = r"F:\yolov8\ultralytics-main\retrained_models" # 新模型存储目录 图片路径 SOURCE_DIR = r"F:\yolov8\ultralytics-main\datasets\bvn\images\train" # 图片输入目录 OUTPUT_DIR = r"F:\yov8\ultralytics-main\datasets\bvn\images\done" # 检测结果输出路径 NO_DETECTION_DIR = os.path.join(OUTPUT_DIR, “no_detection”) # 未检测到目标的文件夹 #训练参数 TRAINING_THRESHOLD = 500 # 收集一定新图片后开始训练 EPOCHS = 50 # 训练轮数 IMGSZ = 640 # 训练图像尺寸 BATCH = 8 # 训练批次大小 # 检测参数 CONFIDENCE_THRESHOLD = 0.5 # 检测置信度阈值 POLL_INTERVAL = 1 # 文件夹轮询间隔() STABLE_TIME = 0.5 # 文件稳定时间() IMAGE_EXTS = {‘.jpg’, ‘.jpeg’, ‘.png’, ‘.bmp’} # 支持的图片格式 确保目录存在 Path(Config.OUTPUT_DIR).mkdir(parents=True, exist_ok=True) Path(Config.NO_DETECTION_DIR).mkdir(parents=True, exist_ok=True) Path(Config.NEW_MODEL_DIR).mkdir(parents=True, exist_ok=True) 全局变量 processed_files = set() # 已处理文件记录 training_queue = queue.Queue() # 训练任务队列 new_images_count = 0 # 新图片计数器 model_lock = threading.Lock() # 模型更新锁 加载初始模型 model = YOLO(Config.MODEL_PATH) def process_image(image_path): “”“处理单张图片保存结果,返回检测结果统计”“” 读取原始图片 original_img = cv2.imread(image_path) if original_img is None: print(f"无法读取图片: {image_path}") return {} 执行目标检测 results = model(image_path, conf=Config.CONFIDENCE_THRESHOLD) # 检测结果计数器 detection_count = 0 class_files = defaultdict(list) # 处理检测结果 for result in results: # 统计检测到的目标数量 detection_count += len(result.boxes) if result.boxes is not None else 0 # 如果有检测结果 if result.boxes is not None and len(result.boxes) > 0: # 绘制检测结果 plotted_img = result.plot() # 获取检测到的类别 class_indices = result.boxes.cls.int().tolist() # 为每个检测到的类别保存结果 for cls_idx in set(class_indices): # 使用set去重 cls_name = model.names[cls_idx] cls_dir = Path(Config.OUTPUT_DIR) / cls_name cls_dir.mkdir(parents=True, exist_ok=True) # 保存路径 save_path = str(cls_dir / f"{Path(image_path).stem}_result{Path(image_path).suffix}“) cv2.imwrite(save_path, plotted_img) class_files[cls_name].append(save_path) # 如果没有检测到任何目标 if detection_count == 0: # 在图片上添加"未检测到目标"文本 annotated_img = original_img.copy() text = “No Detection” font = cv2.FONT_HERSHEY_SIMPLEX font_scale = 1 thickness = 2 color = (0, 0, 255) # 红色文本 # 获取文本尺寸居中 text_size = cv2.getTextSize(text, font, font_scale, thickness)[0] text_x = (annotated_img.shape[1] - text_size[0]) // 2 text_y = (annotated_img.shape[0] + text_size[1]) // 2 # 添加文本 cv2.putText(annotated_img, text, (text_x, text_y), font, font_scale, color, thickness) # 保存到未检测文件夹 save_path = str(Path(Config.NO_DETECTION_DIR) / f”{Path(image_path).name}") cv2.imwrite(save_path, annotated_img) class_files[“no_detection”] = [save_path] # 将处理后的图片添加到训练队列 training_queue.put(image_path) return class_files def auto_retrain_model(): “”“自动训练新模型替换旧模型”“” global model, new_images_count 创建数据集目录 dataset_dir = os.path.join(Config.NEW_MODEL_DIR, “auto_dataset”) images_dir = os.path.join(dataset_dir, “images”, “train”) labels_dir = os.path.join(dataset_dir, “labels”, “train”) os.makedirs(images_dir, exist_ok=True) os.makedirs(labels_dir, exist_ok=True) print(f"\n 开始准备训练数据,共收集到 {new_images_count} 张新图片") # 处理训练队列中的所有图片 processed_count = 0 while not training_queue.empty(): try: img_path = training_queue.get_nowait() base_name = Path(img_path).name # 复制图片到训练集 shutil.copy(img_path, os.path.join(images_dir, base_name)) # 生成对应的标签文件路径 label_path = os.path.join(labels_dir, f"{Path(img_path).stem}.txt") # 如果标签文件不存在,创建一个文件 if not os.path.exists(label_path): open(label_path, ‘w’).close() processed_count += 1 if processed_count % 10 == 0: print(f" 已处理 {processed_count}/{new_images_count} 张图片") except queue.Empty: break # 创建数据集配置文件 dataset_yaml_path = os.path.join(dataset_dir, “dataset.yaml”) with open(dataset_yaml_path, ‘w’) as f: f.write(f"path: {dataset_dir}\n") f.write(“train: images/train\n”) f.write(“val: images/train # 使用相同数据验证\n”) f.write(“names:\n”) for idx, name in model.names.items(): f.write(f" {idx}: {name}\n") print(f" 训练数据集准备完成: {dataset_dir}“) print(f” 开始训练新模型 (epochs={Config.EPOCHS}, batch={Config.BATCH})) # 训练新模型 with model_lock: # 锁定模型以防止在训练时被使用 new_model = YOLO(“yolov8n.yaml”) # 使用YOLOv8n架构 results = new_model.train( data=dataset_yaml_path, epochs=Config.EPOCHS, imgsz=Config.IMGSZ, batch=Config.BATCH, project=Config.NEW_MODEL_DIR, name=“auto_retrain”, exist_ok=True ) # 定位最佳模型 best_model_path = os.path.join(Config.NEW_MODEL_DIR, “auto_retrain”, “weights”, “best.pt”) if os.path.exists(best_model_path): # 备份旧模型 timestamp = time.strftime(”%Y%m%d-%H%M%S") backup_path = f"{Config.MODEL_PATH}.bak.{timestamp}" shutil.copy(Config.MODEL_PATH, backup_path) # 替换模型 shutil.copy(best_model_path, Config.MODEL_PATH) # 重新加载新模型 with model_lock: model = YOLO(Config.MODEL_PATH) print(f" 模型已成功替换: {Config.MODEL_PATH}“) print(f” 旧模型已备份至: {backup_path}“) return True else: print(” 训练失败,未找到最佳模型!!!") return False def monitor_folder(): “”“监控文件夹处理新图片”“” global new_images_count print(f"开始监控文件夹: {Config.SOURCE_DIR}“) print(f"置信度阈值: {Config.CONFIDENCE_THRESHOLD}”) print(f"未检测图片将保存到: {Config.NO_DETECTION_DIR}“) print(f"每收集 {Config.TRAINING_THRESHOLD} 张新图片将自动训练新模型”) try: while True: # 检查是否需要启动训练 if new_images_count >= Config.TRAINING_THRESHOLD: print(“\n⚠️ 达到训练阈值,启动自动训练流程…”) if auto_retrain_model(): # 重置计数器 new_images_count = 0 # 清空训练队列 while not training_queue.empty(): training_queue.get_nowait() # 获取文件夹中的所有文件 for entry in Path(Config.SOURCE_DIR).iterdir(): if not entry.is_file(): continue file_path = str(entry.resolve()) file_ext = entry.suffix.lower() # 检查是否为支持的图片文件 if file_ext not in Config.IMAGE_EXTS: continue # 检查是否已处理过 if file_path in processed_files: continue # 检查文件是否稳定 file_age = time.time() - entry.stat().st_mtime if file_age < Config.STABLE_TIME: continue # 处理新图片 print(f"处理新图片: {entry.name}“) result_files = process_image(file_path) # 记录已处理文件 processed_files.add(file_path) new_images_count += 1 # 打印处理结果 if “no_detection” in result_files: print(f” └─ 未检测到目标: {result_files[‘no_detection’][0]}“) else: for cls_name, paths in result_files.items(): print(f” ├─ 检测到 {cls_name}: {len(paths)}张图片") # 显示当前新图片计数 print(f" 当前新图片数: {new_images_count}/{Config.TRAINING_THRESHOLD}“) time.sleep(Config.POLL_INTERVAL) except KeyboardInterrupt: print(”\n监控已停止") # 在退出前检查是否有待处理的训练任务 if new_images_count > 0: print(f"⚠ 检测到 {new_images_count} 张未处理的图片,是否要训练新模型? (y/n)") if input().lower() == ‘y’: auto_retrain_model() if name == “main”: monitor_folder() 在写一个日志功能,这个日志是记录检测图片的信息。日志也还是按图片检测后分类在不同的文本中。日志内容就是图片名称 ,举个例子:Err2025-06-28 040014922L14397382_0_result,Err2025-06-28是日期,040014922在L前面是时间,L后面的数字是长度14397382长度是mm,写入日志时需要是按m记录,文本中最后还要记录日志信息个数
07-16
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值