使用大疆TSDK实现对红外照片(R_JPEG)的处理 | 无人机热红外照片R_JPG转成TIF后拼接 | 热红外照片温度信息提取 | 方法一

        使用大疆御2行业进阶版(M2EA)拍摄,得到红外照片(R-JPEG),R-JPEG照片使用大疆红外热分析工具3(DJI Thermal Analysis Tool 3)打开设置才会显示温度值,但我们需要的是照片中每个像素表示温度,而不是RGB

        下面我会展示将R-JPEG图像批量转成TIF,TIF图像中每个像素的数据不再表示颜色信息,而是表示了温度,最后将TIF拼接成完整影像

        系统版本:windows 10 64位

        visual studio版本:2019

        大疆TSDK版本:dji_thermal_sdk_v1.4_20220929

        大疆智图版本:DJI Terra 4.0.1

        Pix4D mapper版本:4.4.12

        PyCharm版本:2023

1.在visual studio 2019中配置大疆TSDK

        (1)在visual studio 2019中新建新项目(我的为TSDK),创建好C++文件(我的C++文件名为TSDK.cpp)

        (2)将下载解压缩好的大疆TSDK文件夹dji_thermal_sdk_v1.4_20220929\sample路径下的dji_irp.cpp里面的所有代码复制粘贴到创建好的C++文件中,即TSDK.cpp(复制粘贴后会提示有很多错误,不用担心,后面会解决)

        (3)在项目TSDK下新建名为“Libs”的文件夹,然后在Libs文件夹里面分别新建一个名为“icn”和“lib”的子文件夹(两个文件夹下面要用到)

       (4)将大疆TSDK文件夹dji_thermal_sdk_v1.4_20220929\tsdk-core\api路径下的所有文件复制粘贴到icn文件夹中。同时,将dji_thermal_sdk_v1.4_20220929\sample\argparse路径下的所有文件也复制粘贴放入icn文件夹中

        (5)将dji_thermal_sdk_v1.4_20220929\tsdk-core\lib\windows\release_x64路径下所有后缀为.lib的文件复制粘贴到lib文件夹中

        (6)visual studio 2019 界面上方选择 Debug 和 x64 ,然后右键生成TSDK项目(点击图示2处也可以),项目生成后会在TSDK项目文件夹下会生成一个名为 x64 的文件夹

     (7)将dji_thermal_sdk_v1.4_20220929\tsdk-core\lib\windows\release_x64路径下所有后缀为.dll的文件和后缀为.ini的文件复制粘贴到项目文件夹TSDK\x64\Debug路径下

        (8)在TSDK项目中选择 调试 > TSDK调试属性 > C/C++ > 常规 中,将 附加包含目录 设置为 icn 文件夹

        在TSDK项目中选择 调试 > TSDK调试属性 > 连接器 > 常规 中,将 附加库目录 设置为 lib 文件夹

        在TSDK项目中选择 调试 > TSDK调试属性  > 连接器 > 输入 中,将 附加依赖项 设置为 libdirp.lib ,配置结束

        点击 本地windows调试器 ,会在TSDK\x64\Debug文件夹下生成两个文件(TSDK.exe和TSDK.pdb),TSDK.exe在后面编写python代码的时候会用到

2.编写python代码调用TSDK

        编写python代码调用TSDK.exe,批量处理红外照片(R_JPEG),生成存储温度信息的.raw文件。运行代码即可得到结果

import os

# TSDK.exe的储存位置,根据自己的情况设置
tsdk = r'F:\TSDK\x64\Debug\TSDK.exe'

# 拍摄的R_JPG的储存位置,根据自己的情况设置
path = 'M2EA/0824-1/'

# 处理结果的储存位置
save_path = 'M2EA_output/0804-1/'
os.makedirs(save_path, exist_ok=True)

# 参数根据实际情况设置
distance = 25.0
emissivity = 0.95
humidity = 45
reflection = 51.8


