基于RealSense D435相机实现手部姿态重定向

news2024/11/18 20:24:01

基于Intel RealSense D435 相机和 MediaPipe的手部姿态检测,进一步简单实现手部姿态与机器人末端的重定向。
假设已经按照【基于 RealSenseD435i相机实现手部姿态检测】配置好所需的库和环境,并且有一个可以控制的机器人接口。

一、手部姿态重定向介绍

手部姿态重定向通常涉及将实时手部关键点映射到虚拟环境或另一个坐标系中(通常需要映射到机器人坐标系中)。可以使用以下步骤实现基本的手部姿态重定向:

  1. 获取关键点坐标:使用手部追踪库(如 MediaPipe)获取手部关键点的坐标。
    具体包括数据获取和手部特征识别。
    首先选择合适的相机,如RGB相机、深度相机(如Kinect或RealSense),或高帧率摄像头获取实时图像或深度数据;
    然后使用机器学习或深度学习算法(如YOLO、SSD等)检测图像中的手部,也可以使用现成的手部检测模型,例如MediaPipe Hands,来实现实时手部跟踪;
    最后提取手部的关键点信息,例如手指关节、掌心等。

  2. 定义目标坐标系:确定将手部姿态映射到哪个坐标系中,比如虚拟现实环境或者机器人坐标系。

  3. 姿态重定向:根据目标坐标系的需求,进行平移、旋转或缩放等变换。
    首先将2D图像坐标转换为3D空间坐标,通常需要相机内参(焦距、主点位置等),根据关键点位置计算手部的姿态(位置、方向、旋转);
    然后可以使用旋转矩阵、四元数等方式表示手部的姿态;最后将手部的当前姿态转换到机器人的目标姿态。

  4. 输出重定向后的姿态:将重定向后的坐标记录用于后续处理。

二、简单实现手部姿态与机器人末端的重定向

MediaPipe检测器可以准确定位腕部框架中21个手指关节坐标的3D关键点和图像上的2D关键点。

代码示例

import cv2
import numpy as np
import pyrealsense2 as rs
import mediapipe as mp
import time

# 初始化 RealSense 管道
pipeline = rs.pipeline()
config = rs.config()
config.enable_stream(rs.stream.color, 640, 480, rs.format.bgr8, 30)
config.enable_stream(rs.stream.depth, 640, 480, rs.format.z16, 30)
pipeline.start(config)

# 初始化 MediaPipe 手部模块
mp_hands = mp.solutions.hands
hands = mp_hands.Hands(max_num_hands=2, min_detection_confidence=0.7)
mp_draw = mp.solutions.drawing_utils

# 机器人控制函数(示例),具体需要根据需要通过逆解解算
def move_robot_to(position):
    # 在这里添加机器人控制代码
    print(f"移动机器人末端到位置: {position}")

try:
    while True:
        # 获取图像帧
        frames = pipeline.wait_for_frames()
        color_frame = frames.get_color_frame()

        if not color_frame:
            continue

        # 转换为 numpy 数组
        color_image = np.asanyarray(color_frame.get_data())
        
        # 将图像转换为 RGB 格式
        rgb_image = cv2.cvtColor(color_image, cv2.COLOR_BGR2RGB)
        rgb_image.flags.writeable = False

        # 检测手部
        results = hands.process(rgb_image)

        # 将图像转换回 BGR 格式
        rgb_image.flags.writeable = True
        annotated_image = cv2.cvtColor(rgb_image, cv2.COLOR_RGB2BGR)

        # 如果检测到手部
        if results.multi_hand_landmarks:
            for hand_landmarks in results.multi_hand_landmarks:
                # 绘制手部标记
                mp_draw.draw_landmarks(annotated_image, hand_landmarks, mp_hands.HAND_CONNECTIONS)

                # 获取手腕的位置(关节0)
                wrist = hand_landmarks.landmark[mp_hands.HandLandmark.WRIST]
                h, w, c = annotated_image.shape
                wrist_x, wrist_y = int(wrist.x * w), int(wrist.y * h)

                # 将手腕位置转换为机器人坐标,需要进行不同坐标系的位姿变换
                robot_position = (wrist_x, wrist_y)
                move_robot_to(robot_position)  # 移动机器人末端

        # 显示结果
        cv2.imshow('Hand Detection', annotated_image)

        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
