File size: 5,951 Bytes
76ec265 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 | 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()
|