def use_tsdk(tsdk, path, save_path):
    print('开始处理')
    # 获取指定目录下所有文件名列表
    imgnamelist = os.listdir(path)
    for imgname in imgnamelist:
        # 判断文件名中是否包含"D",以过滤掉非温度图像,你的图像文件名可能包含的是别的字母,根据自己的情况设置
        if "D" in imgname:
            portion = os.path.splitext(imgname)
            coreimgname = portion[0]
            # 构建TSDK.exe的执行参数字符串:选择的模式是measure,输出的结果是温度信息,不是原始信息
            param = '-s ' + path + imgname + ' -a measure -o ' + save_path + coreimgname + '.raw' + ' --distance ' + str(
                distance) + ' --emissivity ' + str(emissivity) + ' --humidity ' + str(humidity) + '--reflection ' + str(
                reflection)
            # 调用TSDK.exe并获取返回值
            r_v = os.system(tsdk + ' ' + param)
            # 输出的为tsdk.exe运行的返回值
            print(r_v)
            print('处理完成')


# 调用函数
use_tsdk(tsdk, path, save_path)

3.raw文件转TIF文件

        将.raw文件中每个数据的值除以10以后即为温度值(即最小精度0.1℃),每个数据即是对应坐标点的测量温度值,转为.tif文件以供后续使用

import os
import cv2
import numpy as np

save_path = 'M2EA_output/0804-1/'


def raw_to_tif(path, rows, cols, channels):
    """
        将指定目录下的.raw文件转换为.tif文件,并删除原始的.raw文件。

        参数:
        - path: 存储.raw文件的目录路径
        - rows: 图像的行数
        - cols: 图像的列数
        - channels: 图像的通道数

        注意:
        - 输入的.raw文件应为16位无符号整数格式
        - 转换后的.tif文件存储在与.raw文件相同的目录下,文件名与.raw文件相同,扩展名为.tif
        - 转换后的.tif文件使用TIFF格式,压缩方式为LZW压缩

        """
    print('开始转换为 .tif')
    # 获取指定目录下所有文件名列表
    files = os.listdir(path)
    for file in files:
        portion = os.path.splitext(file)
        # 判断文件扩展名是否为.raw
        if portion[1] == '.raw':
            realPath = path + file
            # 从.raw文件读取数据,数据类型为uint16
            img = np.fromfile(realPath, dtype='uint16')
            # 将数据除以10,得到温度值
            img = img / 10
            # 重塑数组形状为(rows, cols, channels)
            img = img.reshape(rows, cols, channels)
            # 构建输出.tif文件的文件名
            fileName = portion[0] + '.tif'
            tif_fileName = os.path.join(path, fileName)
            # 使用OpenCV保存.tif文件,压缩方式为LZW压缩
            cv2.imwrite(tif_fileName, img, (int(cv2.IMWRITE_TIFF_COMPRESSION), 1))
            # 删除原始的.raw文件,如果不需要删除,可以注释下面这行
            os.remove(realPath)
        else:
            print(file + ' 不是 .raw 文件')
    print('转换为 .tif 完成')


# 调用函数,传入指定的参数
raw_to_tif(save_path, 512, 640, 1)

  4.exif信息写入TIF文件

        前面转出来的.tif文件没有exif信息,无法定位。下面将exif信息从R_JPG图像中提取出来,写入.tif文件

# 导入 Image 类,该类用于读取和修改图像的 Exif 信息
from pyexiv2 import Image
import os

# 输入的jpg路径
path = 'M2EA/0824-1/'
# 输入的tif路径
save_path = "M2EA_output/0804-1/"


def exifrw(path, exif_path):
    print('exifr&w start')
    # 初始化变量 i,用于记录无法处理的文件数量
    i = 0
    # 获取路径下的所有文件列表
    files = os.listdir(path)
    # 获取输出路径下的所有文件列表
    read_files = os.listdir(exif_path)
    # 遍历输出路径下的文件
    for read_file in read_files:
        # 检查文件名中是否包含 "D"
        if "D" in read_file:
            # 分离文件名和扩展名
            portion = os.path.splitext(read_file)
            # 用 ".tif" 替换 ".rjpgd" 得到对应的 ".tif" 文件名
            file = portion[0] + '.tif'
            # 如果对应的 ".tif" 文件存在于输入路径中
            if file in files:
                # 构建 ".tif" 文件的完整路径
                file_path = os.path.join(path, file)
                # 读取 ".tif" 文件的 Exif 信息
                img = Image(file_path)
                # 构建对应的 ".rjpgd" 文件的路径
                exif_file = os.path.join(exif_path, read_file)
                # 读取 ".rjpgd" 文件的 Exif 信息
                imge = Image(exif_file)
                # 获取 ".rjpgd" 文件的 Exif 信息
                exif = imge.read_exif()
                # 将 ".tif" 文件的 Exif 信息修改为 ".rjpgd" 文件的 Exif 信息
                img.modify_exif(exif)
                # 关闭 ".rjpgd" 和 ".tif" 文件
                imge.close()
                img.close()
            # 如果对应的 ".tif" 文件不存在
            else:
                # 记录无法处理的文件数量
                i = i + 1
                # 打印未完成处理的文件名
                print(str(file) + "unfinish")
    # 打印处理完成的提示
    print('exifr&w finish')
    # 打印无法处理的文件数量
    print(str(i) + " files can not be processed")
    # 打印结束提示
    print('end')