finally:
    # 释放资源
    pipeline.stop()
    cv2.destroyAllWindows()

代码说明

  1. 初始化 RealSense 管道:设置相机流,并启动管道。
  2. 初始化 MediaPipe:配置手部检测模块。
  3. 实时捕获与处理:在循环中捕获视频帧,并检测手部姿态。
  4. 机器人控制:通过 move_robot_to 函数模拟移动机器人末端到手腕位置,需要根据自己的机器人接口实现具体的控制代码。
  5. 显示结果:在窗口中显示手部检测的图像,按 q 键退出。

运行代码

  1. 将代码保存为 hand_pose_robot.py

  2. 连接 Intel RealSense D435 相机。

  3. 在终端中运行代码:

    python hand_pose_robot.py
    

运行结果

在这里插入图片描述将 Intel RealSense D435 相机与 MediaPipe 的手部姿态检测整合在一起,可以实现手部姿态的实时检测,并将手腕的关键点转换为相机坐标系下的空间坐标。接下来,我们将编写一个完整的示例代码,进行手部关键点坐标到机器人坐标系的转换。

三、简单实现手腕与机器人末端的坐标转换

代码实现

以下是将 Intel RealSense D435 相机与 MediaPipe 手部姿态检测结合的完整代码示例:

import cv2
import mediapipe as mp
import numpy as np
import pyrealsense2 as rs

# 初始化MediaPipe手部模型
mp_hands = mp.solutions.hands
hands = mp_hands.Hands(static_image_mode=False, max_num_hands=1, min_detection_confidence=0.7)
mp_drawing = mp.solutions.drawing_utils

# 设置RealSense相机参数
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)

# 启动相机流
pipeline.start(config)

# 相机到机器人坐标系的转换矩阵(示例,需要根据实际情况调整)
camera_to_robot_transform = np.array([
    [1, 0, 0, 0],  # x轴
    [0, 1, 0, 0],  # y轴
    [0, 0, 1, 0],  # z轴
    [0, 0, 0, 1]   # 平移
])

def wrist_to_camera_coordinates(wrist_landmark, depth_frame):
    # 获取深度信息
    depth_value = depth_frame.get_distance(int(wrist_landmark.x * 640), int(wrist_landmark.y * 480))
    if depth_value == 0:
        return None  # 如果深度值为0,返回None

    # 计算空间坐标
    x = (wrist_landmark.x * 640 - 320) * depth_value / 525.0  # 525.0是相机焦距(可根据相机参数调整)
    y = (wrist_landmark.y * 480 - 240) * depth_value / 525.0
    z = depth_value

    return np.array([x, y, z])

def main():
    while True:
        # 获取相机帧
        frames = pipeline.wait_for_frames()
        color_frame = frames.get_color_frame()
        depth_frame = frames.get_depth_frame()

        if not color_frame or not depth_frame:
            continue
        
        # 转换为numpy数组
        frame = np.asanyarray(color_frame.get_data())

        # RGB转换
        frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
        results = hands.process(frame_rgb)

        if results.multi_hand_landmarks:
            for hand_landmarks in results.multi_hand_landmarks:
                # 提取手腕关键点
                wrist_landmark = hand_landmarks.landmark[mp_hands.HandLandmark.WRIST]

                # 转换为相机坐标系下的空间坐标
                wrist_coordinates = wrist_to_camera_coordinates(wrist_landmark, depth_frame)

                if wrist_coordinates is not None:
                    # 映射到机器人坐标系
                    robot_coordinates = camera_to_robot_transform @ np.append(wrist_coordinates, 1)  # 同质坐标转换
                    
                    # 打印机器人坐标
                    print(f"Wrist Coordinates (Camera): {wrist_coordinates}")
                    print(f"Wrist Coordinates (Robot): {robot_coordinates[:3]}")  # 只取x, y, z

                # 可视化手部关键点
                mp_drawing.draw_landmarks(frame, hand_landmarks, mp_hands.HAND_CONNECTIONS)

        cv2.imshow('Hand Tracking', frame)
        
        if cv2.waitKey(1) & 0xFF == 27:  # 按Esc退出
            break

    # 停止相机流
    pipeline.stop()
    cv2.destroyAllWindows()

