pcdtovideo_jilong_overlook.py 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. """
  4. Created on Wed Nov 1 13:38:28 2023
  5. @author: dell
  6. """
  7. import subprocess
  8. from subprocess import Popen, PIPE
  9. import os
  10. import sys
  11. import math
  12. import cv2
  13. import numpy as np
  14. import shutil
  15. import rosbag
  16. def draw_points(pic, filename):
  17. colormap = np.array([[128, 130, 120],
  18. [235, 0, 205],
  19. [0, 215, 0],
  20. [235, 155, 0]]) / 255.0
  21. f = open(filename, "r")
  22. ff = f.readlines()[11:]
  23. for i in range(0, len(ff)):
  24. point = ff[i].split()[:4]
  25. point_x = float(point[0])
  26. point_y = -float(point[1])
  27. point_z = float(point[2])
  28. points_intensity = float(point[2])
  29. if math.isnan(point_x):
  30. pass
  31. else:
  32. cv2.circle(pic, (int(800 - point_x * 10), int(400 - point_y * 10)), 0,
  33. colormap[int(points_intensity) % colormap.shape[0]] * 255, 2)
  34. # if __name__ == '__main__':
  35. # input_dir = sys.argv[1]
  36. # # input_dir='/media/dell/BFAC-F22B/data/jinlong_datareturn/test_1116/jinlong_data_merge_2023-12-13-05-59-34_TTC_7.bag'
  37. # output_dir = sys.argv[2]
  38. # # output_dir = '/media/dell/BFAC-F22B/data/jinlong_datareturn/test_1116'
  39. #
  40. # bag_name = input_dir.split('/')[-1].split('.')[0]
  41. # output_dir = os.path.join(output_dir, bag_name + '_pcd_overlook' + '/pcd')
  42. # if not os.path.exists(output_dir):
  43. # os.makedirs(output_dir)
  44. #
  45. # with rosbag.Bag(input_dir, 'r') as bag:
  46. # num_count = 0
  47. # for topic, msg, t in bag.read_messages():
  48. # if topic == "/points_concat": # /camera/depth/points # /scan_map_icp_amcl_node/scan_point_transformed
  49. # num_count += 1
  50. #
  51. # bagtime = int(input_dir.split('/')[-1].split('.')[0].split('_')[-1])
  52. # hz = str(float(num_count / bagtime))
  53. # print(hz)
  54. #
  55. # #######################解析rosbag中的点云point_concat话题,获得原始pcd文件#######################
  56. # command = ['rosrun', 'pcl_ros', 'bag_to_pcd'] + [input_dir] + ['/points_concat'] + [output_dir]
  57. # command = ' '.join(command)
  58. # os.system(command)
  59. # file1 = os.path.join(output_dir[0:-4], 'pcd_ascii')
  60. # file2 = os.path.join(output_dir[0:-4], 'jpg')
  61. # if not os.path.exists(file1):
  62. # os.makedirs(file1)
  63. # if not os.path.exists(file2):
  64. # os.makedirs(file2)
  65. #
  66. # #######################将原始pcd文件转化成pcd-ascii格式,并生成jpg文件#######################
  67. # for root, dirs, files in os.walk(output_dir[0:-4]):
  68. #
  69. # # find .pcd files and do the transfer twice
  70. # for file in files:
  71. # if "pcd" == root[-3:] and ".pcd" == file[-4:]:
  72. #
  73. # inputFilePath = root + "/" + file
  74. # tempFilePath = root[:-3] + "pcd_ascii/" + file
  75. # outputFilePath = root[:-3] + "jpg/" + file[:-3] + "jpg"
  76. #
  77. # # transfer pcd_utf-8 to pcd_ascii
  78. # command = "pcl_convert_pcd_ascii_binary " + \
  79. # inputFilePath + \
  80. # " " + \
  81. # tempFilePath + \
  82. # " 0"
  83. # # print(command)
  84. # os.system(command)
  85. #
  86. # # make sure the temp file exist, invalid input file may cause this issue
  87. # if not os.path.exists(tempFilePath):
  88. # continue
  89. #
  90. # # transfer pcd_ascii to jpg
  91. # pic = np.zeros([800, 1600, 3]) # pic = np.zeros([800, 1600, 3])
  92. # draw_points(pic, tempFilePath)
  93. # cv2.imwrite(outputFilePath, pic)
  94. # # print("jpg generated: ", outputFilePath)
  95. # else:
  96. # break
  97. #
  98. # #######################将转化的点云jpg合成视频#######################
  99. # jpg_list = os.listdir(file2)
  100. # if not jpg_list == []:
  101. # # command = ['ffmpeg', '-f', 'image2', '-r', hz, '-pattern_type', 'glob', '-i'] + ['"jpg/*.jpg"'] + ['-tag:v',
  102. # # 'avc1',
  103. # # '-y'] + [
  104. # # 'pcd_overlook.mp4']
  105. # command = ['ffmpeg', '-f', 'image2', '-t', bagtime, '-pattern_type', 'glob', '-i'] + ['"jpg/*.jpg"'] + [
  106. # '-tag:v', 'avc1', '-y'] + ['pcd_overlook.mp4']
  107. # result_string = " ".join(command)
  108. # p = Popen(result_string, shell=True, cwd=output_dir[0:-4] + '/', stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  109. # p.wait()
  110. # shutil.rmtree(file1)
  111. # shutil.rmtree(file2)
  112. # shutil.rmtree(output_dir)
  113. def parse(input_bag_file, output_mp4_dir):
  114. input_dir = input_bag_file
  115. # input_dir='/media/dell/BFAC-F22B/bizhang_2023-11-15-10-35-21.bag'
  116. output_dir = output_mp4_dir
  117. # output_dir='/media/dell/BFAC-F22B'
  118. bag_name = input_dir.split('/')[-1].split('.')[0]
  119. output_dir = os.path.join(output_dir, bag_name + '_pcd_overlook' + '/pcd')
  120. if not os.path.exists(output_dir):
  121. os.makedirs(output_dir)
  122. with rosbag.Bag(input_dir, 'r') as bag:
  123. num_count = 0
  124. for topic, msg, t in bag.read_messages():
  125. if topic == "/points_concat": # /camera/depth/points # /scan_map_icp_amcl_node/scan_point_transformed
  126. num_count += 1
  127. bagtime = int(input_dir.split('/')[-1].split('.')[0].split('_')[-1])
  128. # hz = str(float(num_count / bagtime))
  129. hz = str(float(num_count) / bagtime)
  130. #######################解析rosbag中的点云point_concat话题,获得原始pcd文件#######################
  131. command = ['rosrun', 'pcl_ros', 'bag_to_pcd'] + [input_dir] + ['/points_concat'] + [output_dir]
  132. command = ' '.join(command)
  133. os.system(command)
  134. file1 = os.path.join(output_dir[0:-4], 'pcd_ascii')
  135. file2 = os.path.join(output_dir[0:-4], 'jpg')
  136. if not os.path.exists(file1):
  137. os.makedirs(file1)
  138. if not os.path.exists(file2):
  139. os.makedirs(file2)
  140. #######################将原始pcd文件转化成pcd-ascii格式,并生成jpg文件#######################
  141. for root, dirs, files in os.walk(output_dir[0:-4]):
  142. # find .pcd files and do the transfer twice
  143. for file in files:
  144. if "pcd" == root[-3:] and ".pcd" == file[-4:]:
  145. inputFilePath = root + "/" + file
  146. tempFilePath = root[:-3] + "pcd_ascii/" + file
  147. outputFilePath = root[:-3] + "jpg/" + file[:-3] + "jpg"
  148. # transfer pcd_utf-8 to pcd_ascii
  149. command = "pcl_convert_pcd_ascii_binary " + \
  150. inputFilePath + \
  151. " " + \
  152. tempFilePath + \
  153. " 0"
  154. # print(command)
  155. os.system(command)
  156. # make sure the temp file exist, invalid input file may cause this issue
  157. if not os.path.exists(tempFilePath):
  158. continue
  159. # transfer pcd_ascii to jpg
  160. pic = np.zeros([800, 1600, 3]) # pic = np.zeros([800, 1600, 3])
  161. draw_points(pic, tempFilePath)
  162. cv2.imwrite(outputFilePath, pic)
  163. # print("jpg generated: ", outputFilePath)
  164. else:
  165. break
  166. #######################将转化的点云jpg合成视频#######################
  167. jpg_list = os.listdir(file2)
  168. if not jpg_list == []:
  169. command = ['ffmpeg', '-f', 'image2', '-r', hz, '-pattern_type', 'glob', '-i'] + ['"jpg/*.jpg"'] + ['-tag:v',
  170. 'avc1',
  171. '-y'] + [
  172. 'pcd_overlook.mp4']
  173. # command = ['ffmpeg', '-f', 'image2', '-t', bagtime, '-pattern_type', 'glob', '-i'] + ['"jpg/*.jpg"'] + [
  174. # '-tag:v', 'avc1', '-y'] + ['pcd_overlook.mp4']
  175. result_string = " ".join(command)
  176. print '执行视频生成命令:%s' % result_string
  177. p = Popen(result_string, shell=True, cwd=output_dir[0:-4] + '/', stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  178. p.wait()
  179. shutil.rmtree(file1)
  180. shutil.rmtree(file2)
  181. shutil.rmtree(output_dir)
  182. return output_dir[0:-4]