# 调用函数,传入输出路径和输入路径
exifrw(save_path, path)

5.提取pos信息并编辑

        上面的方法处理exif信息只能读取地理信息,无法读取精度及航向角等信息(使用pix4d mapper可以查看到TIF文件里面没有这些信息),拼接的图像不准,可以用大疆智图导出pos信息,经过编辑,导入pix4D mapper

TIF文件里面没有俯仰角、翻滚角、航偏角等信息

        (1)使用大疆智图导出pos信息

        (2)使用python代码编辑pos信息

import os

# 输入路径,存储 pos.txt 文件的目录
path = 'post/'
# 大疆智图导出的 pos.txt 文件所在的路径
pos_path = 'post/'
# 构建 pos.txt 文件的完整路径
posread = os.path.join(pos_path, "pos.txt")
# 以 utf8 编码打开 pos.txt 文件
f = open(posread, encoding='utf8')
# 构建输出文件 posT.txt 的完整路径
poswrite = os.path.join(path, "posT.txt")
# 遍历 pos.txt 文件的每一行
for line in f:
    # 判断当前行是否包含 "D"
    if "D" in line:
        # 获取 name 字段
        i1 = line.find(",")  #  获取 ',' 的索引
        line1 = line[i1 - 12:i1 - 4]  # 获取剩余部分

        # 获取 lat 字段
        line2 = line[i1 + 1:]
        i2 = line2.find(",")  # 获取 ',' 的索引
        line3 = line2[i2 + 1:]  # 获取 'lat' 字段
        line2 = line2[:i2]  # 截取 'lat' 字段之前的部分

        # 获取 lon 字段
        i3 = line3.find(",")
        line4 = line3[i3 + 1:]
        line3 = line3[:i3]

        # 获取 altitude 字段
        i4 = line4.find(",")
        line5 = line4[i4 + 1:]
        line4 = line4[:i4]

        # 获取 yaw 字段
        i5 = line5.find(",")
        line6 = line5[i5 + 1:]
        line5 = line5[:i5]

        # 获取 pitch 字段
        i6 = line6.find(",")
        line7 = line6[i6 + 1:]
        line6 = line6[:i6]

        # 获取 roll 字段
        i7 = line7.find(",")
        line8 = line7[i7 + 1:]
        line7 = line7[:i7]

        # 获取 horizontal 字段
        i8 = line8.find(",")
        line9 = line8[i8 + 1:]
        line8 = line8[:i8]

        # 获取 vertical 字段
        i9 = len(line9)
        line9 = line9[:i9 - 1]

        # 构建新的行字符串
        line = line1 + '.tif ' + line2 + ' ' + line3 + ' ' + line4 + ' ' + line6 + ' ' + line5 + ' ' + line7 + ' ' + line8 + ' ' + line9  # for pix

        # 打印新的行字符串
        print(line)
        # 将新的行字符串写入 posT.txt 文件
        with open(poswrite, "a") as fs:
            fs.write(line + "\n")

# 关闭输入文件
f.close()

        (3)将TIF文件和编辑后的pos信息导入pix4D mapper,使用pix4D mapper进行图像拼接成完整的TIF

                第一次处理红外照片(R_JPEG),文中不可避免地可能会有一些错误或遗漏的地方。如果有什么问题请在评论区留言

版权声明:本文为博主作者:君不见~原创文章,版权归属原作者,如果侵权,请联系我们删除!

原文链接:https://blog.csdn.net/qq_23865133/article/details/135813617

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
xiaoxingxing的头像xiaoxingxing管理团队
上一篇 2024年4月16日
下一篇 2024年4月16日

相关推荐