import pyrealsense2 as rs import numpy as np import cv2 import os import time import paramiko from datetime import datetime # 服务器配置 - 请根据实际情况修改 SERVER_CONFIG = { 'host': '10.103.69.239', # 服务器IP地址 'port': 27277, # SSH端口,通常为22 'username': 'chubin', # 用户名 'password': 'ZQSg7YOAeCqGPRky=Aa0#', # 密码 'remote_dir': '/mnt/disk_3/chubin/img/' # 服务器上的目标文件夹 } def configure_camera(): # 配置摄像头管道 pipeline = rs.pipeline() config = rs.config() # 配置数据流 config.enable_stream(rs.stream.depth, 640, 480, rs.format.z16, 30) config.enable_stream(rs.stream.color, 640, 480, rs.format.bgr8, 30) # 启动摄像头 profile = pipeline.start(config) # 获取深度传感器的深度比例 depth_sensor = profile.get_device().first_depth_sensor() depth_scale = depth_sensor.get_depth_scale() print(f"深度比例系数为: {depth_scale}") # 创建对齐对象 align_to = rs.stream.color align = rs.align(align_to) return pipeline, align, profile def create_video_writer(width, height, fps=30): """创建视频写入器,用于保存彩色和深度视频""" # 创建保存视频的文件夹 if not os.path.exists("videos"): os.makedirs("videos") # 生成带时间戳的文件名 timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") color_filename = f"videos/color_{timestamp}.avi" depth_filename = f"videos/depth_{timestamp}.avi" # 定义编码器和创建VideoWriter对象 fourcc = cv2.VideoWriter_fourcc(*'XVID') color_out = cv2.VideoWriter(color_filename, fourcc, fps, (width, height)) depth_out = cv2.VideoWriter(depth_filename, fourcc, fps, (width, height)) # 检查视频写入器是否成功创建 if not color_out.isOpened(): raise Exception(f"无法创建彩色视频文件: {color_filename}") if not depth_out.isOpened(): raise Exception(f"无法创建深度视频文件: {depth_filename}") print(f"视频将保存到:") print(f" 彩色视频: {color_filename}") print(f" 深度视频: {depth_filename}") return color_out, depth_out def create_sftp_connection(server_config): """创建并返回SSH和SFTP连接对象""" try: # 创建SSH客户端 ssh = paramiko.SSHClient() # 自动添加未知的主机密钥 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # 连接服务器 ssh.connect( server_config['host'], port=server_config['port'], username=server_config['username'], password=server_config['password'] ) # 创建SFTP客户端 sftp = ssh.open_sftp() # 检查远程目录是否存在,不存在则创建 try: sftp.stat(server_config['remote_dir']) except FileNotFoundError: sftp.mkdir(server_config['remote_dir']) print(f"已创建远程目录: {server_config['remote_dir']}") print("SFTP连接已建立") return ssh, sftp except Exception as e: print(f"创建SFTP连接时发生错误: {e}") # 如果连接失败,确保释放资源 if 'ssh' in locals(): ssh.close() raise # 重新抛出异常,让调用者知道连接失败 def upload_to_server(sftp, local_path, remote_path): """通过已建立的SFTP连接上传文件""" try: # 上传文件 sftp.put(local_path, remote_path) print(f"文件 {local_path} 已成功上传到 {remote_path}") return True except Exception as e: print(f"上传文件时发生错误: {e}") return False def main(): # 初始化变量 ssh = None sftp = None pipeline = None color_out = None depth_out = None try: # 配置摄像头 pipeline, align, profile = configure_camera() # 获取实际视频尺寸 color_stream = profile.get_stream(rs.stream.color) video_profile = color_stream.as_video_stream_profile() width, height = video_profile.width(), video_profile.height() # 创建视频写入器 color_out, depth_out = create_video_writer(width, height) # 创建临时保存截图的文件夹 if not os.path.exists("captures"): os.makedirs("captures") # 建立SFTP连接 ssh, sftp = create_sftp_connection(SERVER_CONFIG) print("正在录制视频... 按 's' 停止录制,按 'q' 退出程序") recording = True last_capture_time = 0 # 上次截图时间 capture_interval = 5 # 截图间隔(秒) # 创建显示窗口 cv2.namedWindow('RealSense - 彩色 (左) | 深度 (右)', cv2.WINDOW_AUTOSIZE) while True: # 等待获取一帧数据 frames = pipeline.wait_for_frames() # 对齐深度帧到彩色帧 aligned_frames = align.process(frames) # 获取对齐后的深度帧和彩色帧 aligned_depth_frame = aligned_frames.get_depth_frame() color_frame = aligned_frames.get_color_frame() # 验证两个帧都有效 if not aligned_depth_frame or not color_frame: continue # 将图像转换为numpy数组 depth_image = np.asanyarray(aligned_depth_frame.get_data()) color_image = np.asanyarray(color_frame.get_data()) # 应用深度颜色映射 depth_colormap = cv2.applyColorMap(cv2.convertScaleAbs(depth_image, alpha=0.03), cv2.COLORMAP_JET) # 显示录制状态 if recording: cv2.putText(color_image, "REC", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2) cv2.putText(depth_colormap, "REC", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2) # 保存视频帧 if recording: color_out.write(color_image) depth_out.write(depth_colormap) # 检查是否到了截图时间 current_time = time.time() if current_time - last_capture_time >= capture_interval: # 生成带时间戳的截图文件名 timestamp = datetime.now().strftime("%Y%m%d_%H%M%S_%f") color_capture_path = f"captures/color_capture_{timestamp}.jpg" depth_capture_path = f"captures/depth_capture_{timestamp}.jpg" # 保存截图 cv2.imwrite(color_capture_path, color_image) cv2.imwrite(depth_capture_path, depth_colormap) print(f"已保存截图: {color_capture_path}, {depth_capture_path}") # 上传到服务器 if recording and sftp is not None: # 只有在录制状态且连接有效才上传 remote_color_path = os.path.join(SERVER_CONFIG['remote_dir'], f"color_capture_{timestamp}.jpg") remote_depth_path = os.path.join(SERVER_CONFIG['remote_dir'], f"depth_capture_{timestamp}.jpg") # 上传文件 color_success = upload_to_server(sftp, color_capture_path, remote_color_path) depth_success = upload_to_server(sftp, depth_capture_path, remote_depth_path) # 上传成功后删除本地文件 if color_success: os.remove(color_capture_path) if depth_success: os.remove(depth_capture_path) # 更新上次截图时间 last_capture_time = current_time # 显示图像 cv2.imshow('RealSense - 彩色 (左) | 深度 (右)', np.hstack((color_image, depth_colormap))) # 处理按键事件 key = cv2.waitKey(1) if key & 0xFF == ord('q'): # 按q退出程序 break elif key & 0xFF == ord('s'): # 按s暂停/继续录制 recording = not recording status = "继续录制" if recording else "暂停录制" print(status) except Exception as e: print(f"发生错误: {e}") finally: # 确保SFTP连接关闭 if sftp is not None: try: sftp.close() print("SFTP连接已关闭") except Exception as e: print(f"关闭SFTP连接时发生错误: {e}") # 确保SSH连接关闭 if ssh is not None: try: ssh.close() print("SSH连接已关闭") except Exception as e: print(f"关闭SSH连接时发生错误: {e}") # 释放视频写入器资源 if color_out is not None: color_out.release() if depth_out is not None: depth_out.release() # 停止摄像头 if pipeline is not None: pipeline.stop() # 关闭所有OpenCV窗口 cv2.destroyAllWindows() print("视频录制已结束,文件已保存。") if __name__ == "__main__": main()