当前位置:   article > 正文

使用大疆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文件。运行代码即可得到结果

  1. import os
  2. # TSDK.exe的储存位置,根据自己的情况设置
  3. tsdk = r'F:\TSDK\x64\Debug\TSDK.exe'
  4. # 拍摄的R_JPG的储存位置,根据自己的情况设置
  5. path = 'M2EA/0824-1/'
  6. # 处理结果的储存位置
  7. save_path = 'M2EA_output/0804-1/'
  8. os.makedirs(save_path, exist_ok=True)
  9. # 参数根据实际情况设置
  10. distance = 25.0
  11. emissivity = 0.95
  12. humidity = 45
  13. reflection = 51.8
  14. def use_tsdk(tsdk, path, save_path):
  15. print('开始处理')
  16. # 获取指定目录下所有文件名列表
  17. imgnamelist = os.listdir(path)
  18. for imgname in imgnamelist:
  19. # 判断文件名中是否包含"D",以过滤掉非温度图像,你的图像文件名可能包含的是别的字母,根据自己的情况设置
  20. if "D" in imgname:
  21. portion = os.path.splitext(imgname)
  22. coreimgname = portion[0]
  23. # 构建TSDK.exe的执行参数字符串:选择的模式是measure,输出的结果是温度信息,不是原始信息
  24. param = '-s ' + path + imgname + ' -a measure -o ' + save_path + coreimgname + '.raw' + ' --distance ' + str(
  25. distance) + ' --emissivity ' + str(emissivity) + ' --humidity ' + str(humidity) + '--reflection ' + str(
  26. reflection)
  27. # 调用TSDK.exe并获取返回值
  28. r_v = os.system(tsdk + ' ' + param)
  29. # 输出的为tsdk.exe运行的返回值
  30. print(r_v)
  31. print('处理完成')
  32. # 调用函数
  33. use_tsdk(tsdk, path, save_path)

3.raw文件转TIF文件

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

  1. import os
  2. import cv2
  3. import numpy as np
  4. save_path = 'M2EA_output/0804-1/'
  5. def raw_to_tif(path, rows, cols, channels):
  6. """
  7. 将指定目录下的.raw文件转换为.tif文件,并删除原始的.raw文件。
  8. 参数:
  9. - path: 存储.raw文件的目录路径
  10. - rows: 图像的行数
  11. - cols: 图像的列数
  12. - channels: 图像的通道数
  13. 注意:
  14. - 输入的.raw文件应为16位无符号整数格式
  15. - 转换后的.tif文件存储在与.raw文件相同的目录下,文件名与.raw文件相同,扩展名为.tif
  16. - 转换后的.tif文件使用TIFF格式,压缩方式为LZW压缩
  17. """
  18. print('开始转换为 .tif')
  19. # 获取指定目录下所有文件名列表
  20. files = os.listdir(path)
  21. for file in files:
  22. portion = os.path.splitext(file)
  23. # 判断文件扩展名是否为.raw
  24. if portion[1] == '.raw':
  25. realPath = path + file
  26. # 从.raw文件读取数据,数据类型为uint16
  27. img = np.fromfile(realPath, dtype='uint16')
  28. # 将数据除以10,得到温度值
  29. img = img / 10
  30. # 重塑数组形状为(rows, cols, channels)
  31. img = img.reshape(rows, cols, channels)
  32. # 构建输出.tif文件的文件名
  33. fileName = portion[0] + '.tif'
  34. tif_fileName = os.path.join(path, fileName)
  35. # 使用OpenCV保存.tif文件,压缩方式为LZW压缩
  36. cv2.imwrite(tif_fileName, img, (int(cv2.IMWRITE_TIFF_COMPRESSION), 1))
  37. # 删除原始的.raw文件,如果不需要删除,可以注释下面这行
  38. os.remove(realPath)
  39. else:
  40. print(file + ' 不是 .raw 文件')
  41. print('转换为 .tif 完成')
  42. # 调用函数,传入指定的参数
  43. raw_to_tif(save_path, 512, 640, 1)

  4.exif信息写入TIF文件

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

  1. # 导入 Image 类,该类用于读取和修改图像的 Exif 信息
  2. from pyexiv2 import Image
  3. import os
  4. # 输入的jpg路径
  5. path = 'M2EA/0824-1/'
  6. # 输入的tif路径
  7. save_path = "M2EA_output/0804-1/"
  8. def exifrw(path, exif_path):
  9. print('exifr&w start')
  10. # 初始化变量 i,用于记录无法处理的文件数量
  11. i = 0
  12. # 获取路径下的所有文件列表
  13. files = os.listdir(path)
  14. # 获取输出路径下的所有文件列表
  15. read_files = os.listdir(exif_path)
  16. # 遍历输出路径下的文件
  17. for read_file in read_files:
  18. # 检查文件名中是否包含 "D"
  19. if "D" in read_file:
  20. # 分离文件名和扩展名
  21. portion = os.path.splitext(read_file)
  22. # 用 ".tif" 替换 ".rjpgd" 得到对应的 ".tif" 文件名
  23. file = portion[0] + '.tif'
  24. # 如果对应的 ".tif" 文件存在于输入路径中
  25. if file in files:
  26. # 构建 ".tif" 文件的完整路径
  27. file_path = os.path.join(path, file)
  28. # 读取 ".tif" 文件的 Exif 信息
  29. img = Image(file_path)
  30. # 构建对应的 ".rjpgd" 文件的路径
  31. exif_file = os.path.join(exif_path, read_file)
  32. # 读取 ".rjpgd" 文件的 Exif 信息
  33. imge = Image(exif_file)
  34. # 获取 ".rjpgd" 文件的 Exif 信息
  35. exif = imge.read_exif()
  36. # 将 ".tif" 文件的 Exif 信息修改为 ".rjpgd" 文件的 Exif 信息
  37. img.modify_exif(exif)
  38. # 关闭 ".rjpgd" 和 ".tif" 文件
  39. imge.close()
  40. img.close()
  41. # 如果对应的 ".tif" 文件不存在
  42. else:
  43. # 记录无法处理的文件数量
  44. i = i + 1
  45. # 打印未完成处理的文件名
  46. print(str(file) + "unfinish")
  47. # 打印处理完成的提示
  48. print('exifr&w finish')
  49. # 打印无法处理的文件数量
  50. print(str(i) + " files can not be processed")
  51. # 打印结束提示
  52. print('end')
  53. # 调用函数,传入输出路径和输入路径
  54. exifrw(save_path, path)

