Sheldon_He684 2024-07-11 13:45 采纳率: 0%
浏览 19
已结题

无人机像素经纬度识别

问题遇到的现象和发生背景
遇到的现象和发生背景,请写出第一个错误信息
用代码块功能插入代码,请勿粘贴截图。 不用代码块回答率下降 50%
运行结果及详细报错内容
我的解答思路和尝试过的方法,不写自己思路的,回答率下降 60%
我想要达到的结果,如果你需要快速回答,请尝试 “付费悬赏”

根据代码,我的需求就是鼠标点击照片中某一点的坐标,能迅速识别出这一点的经纬度信息,但是两张照片,拍摄的同一位置显示的结果并不相同,谁能帮忙解决一下
我的无人机是垂直于地面飞行,不考虑地球曲率、图像畸变,我的思路是先提取出图像的经纬度信息,这个经纬度信息是飞行器拍摄位置也是图像中心点的经纬度坐标,知道了图像的GSD,调用鼠标,计算鼠标点击区域的经纬度信息

import exifread
import cv2
import numpy as np
import math

# 从图像文件中提取GPS信息
def extract_gps_info(file_path):
    with open(file_path, 'rb') as f:
        tags = exifread.process_file(f)
        if 'GPS GPSLatitude' in tags and 'GPS GPSLongitude' in tags:
            latitude = tags['GPS GPSLatitude'].values
            longitude = tags['GPS GPSLongitude'].values
            latitude_ref = tags['GPS GPSLatitudeRef'].values
            longitude_ref = tags['GPS GPSLongitudeRef'].values

            lat_degrees = float(latitude[0].num) / float(latitude[0].den)
            lat_minutes = float(latitude[1].num) / float(latitude[1].den)
            lat_seconds = float(latitude[2].num) / float(latitude[2].den)

            lon_degrees = float(longitude[0].num) / float(longitude[0].den)
            lon_minutes = float(longitude[1].num) / float(longitude[1].den)
            lon_seconds = float(longitude[2].num) / float(longitude[2].den)

            if latitude_ref == 'S':
                lat_degrees = -lat_degrees
            if longitude_ref == 'W':
                lon_degrees = -lon_degrees

            latitude_decimal = lat_degrees + lat_minutes/60 + lat_seconds/3600
            longitude_decimal = lon_degrees + lon_minutes/60 + lon_seconds/3600

            return latitude_decimal, longitude_decimal
        else:
            return None

# 主函数
if __name__ == '__main__':
    # 图像文件路径
    file_path = 'DJI_20231225165215_0426_T.JPG'

    # 提取GPS信息
    gps_info = extract_gps_info(file_path)
    if gps_info is not None:
        latitude_decimal, longitude_decimal = gps_info
        print(f"Latitude: {latitude_decimal:.6f}")
        print(f"Longitude: {longitude_decimal:.6f}")
    else:
        print("No GPS information found in the image.")

    # 加载热红外图像
    infrared_image = cv2.imread(file_path, cv2.IMREAD_UNCHANGED)

    # 无人机位置和姿态数据
    uav_latitude = latitude_decimal  # 无人机纬度
    uav_longitude = longitude_decimal  # 无人机经度
    uav_altitude = 20  # 无人机高度(米)
    uav_roll_angle = 0  # 无人机横滚角(度)
    uav_pitch_angle = -90  # 无人机俯仰角(度)
    uav_yaw_angle = 64.60
        #74.40  # 无人机偏航角(度)

    # 相机内参数
    focal_length = 758.33# 焦距(像素)
    sensor_size_width = 7.68  # 传感器宽度(毫米)
    sensor_size_height = 6.144  # 传感器高度(毫米)
    image_width = 640  # 图像宽度(像素)
    image_height = 512  # 图像高度(像素)
    gsd = 0.05275  # 单位:米 (meters),地面采样距离

    # 计算相机的内外参数矩阵
    camera_matrix = np.array([[focal_length, 0, image_width / 2],
                              [0, focal_length, image_height / 2],
                              [0, 0, 1]], dtype=np.float32)

    dist_coefs = np.zeros((4, 1), dtype=np.float32)  # 假设无畸变


    # 鼠标单击事件回调函数
    def get_pixel_coord(event, x, y, flags, param):
        if event == cv2.EVENT_LBUTTONDOWN:
            # 计算点击位置在图像中的坐标
            pixel_x = x
            pixel_y = y

            # 计算点击点相对于中心的偏移量
            cx = image_width / 2 # 单位:像素 (pixels)
            cy = image_height / 2  # 单位:像素 (pixels)
            delta_x = pixel_x - cx  # 单位:像素 (pixels)
            delta_y = pixel_y - cy  # 单位:像素 (pixels)

            # 考虑偏航角
            theta = math.radians(uav_yaw_angle)  # 单位:弧度 (radians)

            # 旋转偏移量以考虑偏航角

            delta_x_prime = delta_x * math.cos(theta) - delta_y * math.sin(theta)  # 单位:像素 (pixels)
            delta_y_prime = delta_x * math.sin(theta) + delta_y * math.cos(theta)  # 单位:像素 (pixels)

            # 根据GSD计算实际距离
            delta_x_meters = delta_x_prime * gsd  # 单位:米 (meters)
            delta_y_meters = delta_y_prime * gsd  # 单位:米 (meters)

            # 计算点击点的经纬度
            click_lat = uav_latitude + delta_y_meters / (111000)  # 111000米大约是1度纬度的距离,单位:度 (degrees)
            click_lon = uav_longitude + delta_x_meters / (111000 * math.cos(math.radians(uav_latitude)))  # 单位:度 (degrees)


            print(f"Pixel coordinates: ({x}, {y})")
            print(f"Latitude: {click_lat:.8f}")
            print(f"Longitude: { click_lon:.8f}")

    cv2.imshow('Infrared Image', infrared_image)
    cv2.setMouseCallback('Infrared Image', get_pixel_coord)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

  • 写回答