if __name__ == "__main__":
    main()

代码说明

  • RealSense 相机设置:使用 pyrealsense2 库来设置和启动 RealSense D435 相机的流。代码配置了颜色流和深度流。

  • MediaPipe 手部姿态检测:使用 MediaPipe 检测手部关键点,特别是手腕的位置。

  • 手腕坐标转换wrist_to_camera_coordinates 函数根据手腕的关键点和深度图计算相机坐标系下的空间坐标。

  • 坐标转换:使用转换矩阵将相机坐标系下的手腕坐标转换到机器人坐标系。需要根据实际机器人和相机的位置关系调整 camera_to_robot_transform 矩阵。

  • 可视化和输出:代码在每帧中显示检测到的手部关键点,并输出手腕在相机坐标系和机器人坐标系下的坐标。

运行代码

  1. 将代码保存为 hand_pose_robot.py
  2. 连接 Intel RealSense D435 相机。
  3. 在终端中运行代码:
python hand_pose_robot.py

运行结果

Wrist Coordinates (Camera): [0.04378617 0.0835716  0.58400005]
Wrist Coordinates (Robot): [ 0.04378617 -0.0835716   0.58400005]

调整与测试

在实际应用中,可能需要:

  • 根据 RealSense 相机的参数调整坐标转换公式。
  • 调整机器人坐标系的转换矩阵,以匹配相机与机器人之间的实际位置关系。
  • 增强代码的鲁棒性,处理深度数据的缺失情况。

四、总结

确保环境中已经安装了相关库,并且相机正常工作。运行后,窗口中将显示实时的手部检测结果,同时机器人末端会根据手腕位置进行重定向。可以实时监测手部动作并将其坐标转换为机器人坐标系,进而实现对机器人的控制。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2166616.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

18924 二叉树的宽度

### 思路 1. 使用广度优先搜索(BFS)遍历二叉树,记录每一层的节点数。 2. 使用队列来实现BFS,队列中存储节点和其对应的层数。 3. 在遍历过程中,更新每一层的节点数,并记录最大节点数。 ### 伪代码 1. 定义…

uni-app - - - - -vue3使用i18n配置国际化语言

uni-app - - - - -使用i18n配置国际化语言 1. 安装vue-i18n2. 配置文件2.1 创建如下文件2.2 文件配置2.3 main文件导入i18n 3. 页面内使用3.1 template内直接使用3.2 变量接收使用 1. 安装vue-i18n npm install vue-i18n --save2. 配置文件 2.1 创建如下文件 locales文件夹里…

__has_include 报错

作用: 在C或C的预处理阶段,__has_include 是一个编译器特定的宏,主要用于检查编译器是否能够包含指定的头文件。这个宏在Clang和GCC(从某个版本开始)等编译器中可用,但在所有编译器中可能并不都支持…

气膜乒乓球馆的前景展望—轻空间

乒乓球作为我国的国球,在全球范围内始终保持领先地位,不仅是国民心中的重要运动,也在国际舞台上占据了举足轻重的地位。气膜乒乓球馆作为一种创新的体育设施,通过结合先进的气膜技术与传统乒乓球运动,为爱好者提供了一…

Heart Animated 写实心脏模型素材带动画医学

心脏动画: 解剖细节逼真的心脏。 此资源包含高质量着色全色HD中的所有纹理,并使用HD中的凹凸贴图(NORMALMASP)。所有Prefab Ready均适用于游戏、应用程序和VR应用程序。预制件已准备好位置和旋转0,0,0。拖动到场景时。 还具有完整的心动周期。 Tris=约81 k。 顶点=约51 k …

关于如何使用终端查看类的布局教程

在继承章节我们使用了vs提供的终端查看类之间的继承模型,在后续多态的学习过程中,我们也将继续使用该方法去查看虚表等信息。 第一步:打开VS提供的终端窗口: 第二步:获取需要查看的类所在的源文件的地址: …

TypeScript 设计模式之【迭代器模式】

文章目录 迭代器模式:优雅遍历集合的智能书签迭代器模式的奥秘迭代器模式有什么利与弊?如何使用迭代器模式来优化你的数据遍历代码实现案例迭代器模式的主要优点迭代器模式的主要缺点迭代器模式的适用场景总结 迭代器模式:优雅遍历集合的智能书签 你是…

