8.1 同时打开摄像头和获取点云数据(python)
·
代码如下:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# coding:utf-8
import cv2
import rospy
from sensor_msgs.msg import PointCloud2
import sensor_msgs.point_cloud2 as pc2
from std_msgs.msg import Header
from visualization_msgs.msg import Marker, MarkerArray
from geometry_msgs.msg import Point
#import torch
import numpy as np
import sys
import time,datetime
print(sys.version)
#from recon_barriers_model import recon_barriers
#from pclpy import pcl
from queue import Queue
import open3d as o3d
import matplotlib
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
#%matplotlib
from create_date_file import data_time
import threading
cap = cv2.VideoCapture("/dev/video61")
#1.聚类的数据处理
def cluster(points, radius=0.2):
"""
points: pointcloud
radius: max cluster range
"""
items = []
while len(points)>1:
item = np.array([points[0]])
base = points[0]
points = np.delete(points, 0, 0)
distance = (points[:,0]-base[0])**2+(points[:,1]-base[1])**2+(points[:,2]-base[2])**2
infected_points = np.where(distance <= radius**2)
item = np.append(item, points[infected_points], axis=0)
border_points = points[infected_points]
points = np.delete(points, infected_points, 0)
while len(border_points) > 0:
border_base = border_points[0]
border_points = np.delete(border_points, 0, 0)
border_distance = (points[:,0]-border_base[0])**2+(points[:,1]-border_base[1])**2
border_infected_points = np.where(border_distance <= radius**2)
item = np.append(item, points[border_infected_points], axis=0)
border_points = points[border_infected_points]
points = np.delete(points, border_infected_points, 0)
items.append(item)
return items
#2.保存点云
def save_pointcloud(pointcloud_np, file_name="pointcloud.pcd"):
point_cloud_o3d = o3d.geometry.PointCloud()
point_cloud_o3d.points = o3d.utility.Vector3dVector(pointcloud_np[:, 0:3])
o3d.io.write_point_cloud(file_name, point_cloud_o3d, write_ascii=False, compressed=True)
#3.点云数据的处理
def lidars(msg,pcd_path):
#4.点云数据的获取
pcl_msg = pc2.read_points(msg, skip_nans=False, field_names=(
"x", "y", "z", "intensity","ring"))
#print(type(pcl_msg))
#5.点云数据的过滤
np_p_2 = np.array(list(pcl_msg), dtype=np.float32)
print(np_p_2.shape)
#6.将过滤后的点云数据保存为pcd文件
print(pcd_path)
save_pointcloud(np_p_2, file_name=pcd_path)
#7.根据条件过滤点云数据
ss=np.where([s[0]>2 and s[1]<3 and s[-1]>-3 and s[2]>-0.5 for s in np_p_2])
ans=np_p_2[ss]
#print("----->",ans.shape)
#8.点云的聚类算法
item=cluster(ans, radius=0.2)
m_item=[]
#9.求每个类的均值,之后与目标进行匹配
for items in item:
#print("..............",items.shape)
#x,y,z=int(items[:,:1].sum().mean())
x,y,z,r=items[:,:1].mean(),items[:,1:2].mean(),items[:,2:3].mean(),items[:,3:4].mean()
m_item.append([x,y,z])
def images(frame,jpg_path):
#1.保存jpg文件
cv2.imwrite(jpg_path,frame)
def velo_callback(msg):
#1.自动生成当天保存文件的文件夹及保存文件的路径
#img_file:存放图片的路径(jpg或者png文件)
#vedios:存放相机视频的路径(mp4文件)
#lidar_videos:存放雷达视频的路径(bag文件)
#lidar_pcd:存放点云数据的pcd文件的视频(pcd文件)
img_file,vedios,lidar_videos,lidar_pcd=data_time(root_path="img_lidar_save/")
vedio_time=day_time()
vedio_path=vedios+"/"+vedio_time+".mp4"
lidar_path=lidar_videos+"/"+vedio_time+".bag"
print(vedio_path)
print(lidar_path)
#2.打开相机
#cap = cv2.VideoCapture("/dev/video61")
#while (cap.isOpened()):
if (cap.isOpened()):
ret, frame = cap.read()
frame = cv2.rotate(frame, 0, dst=None) # 视频是倒着的,要对视频进行两次90度的翻转
frame = cv2.rotate(frame, 0, dst=None) # 视频是倒着的,要对视频进行两次90度的翻转
cv2.imshow("src_image", frame)
cv2.waitKey(1)
#3.获取实时时间,作为保存jpg和pcd文件的名称
now_time=day_time()
print("------>",now_time)
#4.获得存取pcd文件和jpg文件的路径
pcd_path=lidar_pcd+"/"+now_time+".pcd"
jpg_path=img_file+"/"+now_time+".jpg"
#4.lidar和images数据的处理及保存,两个函数放在两个线程同时运行
lidars(msg,pcd_path)#lidar数据的处理及保存
images(frame,jpg_path)#images数据的处理及保存
#根据时间给jpg和pcd文件命名
def day_time():
start_time=datetime.datetime.now().strftime(f'%Y-%m-%d %H:%M:%S{r".%f"}')
times=start_time.split(" ")
mins=times[1].split(":")
day_names=mins[0]+"_"+mins[1]+"_"+mins[2][:2]+"_"+mins[2][3:5]
return day_names
if __name__ == '__main__':
# code added for using ROS
#global max_marker_size_,frequence
#cap = cv2.VideoCapture("/dev/video61")
#q = Queue()
#q.put(None)
rospy.init_node('lidar_node')
sub_ = rospy.Subscriber("livox/lidar", PointCloud2,
velo_callback)#, queue_size=10
#pub_arr_bbox = rospy.Publisher(
#"visualization_marker", MarkerArray)#, queue_size=10
print("ros_node has started!")
rospy.spin()
加入自动存储视频的代码如下(速度比上面慢很多):
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# coding:utf-8
import cv2
import rospy
from sensor_msgs.msg import PointCloud2
import sensor_msgs.point_cloud2 as pc2
from std_msgs.msg import Header
from visualization_msgs.msg import Marker, MarkerArray
from geometry_msgs.msg import Point
#import torch
import numpy as np
import sys
import time,datetime
print(sys.version)
#from recon_barriers_model import recon_barriers
#from pclpy import pcl
from queue import Queue
import open3d as o3d
import matplotlib
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
#%matplotlib
#from create_date_file import data_time
import threading
import time,datetime
import os
#2.打开相机
cap = cv2.VideoCapture("/dev/video61")
#1.根据时间自动创建文件夹
def data_time(root_path="img_lidar_save/"):
# 1.鑾峰彇褰撳墠鏃堕棿瀛楃涓叉垨鏃堕棿鎴筹紙閮藉彲绮剧‘鍒板井绉掞級
start_time=datetime.datetime.now().strftime(f'%Y-%m-%d %H:%M:%S{r".%f"}')
times=start_time.split(" ")
# 2.data_files锛氭牴鎹棩鏈熻幏鍙栬鍒涘缓鐨勬枃浠跺す鍚嶇О锛屾瘮濡備粖澶╂槸2023_12_07
data_files=times[0]
#3.鑾峰彇鏂囦欢澶硅矾寰勶細img_lidar_save/2023_12_07
file_path=root_path+data_files
camera_file = file_path + "/" + "camera_data"
lidar_file = file_path + "/" + "lidar_data"
#4.濡傛灉浠婂ぉ杩樻病鏈夋枃浠跺す锛屽垯鍒涘缓鏂囦欢澶?鏂囦欢澶瑰悕绉颁负 2023_12_07
if not os.path.exists(file_path):
os.makedirs(file_path)
#5.寤虹珛camera鍜宭idar鏂囦欢澶癸紝瀛樺彇鍚勮嚜鐨勬暟鎹?
if not os.path.exists(camera_file):
os.makedirs(camera_file)
if not os.path.exists(lidar_file):
os.makedirs(lidar_file)
#6.寤虹珛鍚勮嚜鐨勫瓨鍙栧浘鐗囧拰瑙嗛鐨勬枃浠跺す
img_file=camera_file+ "/" +"image"
vedios=camera_file+ "/" +"vedios"
lidar_videos=lidar_file +"/" +"vedios"
lidar_pcd=lidar_file +"/" +"image"
if not os.path.exists(img_file):
os.makedirs(img_file)
if not os.path.exists(vedios):
os.makedirs(vedios)
if not os.path.exists(lidar_videos):
os.makedirs(lidar_videos)
if not os.path.exists(lidar_pcd):
os.makedirs(lidar_pcd)
return img_file,vedios,lidar_videos,lidar_pcd
#1.聚类的数据处理
def cluster(points, radius=0.2):
"""
points: pointcloud
radius: max cluster range
"""
items = []
while len(points)>1:
item = np.array([points[0]])
base = points[0]
points = np.delete(points, 0, 0)
distance = (points[:,0]-base[0])**2+(points[:,1]-base[1])**2+(points[:,2]-base[2])**2
infected_points = np.where(distance <= radius**2)
item = np.append(item, points[infected_points], axis=0)
border_points = points[infected_points]
points = np.delete(points, infected_points, 0)
while len(border_points) > 0:
border_base = border_points[0]
border_points = np.delete(border_points, 0, 0)
border_distance = (points[:,0]-border_base[0])**2+(points[:,1]-border_base[1])**2
border_infected_points = np.where(border_distance <= radius**2)
item = np.append(item, points[border_infected_points], axis=0)
border_points = points[border_infected_points]
points = np.delete(points, border_infected_points, 0)
items.append(item)
return items
#2.保存点云
def save_pointcloud(pointcloud_np, file_name="pointcloud.pcd"):
point_cloud_o3d = o3d.geometry.PointCloud()
point_cloud_o3d.points = o3d.utility.Vector3dVector(pointcloud_np[:, 0:3])
o3d.io.write_point_cloud(file_name, point_cloud_o3d, write_ascii=False, compressed=True)
#3.点云数据的处理
def lidars(msg,pcd_path):
#4.点云数据的获取
pcl_msg = pc2.read_points(msg, skip_nans=False, field_names=(
"x", "y", "z", "intensity","ring"))
#5.点云数据的过滤
np_p_2 = np.array(list(pcl_msg), dtype=np.float32)
#print(np_p_2)
#6.将过滤后的点云数据保存为pcd文件
#print(pcd_path)
save_pointcloud(np_p_2, file_name=pcd_path)
#7.根据条件过滤点云数据
ss=np.where([s[0]>2 and s[1]<3 and s[-1]>-3 and s[2]>-0.5 for s in np_p_2])
ans=np_p_2[ss]
#8.点云的聚类算法
item=cluster(ans, radius=0.2)
m_item=[]
#9.求每个类的均值,之后与目标进行匹配
#hh=np.where([s.shape[0]>20 for s in item])
#print("//////////////",len(hh),len(item))
for items in item:
#print("..............",items.shape)
#x,y,z=int(items[:,:1].sum().mean())
x,y,z,r=items[:,:1].mean(),items[:,1:2].mean(),items[:,2:3].mean(),items[:,3:4].mean()
m_item.append([x,y,z])
#4.相机图片数据的处理
def images(frame,jpg_path):
#1.保存jpg文件
cv2.imwrite(jpg_path,frame)
#5.对相机图片和点云数据的汇总处理
def velo_callback(msg):
#1.自动生成当天保存文件的文件夹及保存文件的路径
#img_file:存放图片的路径(jpg或者png文件)
#vedios:存放相机视频的路径(mp4文件)
#lidar_videos:存放雷达视频的路径(bag文件)
#lidar_pcd:存放点云数据的pcd文件的视频(pcd文件)
img_file,vedios,lidar_videos,lidar_pcd=data_time(root_path="img_lidar_save/")
vedio_time=day_time()
vedio_path=vedios+"/"+vedio_time+".avi"
lidar_path=lidar_videos+"/"+vedio_time+".bag"
#print(vedio_path)
#print(lidar_path)
#创建窗口
cv2.namedWindow('window')
fps = 10
size=(int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)),int(cap.get(cv2 .CAP_PROP_FRAME_HEIGHT)))
videoWriter=cv2.VideoWriter(vedio_path,cv2.VideoWriter_fourcc('X','V','I','D'),fps,size)
#while (cap.isOpened()):
ret, frame = cap.read()
frame = cv2.rotate(frame, 0, dst=None) # 视频是倒着的,要对视频进行两次90度的翻转
frame = cv2.rotate(frame, 0, dst=None) # 视频是倒着的,要对视频进行两次90度的翻转
#写入视频
videoWriter.write(frame)
cv2.imshow('window', frame)
#显示视频
cv2.imshow("src_image", frame)
cv2.waitKey(1)
#3.获取实时时间,作为保存jpg和pcd文件的名称
now_time=day_time()
print("------>",now_time)
#4.获得存取pcd文件和jpg文件的路径
pcd_path=lidar_pcd+"/"+now_time+".pcd"
jpg_path=img_file+"/"+now_time+".jpg"
#4.lidar和images数据的处理及保存,两个函数放在两个线程同时运行
lidars(msg,pcd_path)#lidar数据的处理及保存
images(frame,jpg_path)#images数据的处理及保存
cv2.destroyWindow('window')
cap.release()
#根据时间给jpg和pcd文件命名
def day_time():
start_time=datetime.datetime.now().strftime(f'%Y-%m-%d %H:%M:%S{r".%f"}')
times=start_time.split(" ")
mins=times[1].split(":")
day_names=mins[0]+"_"+mins[1]+"_"+mins[2][:2]+"_"+mins[2][3:5]
return day_names
if __name__ == '__main__':
rospy.init_node('lidar_node')
sub_ = rospy.Subscriber("livox/lidar", PointCloud2,
velo_callback)
print("ros_node has started!")
rospy.spin()
这个是比较完整的存取jpg和pcd文件的代码,效果如下:
1./home/rpdzkj/livox/src/img_lidar_save/2024-01-24/lidar_data/image/

2./home/rpdzkj/livox/src/img_lidar_save/2024-01-24/camera_data/image/

3./home/rpdzkj/livox/src/img_lidar_save/2024-01-24/camera_data/vedios/

通过以上两个图片可知,我们首先获得实时的时间,然后根据时间命名,分别保存点云数据和摄像头的图片数据。后续的处理考虑将点云的和图片的函数用线程或者进程作并行处理。
更多推荐
所有评论(0)