Following this instruction :
1. Strictly adhere to PEP-8 standards, ensuring code is clean, well-structured, and follows Python's style guide for readability.
2. Use appropriate modules like `typing` for type hints, ensuring code clarity, maintainability, and leveraging Python's standard libraries effectively.
3. Focus on time, space, robustness, scalability; write optimized, efficient code that can handle large datasets and scale seamlessly.
4. Implement comprehensive error handling, catching exceptions gracefully, providing meaningful error messages, and ensuring code robustness under unexpected conditions.
5. Ensure the developer agent writes advanced, maintainable Python code, balancing performance and readability while adhering to best practices.


TASK : upload image high traffic video , now imporovemt on the video we have show the vechical count legend on the right of video frame , proffesionall look , all cormers of video not anlysis missing some vichicals 


import sys
import cv2
import logging
from typing import List, Union, Optional
from datetime import datetime
from pathlib import Path
from threading import Thread

from ultralytics import YOLO
import plotly.graph_objs as go
import plotly.io as pio

# Configure logging
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s [%(levelname)s] %(message)s',
    handlers=[
        logging.StreamHandler(sys.stdout)
    ]
)

# Constants for traffic density thresholds
LOW_THRESHOLD: int = 10     # Less than 10 vehicles per frame
MEDIUM_THRESHOLD: int = 30  # 10 to 30 vehicles per frame

# Vehicle classes based on YOLOv8's COCO dataset
VEHICLE_CLASSES: set = {'car', 'truck', 'bus', 'motorbike', 'bicycle'}


class ReportGenerator:
    """
    Generates and saves HTML reports with traffic density visualizations.
    """

    def __init__(self, output_folder: Path) -> None:
        self.output_folder: Path = output_folder

    def generate_html_report(
        self,
        timestamps: List[datetime],
        vehicle_counts: List[int]
    ) -> None:
        """
        Generate an HTML report with traffic density visualization using Plotly.

        :param timestamps: List of timestamps corresponding to each frame.
        :param vehicle_counts: List of vehicle counts per frame.
        """
        try:
            if not timestamps or not vehicle_counts:
                logging.warning("No data available to generate report.")
                return

            # Convert timestamps to string for better readability in the plot
            time_strings: List[str] = [ts.strftime("%H:%M:%S") for ts in timestamps]

            # Create a line chart for vehicle counts over time
            trace: go.Scatter = go.Scatter(
                x=time_strings,
                y=vehicle_counts,
                mode='lines+markers',
                name='Vehicle Count',
                line=dict(color='blue')
            )

            layout: go.Layout = go.Layout(
                title='Traffic Density Over Time',
                xaxis=dict(title='Time'),
                yaxis=dict(title='Number of Vehicles'),
                hovermode='closest'
            )

            fig: go.Figure = go.Figure(data=[trace], layout=layout)

            # Define the report file path with timestamp
            report_filename: str = f"traffic_report_{datetime.now().strftime('%Y%m%d_%H%M%S')}.html"
            report_path: Path = self.output_folder / report_filename

            # Save the plotly figure as an HTML file
            pio.write_html(fig, file=report_path, auto_open=False)
            logging.info(f"HTML report generated at: {report_path.resolve()}")

        except Exception as e:
            logging.error(f"Failed to generate HTML report: {e}")