5.提取pos信息并编辑

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

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

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

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

  1. import os
  2. # 输入路径,存储 pos.txt 文件的目录
  3. path = 'post/'
  4. # 大疆智图导出的 pos.txt 文件所在的路径
  5. pos_path = 'post/'
  6. # 构建 pos.txt 文件的完整路径
  7. posread = os.path.join(pos_path, "pos.txt")
  8. # 以 utf8 编码打开 pos.txt 文件
  9. f = open(posread, encoding='utf8')
  10. # 构建输出文件 posT.txt 的完整路径
  11. poswrite = os.path.join(path, "posT.txt")
  12. # 遍历 pos.txt 文件的每一行
  13. for line in f:
  14. # 判断当前行是否包含 "D"
  15. if "D" in line:
  16. # 获取 name 字段
  17. i1 = line.find(",") # 获取 ',' 的索引
  18. line1 = line[i1 - 12:i1 - 4] # 获取剩余部分
  19. # 获取 lat 字段
  20. line2 = line[i1 + 1:]
  21. i2 = line2.find(",") # 获取 ',' 的索引
  22. line3 = line2[i2 + 1:] # 获取 'lat' 字段
  23. line2 = line2[:i2] # 截取 'lat' 字段之前的部分
  24. # 获取 lon 字段
  25. i3 = line3.find(",")
  26. line4 = line3[i3 + 1:]
  27. line3 = line3[:i3]
  28. # 获取 altitude 字段
  29. i4 = line4.find(",")
  30. line5 = line4[i4 + 1:]
  31. line4 = line4[:i4]
  32. # 获取 yaw 字段
  33. i5 = line5.find(",")
  34. line6 = line5[i5 + 1:]
  35. line5 = line5[:i5]
  36. # 获取 pitch 字段
  37. i6 = line6.find(",")
  38. line7 = line6[i6 + 1:]
  39. line6 = line6[:i6]
  40. # 获取 roll 字段
  41. i7 = line7.find(",")
  42. line8 = line7[i7 + 1:]
  43. line7 = line7[:i7]
  44. # 获取 horizontal 字段
  45. i8 = line8.find(",")
  46. line9 = line8[i8 + 1:]
  47. line8 = line8[:i8]
  48. # 获取 vertical 字段
  49. i9 = len(line9)
  50. line9 = line9[:i9 - 1]
  51. # 构建新的行字符串
  52. line = line1 + '.tif ' + line2 + ' ' + line3 + ' ' + line4 + ' ' + line6 + ' ' + line5 + ' ' + line7 + ' ' + line8 + ' ' + line9 # for pix
  53. # 打印新的行字符串
  54. print(line)
  55. # 将新的行字符串写入 posT.txt 文件
  56. with open(poswrite, "a") as fs:
  57. fs.write(line + "\n")
  58. # 关闭输入文件
  59. f.close()

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

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/758259
推荐阅读
相关标签
  

闽ICP备14008679号