| import os |
| from shapely.geometry import Polygon |
|
|
| class DamageCalculator: |
| def __init__(self): |
| self.cost_ranges = { |
| "Scratch": { |
| "Minor": (1000, 3000), |
| "Moderate": (3000, 5000), |
| "Severe": (5000, 10000) |
| }, |
| "Dent": { |
| "Minor": (2000, 4000), |
| "Moderate": (4000, 10000), |
| "Severe": (10000, 15000) |
| }, |
| "Paint chip": { |
| "Minor": (1000, 2000), |
| "Moderate": (2000, 4000), |
| "Severe": (4000, 10000) |
| }, |
| "Broken part": (1000, 7000) |
| } |
|
|
| def parse_coordinates(self, file_path): |
| polygons = [] |
| class_names = [] |
| with open(file_path, 'r') as file: |
| for line in file: |
| parts = line.strip().split() |
| class_name = [] |
| coordinates = [] |
| for part in parts: |
| try: |
| coordinates.append(float(part)) |
| except ValueError: |
| class_name.append(part) |
| if class_name and coordinates: |
| class_name = " ".join(class_name) |
| try: |
| if len(coordinates) % 2 != 0: |
| raise ValueError("Coordinates are not in pairs.") |
| polygon = Polygon([(coordinates[i], coordinates[i+1]) for i in range(0, len(coordinates), 2)]) |
| polygons.append(polygon) |
| class_names.append(class_name) |
| except ValueError as e: |
| print(f"Skipping line due to error: {e}") |
| else: |
| print(f"Skipping line due to insufficient data: {line.strip()}") |
| return class_names, polygons |
|
|
| def calculate_severity(self, coverage_percentage): |
| if 3 < coverage_percentage <= 30: |
| return "Minor" |
| elif 30 < coverage_percentage <= 60: |
| return "Moderate" |
| elif coverage_percentage > 60: |
| return "Severe" |
| return "N/A" |
|
|
| def calculate_cost(self, damage_class, severity): |
| if damage_class == "Broken part": |
| return self.cost_ranges["Broken part"] |
| elif severity in self.cost_ranges[damage_class]: |
| return self.cost_ranges[damage_class][severity] |
| return (0, 0) |
| |
| def summarize_damage_by_part(self, damage_polygons, part_polygons): |
| intersection_info = self.calculate_intersection_area(damage_polygons, part_polygons) |
|
|
| summary = {} |
| for info in intersection_info: |
| part_class = info['part_class'] |
| damage_class = info['damage_class'] |
| coverage_percentage = info['coverage_percentage'] |
|
|
| if part_class not in summary: |
| summary[part_class] = {'total_coverage': 0, 'damage_types': {}} |
|
|
| summary[part_class]['total_coverage'] += coverage_percentage |
|
|
| if damage_class not in summary[part_class]['damage_types']: |
| summary[part_class]['damage_types'][damage_class] = 0 |
|
|
| summary[part_class]['damage_types'][damage_class] += coverage_percentage |
|
|
| for part_class in summary: |
| total_coverage = summary[part_class]['total_coverage'] |
| for damage_class in summary[part_class]['damage_types']: |
| summary[part_class]['damage_types'][damage_class] = ( |
| summary[part_class]['damage_types'][damage_class] / total_coverage * 100 |
| ) |
|
|
| summary[part_class]['undamaged'] = 100 - total_coverage |
|
|
| return summary |
|
|
| def calculate_intersection_area(self, damage_polygons, part_polygons): |
| intersection_info = [] |
| front_back_door_detected = any(part_class in ['Front-door', 'Back-door'] for part_class, _ in part_polygons) |
|
|
| for damage_class, damage_polygon in damage_polygons: |
| for part_class, part_polygon in part_polygons: |
| if damage_polygon.intersects(part_polygon): |
| intersection = damage_polygon.intersection(part_polygon) |
| intersection_area = intersection.area |
| part_area = part_polygon.area |
| coverage_percentage = (intersection_area / part_area) * 100 |
|
|
| |
| if coverage_percentage <= 3: |
| continue |
|
|
| |
| if part_class in ['Front-bumper', 'Back-bumper']: |
| if front_back_door_detected: |
| coverage_percentage *= 0.2 |
| else: |
| coverage_percentage *= 0.6 |
| |
| if coverage_percentage <= 3: |
| continue |
|
|
| |
| if part_class in ['Headlight', 'Tail-light']: |
| if damage_class == 'Broken part' and coverage_percentage > 50: |
| intersection_info.append({ |
| "damage_class": damage_class, |
| "part_class": part_class, |
| "intersection_area": intersection_area, |
| "part_area": part_area, |
| "coverage_percentage": coverage_percentage |
| }) |
| continue |
|
|
| |
| if part_class in ['Front-wheel', 'Back-wheel', 'License-plate']: |
| continue |
|
|
| intersection_info.append({ |
| "damage_class": damage_class, |
| "part_class": part_class, |
| "intersection_area": intersection_area, |
| "part_area": part_area, |
| "coverage_percentage": coverage_percentage |
| }) |
|
|
| |
| summarized_info = {} |
| for info in intersection_info: |
| key = (info['damage_class'], info['part_class']) |
| if key not in summarized_info: |
| summarized_info[key] = { |
| "intersection_area": 0, |
| "part_area": info['part_area'], |
| "coverage_percentage": 0, |
| "count": 0 |
| } |
| summarized_info[key]["intersection_area"] += info["intersection_area"] |
| summarized_info[key]["coverage_percentage"] += info["coverage_percentage"] |
| summarized_info[key]["count"] += 1 |
|
|
| final_info = [] |
| for (damage_class, part_class), values in summarized_info.items(): |
| part_area = values["part_area"] |
| intersection_area = values["intersection_area"] |
| coverage_percentage = values["coverage_percentage"] |
| count = values["count"] |
| severity = self.calculate_severity(coverage_percentage) |
| cost_min, cost_max = self.calculate_cost(damage_class, severity) |
| final_info.append({ |
| "damage_class": damage_class, |
| "part_class": part_class, |
| "intersection_area": intersection_area, |
| "part_area": part_area, |
| "coverage_percentage": coverage_percentage, |
| "severity": severity, |
| "cost_min": cost_min, |
| "cost_max": cost_max, |
| "count": count |
| }) |
|
|
| return final_info |
|
|