python学习——对大疆御3E拍摄照片赋予坐标系并旋转

news2024/11/24 7:00:22

对大疆御3E拍摄照片赋予坐标系并旋转

问题描述

进行植被覆盖度验证时,需采集验证点的植被覆盖情况,但无人机拍摄的照片缺少坐标系,无法进行对比验证。

解决方案

赋予照片坐标系

在gdal中对影像赋予坐标系主要参数为仿射六参数:左上角坐标,xy分辨率和旋转信息,故只需解决该6个参数信息即可将照片初步赋予坐标系,本次以赋予WGS-84坐标系为例。

左上角坐标计算

查看照片属性中的详细信息,其中记录了照片拍摄时的GPS信息(中心坐标)或对照片使用记事本打开,其中 drone-dji:GpsLatitude="“和drone-dji:GpsLongitude=”"两个参数也记录了经纬度信息。根据该GPS信息进行左上角坐标计算,方法为将该坐标视为图像中心坐标,无人机拍摄的照片分辨率已知(3cm),根据中心坐标的行列号与左上角坐标的行列号、xy分辨率计算出左上角坐标计算。

import re
from osgeo import gdal
import os

def png_deal(tif_src, png_file, out_folder, out_name):
    '''
    :param tif_src:正射影像的dataset,用于获取xy分辨率(如果这里没有正射影像,可自行设定分辨率)
    :param png_file:待校正照片的绝对路径
    :param out_folder:输出文件夹
    :param out_name:输出名字
    :return:
    '''
    tif_geo = tif_src.GetGeoTransform()
    tif_x_res = tif_geo[1]
    tif_y_res = tif_geo[5]
    png_src = gdal.Open(png_file)
    # get png metadata
    png_meta = png_src.GetMetadata()
    # get latitude longitude x y
    png_lon = png_meta['EXIF_GPSLongitude']
    png_lat = png_meta['EXIF_GPSLatitude']
    png_x = png_src.RasterXSize
    png_y = png_src.RasterYSize


    # change mile to degree
    png_x_res = tif_x_res / (2 * math.pi * 6371004) * 360;
    png_y_res = tif_y_res / (2 * math.pi * 6371004) * 360;

    lon_str = re.findall(r'\d+', png_lon)
    lon_decimal = float(lon_str[0]) + float(lon_str[1])/60 + (float(lon_str[2]) )/3600
    lat_str = re.findall(r'\d+', png_lat)
    lat_decimal = float(lat_str[0]) + float(lat_str[1])/60 + (float(lat_str[2]))/3600

    # caculate the left-top coordinate
    png_left_coord = [lon_decimal - png_x_res * png_x/2, lat_decimal - png_y_res * png_y/2]
    out_png_geom = [png_left_coord[0], png_x_res, 0.0, png_left_coord[1], 0.0, png_y_res]

    srs = osr.SpatialReference()
    srs.ImportFromEPSG(4326)

    # export the png tif
    driver = gdal.GetDriverByName('GTiff')
    # out_tif = driver.Create(name=out_name, ysize=tar_y, xsize=tar_x, bands=tar_bandnum, eType=tar_datatype)
    out_tif = driver.Create(out_name, png_x, png_y, png_src.RasterCount, eType=png_src.GetRasterBand(1).DataType)
    for i in range(png_src.RasterCount):
        data = png_src.GetRasterBand(i+1).ReadAsArray()
        band = out_tif.GetRasterBand(i+1).WriteArray(data)
        del data, band

    out_tif.SetProjection(srs.ExportToWkt())
    out_tif.SetGeoTransform(out_png_geom)
    out_tif.FlushCache()

    return out_tif

对照片进行旋转

对照片使用记事本打开,其中drone-dji:FlightYawDegree=""记录了照片的旋转信息,这里借助Affrine库实现对影像的旋转

# 该函数主要获取照片的偏航角
def Get_Image_Yaw_angle(file_path):
    """
    :param file_path: 输入图片路径
    :return: 图片的偏航角
    """
    # 获取图片偏航角
    b = b"\x3c\x2f\x72\x64\x66\x3a\x44\x65\x73\x63\x72\x69\x70\x74\x69\x6f\x6e\x3e"
    a = b"\x3c\x72\x64\x66\x3a\x44\x65\x73\x63\x72\x69\x70\x74\x69\x6f\x6e\x20"
    img = open(file_path, 'rb')
    data = bytearray()
    dj_data_dict = {}
    flag = False
    for line in img.readlines():
        if a in line:
            flag = True
        if flag:
            data += line
        if b in line:
            break
    if len(data) > 0:
        data = str(data.decode('ascii'))
        lines = list(filter(lambda x: 'drone-dji:' in x, data.split("\n")))
        for d in lines:
            d = d.strip()[10:]
            key, value = d.split("=")
            dj_data_dict[key] = value
    # print("Image_yaw",dj_data_dict["FlightYawDegree"][1:-1])
    return float(dj_data_dict["FlightYawDegree"][1:-1])

