pcdtovideo_jilong_forwardlook.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  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. f = open(filename, "r")
  18. ff = f.readlines()[11:]
  19. for i in range(0, len(ff)):
  20. point = ff[i].split()[:4]
  21. point_x = float(point[0])
  22. point_y = -float(point[1])
  23. if math.isnan(point_x):
  24. pass
  25. else:
  26. cv2.circle(pic, (int(200 - point_x * 10), int(100 - point_y * 10)), 1, (250, 250, 250), 2)
  27. def rotx(t):
  28. """Rotation about the x-axis."""
  29. c = np.cos(t)
  30. s = np.sin(t)
  31. return np.array([[1, 0, 0],
  32. [0, c, -s],
  33. [0, s, c]])
  34. def roty(t):
  35. """Rotation about the y-axis."""
  36. c = np.cos(t)
  37. s = np.sin(t)
  38. return np.array([[c, 0, s],
  39. [0, 1, 0],
  40. [-s, 0, c]])
  41. def rotz(t):
  42. """Rotation about the z-axis."""
  43. c = np.cos(t)
  44. s = np.sin(t)
  45. return np.array([[c, -s, 0],
  46. [s, c, 0],
  47. [0, 0, 1]])
  48. def transform_from_rot_trans(R, t):
  49. """Transforation matrix from rotation matrix and translation vector."""
  50. R = R.reshape(3, 3)
  51. t = t.reshape(3, 1)
  52. return np.vstack((np.hstack([R, t]), [0, 0, 0, 1]))
  53. def view(rx, ry, rz, tx, ty, tz):
  54. mx = rotx(rx)
  55. my = roty(ry)
  56. mz = rotz(rz)
  57. rotation = np.dot(mz, np.dot(my, mx))
  58. translation = np.array([tx, ty, tz])
  59. return transform_from_rot_trans(rotation, translation)
  60. # if __name__ == '__main__':
  61. # input_dir = sys.argv[1]
  62. # # input_dir='/media/dell/BFAC-F22B/data/jinlong_datareturn/test_1116/jinlong_data_merge_2023-12-13-05-59-34_TTC_7.bag'
  63. # output_dir = sys.argv[2]
  64. # # output_dir = '/media/dell/新加卷/样例及代码/金龙车/样例'
  65. # a = view(0, 30, 0, -10, 0, 5)
  66. # colormap = np.array([[128, 130, 120],
  67. # [235, 0, 205],
  68. # [0, 215, 0],
  69. # [235, 155, 0]]) / 255.0
  70. # bag_name = input_dir.split('/')[-1].split('.')[0]
  71. # output_dir = os.path.join(output_dir, bag_name + '_pcd_forwardlook' + '/pcd')
  72. # if not os.path.exists(output_dir):
  73. # os.makedirs(output_dir)
  74. # with rosbag.Bag(input_dir, 'r') as bag:
  75. # num_count = 0
  76. # for topic, msg, t in bag.read_messages():
  77. # if topic == "/points_concat": # /camera/depth/points # /scan_map_icp_amcl_node/scan_point_transformed
  78. # num_count += 1
  79. # bagtime = int(input_dir.split('/')[-1].split('.')[0].split('_')[-1])
  80. # hz = str(float(num_count) / bagtime)
  81. # #######################解析rosbag中的点云point_concat话题,获得原始pcd文件#######################
  82. # command = ['rosrun', 'pcl_ros', 'bag_to_pcd'] + [input_dir] + ['/points_concat'] + [output_dir]
  83. # command = ' '.join(command)
  84. # os.system(command)
  85. # file1 = os.path.join(output_dir[0:-4], 'pcd_ascii')
  86. # file2 = os.path.join(output_dir[0:-4], 'jpg')
  87. # if not os.path.exists(file1):
  88. # os.makedirs(file1)
  89. # if not os.path.exists(file2):
  90. # os.makedirs(file2)
  91. # #######################将原始pcd文件转化成pcd-ascii格式,并生成jpg文件#######################
  92. # for root, dirs, files in os.walk(output_dir[0:-4]):
  93. # # find .pcd files and do the transfer twice
  94. # for file in files:
  95. # if "pcd" == root[-3:] and ".pcd" == file[-4:]:
  96. # inputFilePath = root + "/" + file
  97. # tempFilePath = root[:-3] + "pcd_ascii/" + file
  98. # outputFilePath = root[:-3] + "jpg/" + file[:-3] + "jpg"
  99. # # transfer pcd_utf-8 to pcd_ascii
  100. # command = "pcl_convert_pcd_ascii_binary " + \
  101. # inputFilePath + \
  102. # " " + \
  103. # tempFilePath + \
  104. # " 0"
  105. # # print(command)
  106. # os.system(command)
  107. # # make sure the temp file exist, invalid input file may cause this issue
  108. # if not os.path.exists(tempFilePath):
  109. # continue
  110. # # transfer pcd_ascii to jpg
  111. # # pic = np.zeros([200, 400, 3]) #pic = np.zeros([800, 1600, 3])
  112. # # draw_points(pic, tempFilePath)
  113. # # cv2.imwrite(outputFilePath, pic)
  114. # # print("jpg generated: ", outputFilePath)
  115. # # pcd_path = "D:/文件/2-课题/科技部3.2/影子模式/pcd/data/pcd_ascii/1666841252.226625000.pcd"
  116. # pic = np.zeros([800, 1600, 3])
  117. # f = open(tempFilePath, "r")
  118. # ff = f.readlines()[11:]
  119. # for i in range(0, len(ff)):
  120. # point = ff[i].split()[:4]
  121. # point_x = float(point[0])
  122. # point_y = float(point[1])
  123. # point_z = float(point[2])
  124. # points_intensity = float(point[2])
  125. # t = np.dot(np.linalg.inv(a), np.array([point_x, point_y, point_z, 1]))
  126. # x = t[0]
  127. # y = t[1]
  128. # if math.isnan(point_x):
  129. # pass
  130. # else:
  131. # cv2.circle(pic, (int(800 - y * 40), int(400 - x * 40)), 0,
  132. # colormap[int(points_intensity) % colormap.shape[0]] * 255, 0)
  133. # cv2.imwrite(outputFilePath, pic)
  134. # else:
  135. # break
  136. # #######################将转化的点云jpg合成视频#######################
  137. # jpg_list = os.listdir(file2)
  138. # if not jpg_list == []:
  139. # command = ['ffmpeg', '-f', 'image2', '-r', hz, '-pattern_type', 'glob', '-i'] + ['"jpg/*.jpg"'] + ['-tag:v',
  140. # 'avc1',
  141. # '-y'] + [
  142. # 'pcd_forwardlook.mp4']
  143. # result_string = " ".join(command)
  144. # p = Popen(result_string, shell=True, cwd=output_dir[0:-4] + '/', stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  145. # p.wait()
  146. # shutil.rmtree(file1)
  147. # shutil.rmtree(file2)
  148. # shutil.rmtree(output_dir)
  149. def parse(input_bag_file, output_mp4_dir):
  150. input_dir = input_bag_file
  151. # input_dir='/media/dell/BFAC-F22B/bizhang_2023-11-15-10-35-21.bag'
  152. output_dir = output_mp4_dir
  153. # output_dir='/media/dell/BFAC-F22B'
  154. # output_dir = '/media/dell/新加卷/样例及代码/金龙车/样例'
  155. a = view(0, 30, 0, -10, 0, 5)
  156. colormap = np.array([[128, 130, 120],
  157. [235, 0, 205],
  158. [0, 215, 0],
  159. [235, 155, 0]]) / 255.0
  160. bag_name = input_dir.split('/')[-1].split('.')[0]
  161. output_dir = os.path.join(output_dir, bag_name + '_pcd_forwardlook' + '/pcd')
  162. if not os.path.exists(output_dir):
  163. os.makedirs(output_dir)
  164. with rosbag.Bag(input_dir, 'r') as bag:
  165. num_count = 0
  166. for topic, msg, t in bag.read_messages():
  167. if topic == "/points_concat": # /camera/depth/points # /scan_map_icp_amcl_node/scan_point_transformed
  168. num_count += 1
  169. bagtime = int(input_dir.split('/')[-1].split('.')[0].split('_')[-1])
  170. hz = str(float(num_count) / bagtime)
  171. #######################解析rosbag中的点云point_concat话题,获得原始pcd文件#######################
  172. command = ['rosrun', 'pcl_ros', 'bag_to_pcd'] + [input_dir] + ['/points_concat'] + [output_dir]
  173. command = ' '.join(command)
  174. os.system(command)
  175. file1 = os.path.join(output_dir[0:-4], 'pcd_ascii')
  176. file2 = os.path.join(output_dir[0:-4], 'jpg')
  177. if not os.path.exists(file1):
  178. os.makedirs(file1)
  179. if not os.path.exists(file2):
  180. os.makedirs(file2)
  181. #######################将原始pcd文件转化成pcd-ascii格式,并生成jpg文件#######################
  182. for root, dirs, files in os.walk(output_dir[0:-4]):
  183. # find .pcd files and do the transfer twice
  184. for file in files:
  185. if "pcd" == root[-3:] and ".pcd" == file[-4:]:
  186. inputFilePath = root + "/" + file
  187. tempFilePath = root[:-3] + "pcd_ascii/" + file
  188. outputFilePath = root[:-3] + "jpg/" + file[:-3] + "jpg"
  189. # transfer pcd_utf-8 to pcd_ascii
  190. command = "pcl_convert_pcd_ascii_binary " + \
  191. inputFilePath + \
  192. " " + \
  193. tempFilePath + \
  194. " 0"
  195. # print(command)
  196. os.system(command)
  197. # make sure the temp file exist, invalid input file may cause this issue
  198. if not os.path.exists(tempFilePath):
  199. continue
  200. # transfer pcd_ascii to jpg
  201. # pic = np.zeros([200, 400, 3]) #pic = np.zeros([800, 1600, 3])
  202. # draw_points(pic, tempFilePath)
  203. # cv2.imwrite(outputFilePath, pic)
  204. # print("jpg generated: ", outputFilePath)
  205. # pcd_path = "D:/文件/2-课题/科技部3.2/影子模式/pcd/data/pcd_ascii/1666841252.226625000.pcd"
  206. pic = np.zeros([800, 1600, 3])
  207. f = open(tempFilePath, "r")
  208. ff = f.readlines()[11:]
  209. for i in range(0, len(ff)):
  210. point = ff[i].split()[:4]
  211. point_x = float(point[0])
  212. point_y = float(point[1])
  213. point_z = float(point[2])
  214. points_intensity = float(point[2])
  215. t = np.dot(np.linalg.inv(a), np.array([point_x, point_y, point_z, 1]))
  216. x = t[0]
  217. y = t[1]
  218. if math.isnan(point_x):
  219. pass
  220. else:
  221. cv2.circle(pic, (int(800 - y * 40), int(400 - x * 40)), 0,
  222. colormap[int(points_intensity) % colormap.shape[0]] * 255, 0)
  223. cv2.imwrite(outputFilePath, pic)
  224. else:
  225. break
  226. #######################将转化的点云jpg合成视频#######################
  227. jpg_list = os.listdir(file2)
  228. if not jpg_list == []:
  229. command = ['ffmpeg', '-f', 'image2', '-r', hz, '-pattern_type', 'glob', '-i'] + ['"jpg/*.jpg"'] + ['-tag:v',
  230. 'avc1',
  231. '-y'] + [
  232. 'pcd_forwardlook.mp4']
  233. result_string = " ".join(command)
  234. p = Popen(result_string, shell=True, cwd=output_dir[0:-4] + '/', stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  235. p.wait()
  236. shutil.rmtree(file1)
  237. shutil.rmtree(file2)
  238. shutil.rmtree(output_dir)
  239. return output_dir[0:-4]