代码如下:

#!/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/

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

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