# 获取中心像元行列号
def raster_center(ds):
    """This function return the pixel coordinates of the raster center
    """

    # We get the size (in pixels) of the raster
    # using gdal
    width, height = ds.RasterXSize, ds.RasterYSize

    # We calculate the middle of raster
    xmed = width / 2
    ymed = height / 2
    tar_geom = ds.GetGeoTransform()
    tar_Xp = tar_geom [0] + xmed * tar_geom[1] + ymed * tar_geom[2]
    tar_Yp = tar_geom [3] + xmed * tar_geom[4] + ymed * tar_geom[5]

    return [tar_Xp, tar_Yp]
# 对照片进行旋转
def rotate_gt(affine_matrix, angle, pivot=None):
    """This function generate a rotated affine matrix
    """

    affine_src = Affine.from_gdal(*affine_matrix)
    # We made the rotation. For this we calculate a rotation matrix,
    # with the rotation method and we combine it with the original affine matrix
    # Be carful, the star operator (*) is surcharged by Affine package. He make
    # a matrix multiplication, not a basic multiplication
    affine_dst = affine_src * affine_src.rotation(angle, pivot)
    # We retrun the rotated matrix in gdal format
    return affine_dst.to_gdal()

yaw_angle = Get_Image_Yaw_angle(jpg_file)
after_coordinate_file = r'输入赋予坐标系后的照片路径'
dataset_src = gdal.Open(after_coordinate_file)
out_fin_folder = r'输出文件夹'
out_file = r'输出绝对路径'
# 创建输出路径
driver = gdal.GetDriverByName('GTiff')
datase_dst = driver.CreateCopy(out_file, dataset_src, strict=0)
gt_affine = dataset_src.GetGeoTransform()
center = raster_center(dataset_src)
# 进行旋转输出
datase_dst.SetGeoTransform(rotate_gt(gt_affine, yaw_angle, center))

结果如下
原始照片:
在这里插入图片描述
校正后结果:
在这里插入图片描述
参考:
https://blog.csdn.net/m0_56729804/article/details/131695618

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1297290.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

深度解析TCP协议:特点、应用场景及市面上常见软件案例

目录 引言 TCP的特点 TCP的应用场景 市面上使用TCP的软件案例 引言 TCP(Transmission Control Protocol)是计算机网络中一种基于连接的、可靠的传输层协议。它具有一系列独特的特点,适用于广泛的应用场景。本文将深入研究TCP的特点、应用…

VSCode SSH登录服务器 提示XHR failed

设置->搜索“代理” 把图中的√去掉 重启 即可

全面覆盖,无所不包:C++ 编程必备指南 | 开源日报 No.99

fffaraz/awesome-cpp Stars: 51.0k License: MIT 这个项目是一个精心策划的 C(或者 C) 框架、库、资源和其他有趣东西的列表。它收集了各种标准库,如 STL 容器和算法;不同领域的框架,比如人工智能、异步事件循环等;以及一系列功…

【Linux】cat 命令使用

cat 命令 cat(英文全拼:concatenate)命令用于连接文件并打印到标准输出设备上。 可以使用cat连接多个文件、创建新文件、将内容附加到现有文件、查看文件内容以及重定向终端或文件中的输出。 cat可用于在不同选项的帮助下格式化文件的输出…

应用商店ASO优化提升APP排名的6大策略

ASO优化基操你了解多少? ASO优化对于APP推广运营来说是必不可少的一个方法。在当今竞争激烈的应用程序市场中,ASO(App Store Optimization)优化已成为提升APP排名和曝光度的关键因素。 一、ASO优化的重要性 ASO优化有助于提高AP…

如何为 3D 模型制作纹理的最佳方法

在线工具推荐: 3D数字孪生场景编辑器 - GLTF/GLB材质纹理编辑器 - 3D模型在线转换 - Three.js AI自动纹理开发包 - YOLO 虚幻合成数据生成器 - 三维模型预览图生成器 - 3D模型语义搜索引擎 您可以通过不同的方式为 3D 模型创建 3D 纹理。下面我们将介绍为 3D …

UML图的各种类型以及软件设计师考试考察的方式

UML建模 前言 常见的UML的类型 UML 比前两题是更难的(略高,但是学会就可以了。前两题是:数据流图,数据库的设计),因为UML图有很多类型:用例图,类图与对象图,顺序图&…

免费网页抓取工具大全【附下载和工具使用教程】

在当今信息爆炸的时代,获取准确而丰富的数据对于企业决策和个人研究至关重要。而网页抓取工具作为一种高效获取互联网数据的方式,正逐渐成为大家解决数据需求的得力助手。本文将深入探讨网页抓取工具的种类,并为大家提供简单实用的页面采集教…

