edge-sign / src /data_prep.py
gyann's picture
Deploy Edge-Sign (Direction A redesign) โ€” detection+tracking+recognition+Q&A
76ec265 verified
Raw
History Blame Contribute Delete
5.95 kB
import json
from pathlib import Path
import pandas as pd
from sklearn.model_selection import train_test_split
DATA_DIR = Path(__file__).parent.parent / "data"
LABEL_FILE = Path(__file__).parent.parent / "web" / "labels.json"
# Define our selected 12 classes mapping: original_class_id -> (new_class_idx, label_name, korean_name)
SELECTED_CLASSES = {
1: (0, "Speed Limit 30", "์†๋„์ œํ•œ 30km/h"),
2: (1, "Speed Limit 50", "์†๋„์ œํ•œ 50km/h"),
5: (2, "Speed Limit 80", "์†๋„์ œํ•œ 80km/h"),
12: (3, "Priority Road", "์šฐ์„ ๋„๋กœ"),
13: (4, "Yield", "์–‘๋ณด"),
14: (5, "Stop", "์ •์ง€"),
17: (6, "No Entry", "์ง„์ž…๊ธˆ์ง€"),
18: (7, "General Caution", "์ฃผ์˜"),
33: (8, "Turn Right Ahead", "์šฐํšŒ์ „"),
34: (9, "Turn Left Ahead", "์ขŒํšŒ์ „"),
38: (10, "Keep Right", "์šฐ์ธกํ†ตํ–‰"),
40: (11, "Roundabout Mandatory", "ํšŒ์ „๊ต์ฐจ๋กœ"),
}
def find_gtsrb_images():
# Check common paths for torchvision or manual extraction
paths_to_check = [
DATA_DIR / "gtsrb" / "GTSRB" / "Training",
DATA_DIR / "gtsrb" / "GTSRB" / "Final_Training" / "Images",
DATA_DIR / "GTSRB" / "Final_Training" / "Images",
DATA_DIR / "GTSRB_Final_Training_Images" / "GTSRB" / "Final_Training" / "Images",
DATA_DIR / "Final_Training" / "Images",
]
for path in paths_to_check:
if path.exists():
print(f"Found GTSRB training images at: {path}")
return path
# Recursive search as last resort
found = list(DATA_DIR.glob("**/Final_Training/Images"))
if found:
print(f"Found GTSRB training images via search at: {found[0]}")
return found[0]
raise FileNotFoundError(
"Could not find GTSRB training images. Ensure download script finished successfully."
)
def main():
try:
train_img_dir = find_gtsrb_images()
except FileNotFoundError as e:
print(e)
return
# Export label mapping to JSON for Web UI
labels_mapping = {}
for orig_id, (new_idx, name_en, name_ko) in SELECTED_CLASSES.items():
labels_mapping[str(new_idx)] = {
"english": name_en,
"korean": name_ko,
"original_id": orig_id,
}
# Create web folder if it doesn't exist
LABEL_FILE.parent.mkdir(parents=True, exist_ok=True)
with open(LABEL_FILE, "w", encoding="utf-8") as f:
json.dump(labels_mapping, f, indent=4, ensure_ascii=False)
print(f"Exported class mapping to {LABEL_FILE}")
# Gather data paths
data_records = []
# GTSRB contains folders like 00000, 00001, etc.
for orig_id, (new_idx, _name_en, _name_ko) in SELECTED_CLASSES.items():
class_folder = train_img_dir / f"{orig_id:05d}"
if not class_folder.exists():
print(f"Warning: Class folder {class_folder} does not exist.")
continue
# Read the CSV inside the class folder for metadata (bounding boxes, etc.)
csv_files = list(class_folder.glob("*.csv"))
if not csv_files:
# If no CSV, just grab images directly
img_files = (
list(class_folder.glob("*.ppm"))
+ list(class_folder.glob("*.jpg"))
+ list(class_folder.glob("*.png"))
)
for img_path in img_files:
data_records.append(
{
"path": str(img_path),
"class_id": new_idx,
"roi_x1": 0,
"roi_y1": 0,
"roi_x2": 0,
"roi_y2": 0,
}
)
else:
# Parse CSV metadata
# Columns: Filename;Width;Height;Roi.X1;Roi.Y1;Roi.X2;Roi.Y2;ClassId
df = pd.read_csv(csv_files[0], sep=";")
for _, row in df.iterrows():
img_path = class_folder / row["Filename"]
if img_path.exists():
data_records.append(
{
"path": str(img_path),
"class_id": new_idx,
"roi_x1": int(row["Roi.X1"]),
"roi_y1": int(row["Roi.Y1"]),
"roi_x2": int(row["Roi.X2"]),
"roi_y2": int(row["Roi.Y2"]),
}
)
df_dataset = pd.DataFrame(data_records)
print(f"Total filtered samples collected: {len(df_dataset)}")
if len(df_dataset) == 0:
print("No samples found. Please wait for the download task to complete and try again.")
return
# Print distribution
print("\nClass Distribution:")
for new_idx in sorted(df_dataset["class_id"].unique()):
count = len(df_dataset[df_dataset["class_id"] == new_idx])
label = SELECTED_CLASSES[
list(SELECTED_CLASSES.keys())[
list(SELECTED_CLASSES.values()).index(
next(v for v in SELECTED_CLASSES.values() if v[0] == new_idx)
)
]
][1]
print(f"Class {new_idx} ({label}): {count} samples")
# Split into train/validation sets (80/20 stratified split)
train_df, val_df = train_test_split(
df_dataset, test_size=0.2, random_state=42, stratify=df_dataset["class_id"]
)
# Save split info to data directory
data_meta_dir = DATA_DIR / "processed"
data_meta_dir.mkdir(parents=True, exist_ok=True)
train_df.to_csv(data_meta_dir / "train_split.csv", index=False)
val_df.to_csv(data_meta_dir / "val_split.csv", index=False)
print(f"\nSaved splits to {data_meta_dir} (Train: {len(train_df)}, Val: {len(val_df)})")
if __name__ == "__main__":
main()