运维工具之adb命令安装和使用

一、adb命令简介 ADB(Android Debug Bridge)是 Android 开发者工具包中的一个命令行工具,主要用于在开发、调试和测试 Android 应用时与 Android 设备进行交互。通过 ADB 工具,开发者和用户可以从电脑对 Android 设备执行各种操作…

md编辑器语法

这里写自定义目录标题 欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants 创建一个自定义列表如何创建一个…

【递归】5.leetcode 872 叶子相似的树

1 题目描述 题目链接:叶子相似的树 2 解答思路 递归分为三步,接下来就按照这三步来思考问题 第一步:挖掘出相同的子问题 (关系到具体函数头的设计) 第二步:只关心具体子问题做了什么 (关…

Swoole的多进程模块

Swoole是有自己的一个进程管理模块,用来替代PHP的pcntl扩展,需要注意Process进程在系统是非常昂贵的资源,创建进程消耗很大,另外创建的进程过多会导致进程切换开销大幅上升。 为什么不使用pcntl 1.pcntl没有提供进程间通信的功能…

AI智能眼镜_带摄像头的AI智能眼镜,AI大模型落地的载体

随着科技的迅猛发展,AI智能眼镜汇聚了众多硬件的优势,成为现代生活中不可或缺的一部分。这种创新设备不仅内嵌了耳机、摄像头以及WiFi和蓝牙模块等核心硬件,还具备了音频播放、图像拍摄和无线通信等多种功能,极大地提升了信息获取…

深度学习经典模型之BERT(上)

深度学习经典模型之BERT(下) BERT(Bidirectional Encoder Representations from Transformers)是一个双向transformer编码器的言表示模型。来自论文:BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding 。由Google公司的…

【WRF运行第二期(Ubuntu)】ARWpost安装及错误总结

WRF运行第二期:ARWpost安装及错误总结 1 ARWpost介绍2 ARWpost安装2.1 ARWpost_V3安装前准备2.2 安装ARWpost2.3 修改Makefile文件2.4 修改configure.arwp文件2.5 生成可执行文件EXE另:报错1-Error: Type mismatch between actual argument at (1) and a…

计算物理精解【3】- FORTRAN计算

文章目录 概述hello,world环境接收输入与输出 读取csv文件if and select case循环formatread,write formatread,write读写文件录入与读取数据文件定位csv 数组一维数组最小二乘法下标隐式循环 关系代数基本运算笛卡尔积投影选择 过程参数select case 和 过程module快排函数自定…

深度学习自编码器 - 分布式表示篇

序言 深度学习作为人工智能领域的重要分支,其核心在于表示学习( Representation Learning \text{Representation Learning} Representation Learning),尤其是分布式表示( Distributed Representation \text{Distribut…

【JUC并发编程系列】深入理解Java并发机制:高效并发背后的守护者(八、线程池的秘密)

文章目录 【JUC并发编程系列】深入理解Java并发机制:高效并发背后的守护者(八、线程池的秘密)1. 线程池基础知识1.1 什么是线程池1.2 为什么要使用线程池1.3 线程池使用场景1.4 线程池有哪些作用 2. 线程池基本用法2.1 线程池的创建方式2.2 线程池底层是如何实现复用…

前端vuex

需要共享的数据适合存储到vuex中 state基本使用 如果开启strict严格模式,直接修改上图的age会报错提示。不能在组件中直接修改state

“永辉优品”会是中国零售的答案吗?

投资者这么快就“看懂”名创优品的豪赌了? 9月25日,永辉超市继续一字涨停,而令人意外的是,名创优品也反弹近8%。 随着名创优品于9月23日晚间在港交所公告,以62.7亿人民币收购永辉超市29.4%的股权,两家公司…

数据科学的核心工具箱:全面解析pandas、matplotlib.pyplot与scipy.stats在复杂数据分析流程中的应用

在当今数据驱动的世界中,Python已成为数据分析和科学计算的首选语言。 而 pandas 、 matplotlib.pyplot 和 scipy.stats 这三个库则是数据科学家和分析师武器库中 的三把利剑。 1. pandas 数据处理的瑞士军刀 pandas 库是 Python数据分析 的基石,它…