springboot3 liquibase SQL执行失败自动回滚,及自动打tag

一&#xff1a; 自动执行回滚&#xff0c; 已执行成功的忽略&#xff0c;新sql执行失败则执行新sql文件中的回滚sql pom.xml <dependency> <groupId>org.liquibase</groupId> <artifactId>liquibase-core</artifactId> <version>4.25.0&…

2023.2版idea安装教程,现在jdk8已经过去式了,不同idea支持的jdk不同。升级jdk后idea也要随之升级

下载idea2023.2版本&#xff0c;下载之前需要删除之前的版本&#xff0c;一定要删除干净&#xff0c;删除程序要勾选那两个delete 下载路径&#xff1a;其他版本 - IntelliJ IDEA (jetbrains.com.cn) 选择2023.2版本 下载后进入安装程序&#xff0c;选择安装目录&#xff0c;然…

关于我自己搭建了一个完整的 网站 - 从零开始(服务器购买选型,域名备案,wordpress 主题,各种支付插件)

这篇博客主要介绍是如何在华为云上搭建一个 WordPress 网站。我将详细介绍从购买服务器到推广网站的整个过程&#xff0c;包括域名主机的备案。无论您是技术新手还是有一定经验的开发者&#xff0c;这篇文章都能为您提供有价值的指导。 第一步&#xff1a;选择云服务器 我选择…

计算一组x和y(一维数组)

输入30个整数a1,a2,a3,…,a30&#xff0c;计算所有的x与y。已知&#xff1a; 输入格式: 30个整数 输出格式: 计算得到的x1, x2,.......,x10 计算得到的y1, y2,.......,y10 所有输出精确到小数点后3位。 注意&#xff1a; 1、输出的每个“”左右各有一个空格&#xff0c;输出…

TrustZone之Translation Look aside Buffer(TLB)

TLB缓存最近使用的地址转换。处理器具有多个独立的translation regimes。TLB记录了一个条目表示的translation regime&#xff0c;包括安全状态。虽然TLBs的结构是由实现定义的&#xff0c;但以下图表显示了一个示例&#xff1a; 当软件在EL1或EL2中发出TLB失效操作&#xff08…

亚马逊运营推荐数仓项目实战

亚马逊运营推荐数仓项目实战 项目技术栈 HadoopSpark (Python)Scala SparkSQLSparkStreaming MongoDB Redis Kafka Flume ( SpringMVC vue) 1 项目介绍 1.1 项目系统架构 项目以推荐系统建设领域知名的经过修改过的中文亚马逊电商数据集作为依托&#xff0c;以某电商…

设置网络发现,合理利用共享,让自己在准确的地方出现或隐藏

本文介绍如何在Windows 11中打开或关闭网络发现。它还解释了网络发现的用途以及你可能想使用&#xff08;或不使用&#xff09;它的时间。 如何在Windows 11中切换网络发现 可以在“设置”中打开和关闭网络发现。 1、使用WINI快捷方式打开“设置”或从任务栏中搜索。 2、选…

【数据结构】——队列实现二叉树的功能

前言&#xff1a;二叉树的实现方式多种多样&#xff0c;有数组实现满二叉树&#xff0c;有链表实现完全二叉树&#xff0c;今天我们就用队列来实现二叉树。 创建二叉树&#xff1a; typedef int BTDataType; typedef struct BinaryTreeNode {BTDataType data;struct BinaryTre…

长城之上的无人机:文化遗产的守护者

长城之上的无人机&#xff1a;文化遗产的守护者 在八达岭长城景区&#xff0c;两架无人机分别部署在了长城的南、北楼两点。根据当前的保护焦点和需求&#xff0c;制定了5条无人机综合巡查航线&#xff0c;以确保长城景区的所有开放区域都能得到有效监管。每天&#xff0c;无人…

【C++】:搜索二叉树

朋友们、伙计们&#xff0c;我们又见面了&#xff0c;本期来给大家解读一下有关多态的知识点&#xff0c;如果看完之后对你有一定的启发&#xff0c;那么请留下你的三连&#xff0c;祝大家心想事成&#xff01; C 语 言 专 栏&#xff1a;C语言&#xff1a;从入门到精通 数据结…

xml文本转Java对象

Java对象转String public static String toData(Object object) throws Exception {JAXBContext jc JAXBContext.newInstance(object.getClass());Marshaller m jc.createMarshaller();StringWriter output new StringWriter(2048);m.marshal(object, output);String data …

jsp 个人网站系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 JSP 个人&#xff08;博客&#xff09;网站系统是一套完善的java web信息管理系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为 TOMCAT7.0,Myeclipse8.5开发&…