28条回答 默认 最新

  • 阿里嘎多学长 2024-07-11 13:48
    关注
    获得0.15元问题酬金

    以下内容由CHATGPT及阿里嘎多学长共同生成、有用望采纳:


    您好!很高兴看到您正在尝试解决无人机图像中像素坐标到经纬度的转换问题。这个问题涉及到图像处理和地理信息系统(GIS)的多个方面。让我们一步步分析您遇到的问题。

    首先,您已经成功地从图像的EXIF信息中提取了无人机的GPS坐标,这是一个很好的开始。接下来,您使用了无人机的飞行数据和相机的参数来计算地面采样距离(GSD),这也是正确的方法。

    问题可能出在以下几个方面:

    1. 图像的GSD计算:GSD的计算是否准确?如果无人机的飞行高度或相机参数有微小的变化,都可能影响到GSD的准确性。

    2. 鼠标点击坐标的处理:在图像上点击的坐标是否准确转换为相对于图像中心的偏移量?这需要确保图像的原点(0,0)是在图像的左上角,并且坐标系是正确的。

    3. 偏航角的处理:您已经考虑了偏航角对坐标的影响,但是需要确保偏航角的值是准确的,并且旋转矩阵的计算是正确的。

    4. 地球曲率的忽略:虽然您提到不考虑地球曲率,但是在高精度要求下,地球曲率的影响可能需要考虑。

    5. 图像的校准:是否每张图像都经过了相同的校准过程?不同的图像可能因为拍摄条件的不同(如光照、角度等)需要不同的校准。

    6. 代码实现:检查代码实现中是否有逻辑错误或计算错误,特别是经纬度转换的部分。

    为了解决您的问题,我建议您:

    • 验证GSD的计算是否准确,可以通过比较不同图像上的相同物理位置的GSD值来检查。
    • 确保鼠标点击事件正确地获取了图像上的像素坐标,并且这些坐标被正确地转换为相对于图像中心的偏移量。
    • 检查无人机的偏航角数据是否准确,并且旋转矩阵的计算是否正确。
    • 如果可能,考虑使用更高精度的经纬度转换方法,比如考虑地球曲率的影响。
    • 对每张图像进行校准,确保它们在处理过程中是一致的。

    此外,您可以考虑使用一些专业的GIS软件或库来帮助您进行更准确的经纬度转换,比如GDAL或Pyproj。

    希望这些建议对您有所帮助!如果您需要进一步的帮助,请随时告诉我。

    评论 编辑记录

报告相同问题?

问题事件

  • 系统已结题 7月19日
  • 创建了问题 7月11日

悬赏问题

  • ¥15 如何在vue.config.js中读取到public文件夹下window.APP_CONFIG.API_BASE_URL的值
  • ¥50 浦育平台scratch图形化编程
  • ¥20 求这个的原理图 只要原理图
  • ¥15 vue2项目中,如何配置环境,可以在打完包之后修改请求的服务器地址
  • ¥20 微信的店铺小程序如何修改背景图
  • ¥15 UE5.1局部变量对蓝图不可见
  • ¥15 一共有五道问题关于整数幂的运算还有房间号码 还有网络密码的解答?(语言-python)
  • ¥20 sentry如何捕获上传Android ndk 崩溃
  • ¥15 在做logistic回归模型限制性立方条图时候,不能出完整图的困难
  • ¥15 G0系列单片机HAL库中景园gc9307液晶驱动芯片无法使用硬件SPI+DMA驱动,如何解决?