| import os |
| import yaml |
| from pathlib import Path |
| import shutil |
| from PIL import Image |
| import math |
| import numpy as np |
| from shapely.geometry import Polygon |
| import matplotlib.pyplot as plt |
| from matplotlib.patches import Polygon as PltPolygon |
| import random |
|
|
| |
| zebra_labels = "zebra_annotations/txt_annotations" |
| zebra_images = "zebra_annotations/zebra_images" |
| save_dir = "zebra_annotations/classification_data" |
| segments = 4 |
|
|
| |
| |
| def check_box_intersection(box_1, box_2, threshold=0.6): |
| |
| formatted_box_1 = [[box_1[0], box_1[1]], [box_1[2], box_1[1]], [box_1[2], box_1[3]], [box_1[0], box_1[3]]] |
|
|
| poly_1 = Polygon(formatted_box_1) |
| poly_2 = Polygon(box_2) |
| try: |
| iou = poly_1.intersection(poly_2).area / poly_1.union(poly_2).area |
| scaled_iou = iou * ((poly_1.area) / (poly_2.area)) |
| |
| |
| return (scaled_iou > threshold) |
| except ZeroDivisionError: |
| |
| print("ZERO DIVISION ERROR", poly_1.area, poly_2.area) |
| return False |
|
|
| def load_yaml_database(yaml_path): |
| config_file = None |
|
|
| with open(yaml_path, "r") as file: |
| config_file = yaml.safe_load(file) |
| |
| root = Path(config_file['path']) |
| train_dir = root / config_file['train'] |
| valid_dir = root / config_file['val'] |
| test_dir = root / config_file['test'] |
| image_size = config_file['img_size'] |
| classes = config_file['names'] |
|
|
| |
| return (train_dir, valid_dir, test_dir), (image_size, classes) |
|
|
|
|
| |
| |
| def convert_database_to_segments(image_dir, label_dir, dst_dir, overwrite=False): |
| if not os.path.exists(image_dir) or not os.path.exists(label_dir): |
| print("Error: Image or label directories do not exist") |
| return |
| |
| |
| dst_dir = Path(dst_dir) |
| try: |
| if overwrite and dst_dir.exists() and dst_dir.is_dir(): |
| shutil.rmtree(dst_dir) |
| dst_dir.mkdir(parents=True, exist_ok=True) |
| else: |
| dst_dir.mkdir(parents=True, exist_ok=False) |
| except FileExistsError: |
| |
| return |
| |
| |
| image_files = {Path(f).stem for f in os.listdir(image_dir) if f.endswith(('.jpg', '.jpeg', '.png'))} |
|
|
| file_base = 0 |
| iterations = 0 |
|
|
| for label in os.listdir(label_dir)[1:]: |
| if label.endswith('.txt'): |
| image_name = Path(label).stem |
|
|
| if image_name in image_files: |
| image_path = os.path.join(image_dir, image_name) |
| label_path = os.path.join(label_dir, label) |
| |
| file_base = breakdown(image_path, label_path, dst_dir, file_base) |
|
|
| if iterations < 10: |
| print(file_base, end=" ") |
| iterations += 1 |
| else: |
| print(file_base, end= '\r',) |
| iterations = 0 |
|
|
| def breakdown(image_path, label, dst_dir, file_base, segment=segments, targ_size = None): |
| with Image.open(image_path + ".jpg") as image: |
| img_size, take_size = image.size[0], None |
|
|
| |
| if targ_size is None: |
| take_size = math.floor(img_size / segment) |
|
|
| else: |
| segment = math.floor(img_size / targ_size) |
| take_size = img_size / segment |
|
|
| |
| label_data = [] |
| with open(label, 'r') as label_file: |
| for line in label_file.readlines(): |
| if line[0] == '0': |
| parsed = list(map(float, line.split()[1:])) |
| entity_box = np.array([(parsed[i], parsed[i + 1]) for i in range(0, len(parsed), 2)]) |
| label_data.append(entity_box * img_size) |
|
|
|
|
| img = np.array(image) |
| for i in range(segment): |
| for j in range(segment): |
| box_coordinates = [i * take_size, j * take_size, min((i + 1) * take_size, len(img[0])), min((j + 1) * take_size, len(img))] |
| new_img = img[box_coordinates[1]: box_coordinates[3], box_coordinates[0]: box_coordinates[2]] |
| |
| |
| |
| if new_img.size <= 32: |
| continue |
|
|
| new_image = Image.fromarray(new_img) |
|
|
| crosswalk_intersection = False |
| for crosswalk_box in label_data: |
| if check_box_intersection(box_coordinates, crosswalk_box): |
| |
| crosswalk_intersection = True |
| else: |
| |
| pass |
| |
| if crosswalk_intersection: |
| with open(os.path.join(dst_dir, str(file_base)) + ".txt", 'w') as new_label_file: |
| new_label_file.write("1") |
| new_image.save(str(os.path.join(dst_dir, str(file_base))) + ".png") |
|
|
| |
| else: |
| if random.randint(0, 4) >= 1: |
| with open(os.path.join(dst_dir, str(file_base)) + ".txt", 'w') as new_label_file: |
| new_label_file.write("0") |
| new_image.save(str(os.path.join(dst_dir, str(file_base))) + ".png") |
| |
| |
| file_base += 1 |
|
|
| return file_base |
|
|
| convert_database_to_segments("zebra_annotations/zebra_images", "zebra_annotations/txt_annotations", "zebra_annotations/classification_data") |
|
|