uas-at-ucla / suas-23-24

Software/Vision operations for UAS@UCLA, 2023-2024. For a list of tasks, visit https://github.com/orgs/uas-at-ucla/projects/1
3 stars 0 forks source link

GPS Tagging #31

Open nathanchan631 opened 1 year ago

nathanchan631 commented 1 year ago

Implement the algorithm described here: https://drive.google.com/file/d/1RR4rdbkf4fAFXdHqxx3LnqgSiEW36u39/view

kushhansagarwal commented 1 year ago

I have implemented an untested version of the code here.

Code is as follows

def calculate_object_gps(image_path: str, detections: list) -> list:
    """
    Calculates the GPS coordinates of detected objects in an image.

    Args:
        image_path (str): The path to the input image.
        detections (list): A list of dictionaries containing the x and y positions of the detected objects.

    Returns:
        list: A list of tuples containing the GPS coordinates of the detected objects.
    """

    # Open the image and get its dimensions
    with Image.open(image_path) as image:
        image_width = image.size[0]
        image_height = image.size[1]

    # Get the image metadata
    image_metadata = exif.ImageMetadata(image)
    image_metadata.read()

    # Get the image metadata
    location = [image_metadata.gps_latitude, image_metadata.gps_longitude]
    true_heading = image_metadata.gps_img_direction
    altitude = image_metadata.gps_altitude
    focal_length = image_metadata.focal_length
    sensor_width = image_metadata.sensor_width

    # Calculate the center pixel of the image
    center_pixel_x = image_width / 2
    center_pixel_y = image_height / 2

    # Calculate the ground sample distance
    GSD = (altitude * sensor_width) / (focal_length * image_width)

    # Calculate the GPS coordinates of the detected objects
    detections_coords = []

    for detection in detections:
        x_pos = detection['x_pos']
        y_pos = detection['y_pos']

        #  Calculate the delta x and y of the detected object in inches
        delta_x = (x_pos - center_pixel_x) * GSD
        delta_y = (y_pos - center_pixel_y) * GSD

        # Calculate the true x and y of the detected object in inches
        true_x = delta_x * math.cos(true_heading) - delta_y * math.sin(true_heading)
        true_y = delta_x * math.sin(true_heading) + delta_y * math.cos(true_heading)

        # Convert the true x and y to GPS coordinates
        delta_gps_x = true_x / 111111
        delta_gps_y = true_y / 111111

        # Add the GPS coordinates to the list of detections
        detections_coords = [(location[0] + delta_gps_x, location[1] + delta_gps_y)]

    # Return the GPS coordinates of the detected objects
    return detections_coords

I am not sure about the conversion from inches to GPS coordinates, as I do not know what GPS location format we would be using for telemetry and tagging.

nathanchan631 commented 1 year ago

Looks good, though your function looks different than the one I linked? Anyway, we're using latitude/longitude. Also, could you make a new file in the odlc directory and put it there?

kushhansagarwal commented 1 year ago

I am using a slightly different approach which I believe would be quicker to debug. It is as follows

I think its better as it avoids the lengthy equation in the doc you linked and breaks it into simpler steps. However, I am still not 100% sure about the rotation of axes code and will fix it soon.