class TrafficMonitor:
    """
    Monitors traffic by processing video streams, detecting vehicles, and maintaining traffic metrics.
    """

    def __init__(
        self,
        source: Union[str, int],
        model_path: str = 'yolov8n.pt',
        output_folder: str = 'traffic_reports'
    ) -> None:
        self.source: Union[str, int] = source
        self.output_folder: Path = Path(output_folder)
        self.model_path: str = model_path
        self.model: Optional[YOLO] = None
        self.cap: Optional[cv2.VideoCapture] = None
        self.timestamps: List[datetime] = []
        self.vehicle_counts: List[int] = []
        self.report_generator: Optional[ReportGenerator] = None
        self.frame_number: int = 0
        self._initialize()

    def _initialize(self) -> None:
        """
        Initialize the traffic monitor by setting up the output folder and loading the YOLO model.
        """
        self._create_output_folder()
        self._load_yolo_model()
        self.report_generator = ReportGenerator(self.output_folder)

    def _create_output_folder(self) -> None:
        """
        Create an output folder if it doesn't exist.
        """
        try:
            self.output_folder.mkdir(parents=True, exist_ok=True)
            logging.info(f"Output folder is set to: {self.output_folder.resolve()}")
        except Exception as e:
            logging.error(f"Failed to create output folder '{self.output_folder}': {e}")
            sys.exit(1)

    def _load_yolo_model(self) -> None:
        """
        Load the YOLOv8 model.
        """
        try:
            self.model = YOLO(self.model_path)
            logging.info("YOLOv8 model loaded successfully.")
        except Exception as e:
            logging.error(f"Failed to load YOLOv8 model: {e}")
            sys.exit(1)

    @staticmethod
    def classify_traffic_density(vehicle_count: int) -> str:
        """
        Classify traffic density based on the number of vehicles detected.

        :param vehicle_count: Number of vehicles detected in the frame.
        :return: Traffic density category as a string.
        """
        if vehicle_count < LOW_THRESHOLD:
            return 'Low Traffic'
        elif LOW_THRESHOLD <= vehicle_count < MEDIUM_THRESHOLD:
            return 'Medium Traffic'
        else:
            return 'High Traffic'

    def _process_detections(self, detections) -> int:
        """
        Process YOLO detections and count vehicles.

        :param detections: YOLO detections for the current frame.
        :return: Number of vehicles detected.
        """
        vehicle_count: int = 0
        for det in detections:
            try:
                cls_id: int = int(det.cls[0])
                cls_name: str = self.model.names.get(cls_id, '')
                if cls_name in VEHICLE_CLASSES:
                    vehicle_count += 1
                    # Draw bounding box
                    x1, y1, x2, y2 = map(int, det.xyxy[0])
                    cv2.rectangle(self.frame, (x1, y1), (x2, y2), (0, 255, 0), 2)
                    cv2.putText(
                        self.frame, cls_name, (x1, y1 - 10),
                        cv2.FONT_HERSHEY_SIMPLEX, 0.9, (36, 255, 12), 2
                    )
            except Exception as e:
                logging.error(f"Error processing detection: {e}")
        return vehicle_count

    def process_stream(self) -> None:
        """
        Process the video stream, perform object detection, and collect traffic metrics.
        """
        try:
            self.cap = cv2.VideoCapture(self.source)
            if not self.cap.isOpened():
                logging.error(f"Cannot open video source: {self.source}")
                sys.exit(1)
            else:
                logging.info(f"Video source '{self.source}' opened successfully.")

            while True:
                ret, frame = self.cap.read()
                if not ret:
                    logging.warning("No frame received. Exiting...")
                    break

                self.frame_number += 1
                self.frame: any = frame.copy()  # Make a copy to draw annotations
                timestamp: datetime = datetime.now()
                self.timestamps.append(timestamp)

                # Perform object detection
                results = self.model(self.frame, verbose=False)

                # Extract detected classes and count vehicles
                detections = results[0].boxes
                vehicle_count = self._process_detections(detections)
                self.vehicle_counts.append(vehicle_count)
                traffic_density = self.classify_traffic_density(vehicle_count)

                # Display traffic density on the frame
                cv2.putText(
                    self.frame, f'Traffic: {traffic_density}', (50, 50),
                    cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2
                )

                # Display the resulting frame
                cv2.imshow('Real-Time Traffic Monitoring', self.frame)

                # Break the loop on 'q' key press
                if cv2.waitKey(1) & 0xFF == ord('q'):
                    logging.info("Exit signal received. Stopping video processing...")
                    break

                # Logging every 100 frames to avoid excessive log entries
                if self.frame_number % 100 == 0:
                    logging.info(f"Processed {self.frame_number} frames.")

            self._cleanup()

        except KeyboardInterrupt:
            logging.info("Keyboard interrupt received. Exiting gracefully...")
            self._cleanup()
        except Exception as e:
            logging.error(f"An error occurred during video processing: {e}")
            self._cleanup()
            sys.exit(1)

    def _cleanup(self) -> None:
        """
        Release video capture and destroy all OpenCV windows. Generate the report.
        """
        if self.cap and self.cap.isOpened():
            self.cap.release()
            logging.info("Video capture released.")
        cv2.destroyAllWindows()
        logging.info("All OpenCV windows destroyed.")

        if self.report_generator:
            # Generate the HTML report in a separate thread to avoid blocking
            report_thread: Thread = Thread(
                target=self.report_generator.generate_html_report,
                args=(self.timestamps, self.vehicle_counts),
                daemon=True
            )
            report_thread.start()
            logging.info("Report generation started in a separate thread.")


def get_video_source() -> Union[str, int]:
    """
    Prompt the user to choose between uploading a video or using the webcam.

    :return: Video source (file path or webcam index).
    """
    while True:
        print("\nSelect Video Source:")
        print("1. Upload a video file")
        print("2. Use webcam for real-time recording")
        choice: str = input("Enter your choice (1 or 2): ").strip()

        if choice == '1':
            file_path: str = input("Enter the path to the video file: ").strip()
            if Path(file_path).is_file():
                logging.info(f"Selected video file: {file_path}")
                return file_path
            else:
                logging.error(f"File not found: {file_path}")
        elif choice == '2':
            logging.info("Selected webcam for real-time recording.")
            return 0  # Typically, 0 is the default webcam index
        else:
            logging.error("Invalid choice. Please enter 1 or 2.")


def main() -> None:
    """
    Main function to set up and run the traffic monitoring system based on user choice.
    """
    try:
        # Get user choice for video source
        video_source: Union[str, int] = get_video_source()

        # Initialize and start the traffic monitor
        traffic_monitor: TrafficMonitor = TrafficMonitor(source=video_source)
        traffic_monitor.process_stream()

    except Exception as e:
        logging.error(f"An unexpected error occurred in the main function: {e}")
        sys.exit(1)


if __name__ == '__main__':
    main()