Browse Source
- Redesigned expanded content with organized sections: * Pokemon Info (Name, Dex #, Gender, Form) * Combat Stats (CP, HP, Level, IV%) * Individual Stats (ATK/DEF/STA if available) * Special Properties (Shiny/Alpha checkboxes) * Technical Info (Processing time, Detection count, Timestamp) - Added multi-column layout helper methods for better space utilization - Implemented checkbox indicators using Unicode symbols (☐/☑) - Enhanced visual hierarchy with blue section headers - Improved data organization and readability 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>feature/pgh-1-results-display-history
4 changed files with 8760 additions and 38 deletions
@ -0,0 +1,3 @@ |
|||
{ |
|||
"cmake.ignoreCMakeListsMissing": true |
|||
} |
|||
@ -0,0 +1,112 @@ |
|||
from ultralytics import YOLO |
|||
import os |
|||
import shutil |
|||
from PIL import Image |
|||
|
|||
# --- Configuration --- |
|||
# Load your trained model |
|||
model = YOLO('./best.pt') # Adjust 'train8' if needed |
|||
|
|||
# Directory with new, unannotated images (your input) |
|||
unlabeled_image_dir = './untrained_images' |
|||
|
|||
# Base directory for YOLOv8's output. YOLOv8 will create 'predictX' folders inside this. |
|||
# Example: /TempReview/predict, /TempReview/predict1, etc. |
|||
yolov8_project_dir = './.yolo_yemp' # This is where your 'predictX' folders are generated |
|||
|
|||
# The final, flat directory where images and labels will be moved for LabelImg |
|||
flat_output_dir = './for_labelimg_review' |
|||
|
|||
# --- Ensure input directory exists --- |
|||
os.makedirs(unlabeled_image_dir, exist_ok=True) # Make sure this exists if you haven't uploaded images yet |
|||
|
|||
# Get all image files from the unlabeled directory |
|||
image_files = [f for f in os.listdir(unlabeled_image_dir) if f.lower().endswith(('.jpg', '.jpeg', '.png'))] |
|||
|
|||
if not image_files: |
|||
print(f"No image files found in '{unlabeled_image_dir}'. Please upload images there.") |
|||
else: |
|||
print(f"--- Step 1: Running YOLOv8 Inference on new images ---") |
|||
print(f"Running inference on {len(image_files)} new images...") |
|||
|
|||
# Run inference on all images in the directory |
|||
# YOLOv8 will automatically create a new 'predictX' folder (e.g., predict, predict1, predict2) |
|||
# inside the yolov8_project_dir for each unique run. |
|||
results_list = model(unlabeled_image_dir, |
|||
#save=True, # Save images with plotted boxes |
|||
save_txt=True, # Save the YOLO .txt label files |
|||
conf=0.6, # Confidence threshold for predictions (adjust as needed) |
|||
project=yolov8_project_dir # This is your 'TempReview' |
|||
) |
|||
|
|||
# Find the most recently created 'predictX' folder |
|||
# This assumes the latest run will be the one with the highest number |
|||
# or the one most recently modified. |
|||
predict_dirs = [d for d in os.listdir(yolov8_project_dir) if d.startswith('predict') and os.path.isdir(os.path.join(yolov8_project_dir, d))] |
|||
|
|||
if not predict_dirs: |
|||
print(f"Error: No 'predictX' folders found in '{yolov8_project_dir}'. Inference might have failed.") |
|||
else: |
|||
# Sort by creation time (most recent first) or by name (highest number) |
|||
# Sorting by name (predict, predict1, predict10, predict2...) doesn't always work numerically. |
|||
# Sorting by modification time is safer. |
|||
latest_predict_dir_name = max(predict_dirs, key=lambda d: os.path.getmtime(os.path.join(yolov8_project_dir, d))) |
|||
|
|||
yolov8_run_path = os.path.join(yolov8_project_dir, latest_predict_dir_name) |
|||
yolov8_images_path = yolov8_run_path |
|||
yolov8_labels_path = os.path.join(yolov8_run_path, 'labels') |
|||
|
|||
print(f"YOLOv8 results saved to: '{yolov8_run_path}'") |
|||
|
|||
print(f"\n--- Step 2: Flattening output structure for LabelImg ---") |
|||
os.makedirs(flat_output_dir, exist_ok=True) |
|||
|
|||
# Move images |
|||
if os.path.exists(yolov8_images_path): |
|||
for img_file in os.listdir(yolov8_images_path): |
|||
# Only move files that are original image files (e.g., .jpg, .png) |
|||
if img_file.lower().endswith(('.jpg', '.jpeg', '.png')): |
|||
shutil.move(os.path.join(yolov8_images_path, img_file), |
|||
os.path.join(flat_output_dir, img_file)) |
|||
print(f"Moved images to '{flat_output_dir}'") |
|||
else: |
|||
print(f"Warning: No images found at '{yolov8_images_path}'.") |
|||
|
|||
# Process and move labels |
|||
if os.path.exists(yolov8_labels_path): |
|||
for label_file in os.listdir(yolov8_labels_path): |
|||
if label_file.lower().endswith('.txt'): |
|||
label_path_src = os.path.join(yolov8_labels_path, label_file) |
|||
|
|||
# Read lines, parse class_id, and sort |
|||
with open(label_path_src, 'r') as f: |
|||
lines = f.readlines() |
|||
|
|||
# Sort lines based on the first element (class_id) as an integer |
|||
# Handle potential errors if a line is malformed, though unlikely from YOLO. |
|||
try: |
|||
sorted_lines = sorted(lines, key=lambda line: int(line.strip().split(' ')[0])) |
|||
except ValueError as e: |
|||
print(f"Warning: Could not sort lines in {label_file} due to format error: {e}. Skipping sort for this file.") |
|||
sorted_lines = lines # Fallback to original order |
|||
|
|||
# Write sorted lines to the destination file |
|||
label_path_dest = os.path.join(flat_output_dir, label_file) |
|||
with open(label_path_dest, 'w') as f: |
|||
f.writelines(sorted_lines) |
|||
|
|||
# Remove the original label file after processing (optional, but keeps source clean) |
|||
os.remove(label_path_src) |
|||
print(f"Moved and sorted labels to '{flat_output_dir}'") |
|||
else: |
|||
print(f"Warning: No labels found at '{yolov8_labels_path}'.") |
|||
|
|||
# Clean up the intermediate YOLOv8 output directory (optional, but recommended for Colab space) |
|||
# Be careful with shutil.rmtree - it deletes recursively! |
|||
if os.path.exists(yolov8_run_path): |
|||
print(f"Cleaning up temporary YOLOv8 output: '{yolov8_run_path}'") |
|||
shutil.rmtree(yolov8_run_path) |
|||
|
|||
print(f"\n--- Process Complete! ---") |
|||
print(f"Your images and predicted .txt labels are now in a flat structure in: '{flat_output_dir}'") |
|||
print("You can now open LabelImg and point it to this directory to begin review and correction.") |
|||
File diff suppressed because one or more lines are too long
Loading…
Reference in new issue