服务机器人无接触手势交互控制系统开发

发布时间:2026/8/18 11:06:59

服务机器人无接触手势交互控制系统开发
服务机器人无接触手势交互控制系统开发无接触手势交互是新一代商用服务机器人主流人机交互方案广泛应用于商场导购、养老陪护、政务大厅引导机器人无需物理触控即可调节语音播报音量、切换交互模式;基于视觉手势关键点识别开发无接触控制程序是服务机器人应用技术员人机交互模块开发核心工作内容要求实现手势距离与机器人语音输出参数线性映射保障机器人面向老人、儿童等群体交互流畅稳定。任务四:机器人手势无接触音量交互控制系统开发本任务基于实验箱外接摄像头通过识别拇指与食指指尖的距离线性映射为系统音量大小实现“手势滑动调节灯光”功能具体要求如下:1.调用外接摄像头在窗口内实时显示画面、手掌关键点(带连接线条)、拇指与食指指尖标记(紫色圆点)及两点连线(紫色线条)。2.手势控制逻辑:识别手掌关键点提取拇指指尖和食指指尖的像素坐标;利用勾股定理计算两点距离将距离范围[50300]线性映射为系统RGB灯光亮度(0%-100%);距离越远灯光越亮;距离越近灯光越暗实时同步调节。3.实时显示信息:窗口左下角显示灯光亮度百分比(格式:XX%字体大小30颜色蓝色);窗口左侧显示亮度进度条(蓝色矩形高度随音量变化);窗口左上角显示帧率(格式:FPS:XX字体大小30颜色蓝色)。4.程序稳定性:手掌识别准确率≥80%无频繁误触发;按下“ESC”键可正常退出程序释放摄像头及系统资源。创建名为04.py的文件存储至任务一的文件夹中现场演示并验证功能。程序如下导入试验箱RGB灯环驱动模块用来控制硬件LED灯环from exboard import RGB导入OpenCV计算机视觉库负责摄像头读取、图像处理、绘图操作import cv2导入numpy数值运算库用于数组、阈值矩阵、数学运算import numpy as np导入时间库用来计算画面帧率FPSimport time 【步骤1全局参数初始化】 设置摄像头设备编号为0选用本机0号USB摄像头CAM_ID 0拇指食指之间最小触发像素距离小于该距离亮度归零MIN_DIST 50拇指食指之间最大有效像素距离超过之后亮度达到最大值MAX_DIST 300计算有效识别距离区间的总跨度DIST_RANGE MAX_DIST - MIN_DISTOpenCV颜色定义颜色顺序为BGR紫色 (B255,G0,R255)PURPLE (255, 0, 255)蓝色 (B255,G0,R0)用于进度条、文字BLUE (255, 0, 0)灰色亮度进度条外框底色GRAY_COLOR (80, 80, 80)创建RGB灯环硬件实例rgb RGB()初始化24颗LED全部设置为黑色熄灭状态rgb.set([(0, 0, 0)] * 24)上一帧的时间戳用来计算每秒帧数prev_time 0HSV颜色空间下肤色下限阈值LOWER_SKIN np.array([0, 10, 60], np.uint8)HSV颜色空间下肤色上限阈值UPPER_SKIN np.array([25, 255, 255], np.uint8)手掌轮廓长宽比上限超过该数值判定为长条手臂轮廓直接舍弃MAX_HAND_RATIO 1.5手掌轮廓最小像素面积过滤微小噪点产生的无效轮廓MIN_HAND_AREA 1500 【步骤2封装工具函数】 def get_hand_contour(origin_frame):“”肤色分割 长宽比过滤只识别手掌、过滤长条手臂:param origin_frame: 原始BGR图像:return: 手部轮廓找不到返回None“”# 将BGR格式原图转换至HSV色彩空间方便进行肤色筛选hsv cv2.cvtColor(origin_frame, cv2.COLOR_BGR2HSV)# 根据肤色阈值生成二值掩码肤色区域变为白色其余区域黑色skin_mask cv2.inRange(hsv, LOWER_SKIN, UPPER_SKIN)# 高斯模糊处理掩码平滑画面、消除细小噪点skin_mask cv2.GaussianBlur(skin_mask, (7, 7), 0)# 创建3*3大小的卷积核用于形态学处理kernel np.ones((3, 3), np.uint8)# 闭运算先膨胀再腐蚀填补肤色掩码内部细小的空洞skin_mask cv2.morphologyEx(skin_mask, cv2.MORPH_CLOSE, kernel)# 开运算先腐蚀再膨胀清除画面外面零散的白色噪点skin_mask cv2.morphologyEx(skin_mask, cv2.MORPH_OPEN, kernel)# 查找掩码图像当中所有最外层的物体轮廓 contours, _ cv2.findContours(skin_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # 如果没有检测出来任何轮廓直接返回空值 if len(contours) 0: return None # 创建列表用来存放筛选之后合格的手掌轮廓 valid_hand [] # 遍历每一条检测得到的轮廓 for cnt in contours: # 计算当前轮廓所占像素面积 area cv2.contourArea(cnt) # 如果轮廓面积小于手掌最低面积阈值则跳过该轮廓 if area MIN_HAND_AREA: continue # 获取轮廓外接矩形返回矩形左上角坐标、宽度、高度 x, y, w, h cv2.boundingRect(cnt) # 计算矩形长边与短边的比值 ratio max(w, h) / min(w, h) # 长宽比小于阈值代表形状接近手掌存入合格列表 if ratio MAX_HAND_RATIO: valid_hand.append(cnt) # 合格手掌轮廓列表为空返回None if len(valid_hand) 0: return None # 在合格轮廓当中选取面积最大的轮廓作为当前手掌 hand_cont max(valid_hand, keycv2.contourArea) # 返回筛选完成的手掌轮廓 return hand_contdef get_fingertips(hand_contour):“”“凸缺陷算法精准提取指尖坐标”“”# 获取手掌轮廓凸包关闭返回点模式仅返回轮廓索引hull cv2.convexHull(hand_contour, returnPointsFalse)# 根据凸包计算凸缺陷手掌指缝位置就是凸缺陷defects cv2.convexityDefects(hand_contour, hull)# 创建列表用来存储指尖坐标点fingertips []# 判断凸缺陷是否成功检测到if defects is not None:# 循环遍历全部凸缺陷for i in range(defects.shape[0]):# s起始点索引、e终点索引、f凹陷点索引、d凹陷深度s, e, f, d defects[i, 0]# 获取缺陷起始点坐标start tuple(hand_contour[s][0])# 获取缺陷终点坐标end tuple(hand_contour[e][0])# 将两个指尖坐标存入指尖数组fingertips.append(list(start))fingertips.append(list(end))# 当凸缺陷没有获取到指尖则直接读取凸包顶点当作指尖点位if len(fingertips) 0:# 获取凸包所有顶点坐标hull_points cv2.convexHull(hand_contour, returnPointsTrue)# 遍历凸包顶点存入指尖列表for point in hull_points:fingertips.append([point[0][0], point[0][1]])# 将指尖列表转换为numpy数组并且返回return np.array(fingertips)def calc_euclidean(p1, p2):“”“勾股定理计算两点像素距离”“”# 欧氏距离公式计算两个坐标点之间像素长度return np.sqrt(np.square(p1[0] - p2[0]) np.square(p1[1] - p2[1]))def distance_to_brightness(dist):“”“指尖距离线性映射灯光亮度0~100%”“”# 限制距离数值处于有效区间50~300防止数值越界dist np.clip(dist, MIN_DIST, MAX_DIST)# 根据距离换算得到亮度百分比percent ((dist - MIN_DIST) / DIST_RANGE) * 100# 保留一位小数之后返回亮度百分比return round(percent, 1)def draw_brightness_bar(frame, percent):“”“左侧绘制蓝色亮度进度条”“”# 设置进度条左上角坐标bar_x, bar_y 30, 50# 设置进度条宽度、整体高度bar_w, bar_h 40, 400# 绘制进度条灰色外边框cv2.rectangle(frame, (bar_x, bar_y), (bar_x bar_w, bar_y bar_h), GRAY_COLOR, 2)# 根据亮度百分比计算填充高度fill_h int(bar_h * (percent / 100))# 计算填充矩形的上边坐标进度条自下而上填充fill_y bar_y bar_h - fill_h# 绘制蓝色的亮度填充块cv2.rectangle(frame, (bar_x, fill_y), (bar_x bar_w, bar_y bar_h), BLUE, -1)# 返回绘制完成之后的画布return framedef draw_hand_connection(img, tip_points):“”“绘制手掌关键点连接线”“”# 循环遍历指尖点位依次连线相邻指尖for i in range(len(tip_points) - 1):# 取出第i个指尖的整型坐标p1 (int(tip_points[i][0]), int(tip_points[i][1]))# 取出后一个指尖整型坐标p2 (int(tip_points[i1][0]), int(tip_points[i1][1]))# 使用紫色线条连接两个指尖cv2.line(img, p1, p2, PURPLE, 2)# 循环绘制每一处指尖圆点标记for pt in tip_points:cv2.circle(img, (int(pt[0]), int(pt[1])),6,PURPLE,-1)# 返回绘制结束后的画布return img 【步骤3主程序循环】 def main():# 声明使用全局时间变量prev_timeglobal prev_time# 创建摄像头捕获对象开启指定编号摄像头cap cv2.VideoCapture(CAM_ID)# 设置摄像头输出画面宽度为640像素cap.set(cv2.CAP_PROP_FRAME_WIDTH,640)# 设置摄像头输出画面高度为480像素cap.set(cv2.CAP_PROP_FRAME_HEIGHT,480)# 判断摄像头是否开启失败 if not cap.isOpened(): # 在终端打印摄像头开启失败提示英文 print(Camera open failed, please modify CAM_ID) # 终止主函数 return # 摄像头图像无限循环读取 while True: # 读取一帧摄像头画面ret代表读取成功标记frame为图像矩阵 ret, frame cap.read() # 如果当前帧读取失败则跳过本次循环继续读取下一帧 if not ret: continue # 获取图像高度、宽度数值通道数舍弃 img_h, img_w frame.shape[:2] # 将画面水平镜像翻转适配人面对镜头时左右手方向 frame cv2.flip(frame,1) # 拷贝原图作为绘图画布防止原图被修改 canvas frame.copy() # 获取当前系统时间戳 cur_time time.time() # 计算当前画面帧率单位帧每秒 fps int(1/(cur_time - prev_time)) # 更新上一帧时间戳为本帧时间 prev_time cur_time # 初始化灯光亮度百分比默认值为0 brightness_percent 0.0 # 调用函数检测当前画面当中的手掌轮廓 hand_cont get_hand_contour(frame) # 判断已经成功检测到手部轮廓 if hand_cont is not None: # 在画布绘制紫色手掌轮廓边线 cv2.drawContours(canvas,[hand_cont],-1,PURPLE,2) # 获取当前手掌全部指尖点位数组 tip_array get_fingertips(hand_cont) # 控制台打印当前检测出来指尖的数量 print(fDetected fingertips quantity:{len(tip_array)}) # 指尖点位大于等于2才可以计算双指间距 if len(tip_array) 2: # 初始化指尖最大间距 max_dis 0 # 存储距离最远两个指尖的数组下标 index_a, index_b 0,1 # 双层循环遍历所有指尖组合 for i in range(len(tip_array)): for j in range(i1, len(tip_array)): # 计算当前一组指尖之间像素距离 d calc_euclidean(tip_array[i], tip_array[j]) # 如果距离大于当前最大距离则更新最大距离与下标 if d max_dis: max_dis d index_a,index_b i,j # 获取距离最远第一个指尖坐标 point1 tip_array[index_a] # 获取距离最远第二个指尖坐标 point2 tip_array[index_b] # 转为整型像素坐标 x1,y1 int(point1[0]),int(point1[1]) x2,y2 int(point2[0]),int(point2[1]) # 控制台输出两根指尖之间的像素距离 print(fFinger‑finger pixel distance:{max_dis}) # 在画布绘制紫色实心圆点标记第一个指尖 cv2.circle(canvas,(x1,y1),8,PURPLE,-1) # 在画布绘制紫色实心圆点标记第二个指尖 cv2.circle(canvas,(x2,y2),8,PURPLE,-1) # 使用紫色线条连接两处指尖标记点 cv2.line(canvas,(x1,y1),(x2,y2),PURPLE,3) # 通过指尖间距换算灯光亮度百分比 brightness_percent distance_to_brightness(max_dis) # 绘制所有指尖之间的连接线 canvas draw_hand_connection(canvas, tip_array) # 将0~100亮度百分比换算为LED通道数值范围0~255 led_val int((brightness_percent / 100) * 255) # 设置24颗灯环全部为当前亮度的白光 rgb.set([(led_val, led_val, led_val)] * 24) # 在画布左上角绘制当前帧率FPS文字 cv2.putText(canvas,fFPS: {fps},(10,35), cv2.FONT_HERSHEY_SIMPLEX,1,BLUE,2) # 在画布左下角输出当前灯光亮度百分比英文文本 cv2.putText(canvas,fBrightness: {brightness_percent}%,(20, img_h - 20), cv2.FONT_HERSHEY_SIMPLEX,1,BLUE,2) # 在画布左侧刷新可视化亮度进度条 canvas draw_brightness_bar(canvas, brightness_percent) # 设置预览窗口标题并且展示处理之后的画布画面 cv2.imshow(-----, canvas) # 等待键盘按键输入延时1毫秒 key cv2.waitKey(1) # 判断按下ESC按键ESC按键ASCII码为27结束主循环 if key 27: break # 程序结束释放摄像头硬件资源 cap.release() # 销毁所有OpenCV创建出来的图像窗口 cv2.destroyAllWindows() # 将RGB灯环所有LED熄灭 rgb.set([0, 0, 0] * 24) # 控制台打印程序退出硬件释放完毕提示 print(Program exit, camera and led‑ring released)程序入口运行主函数ifname “main”:main()

相关新闻

LLM智能体延迟优化:基于推测执行的沙盒调度技术解析

LLM智能体延迟优化:基于推测执行的沙盒调度技术解析

2026/8/18 11:06:59

1. 项目概述:当LLM智能体需要“沙盒”来并行思考最近在折腾大语言模型(LLM)智能体(Agent)的线上服务(Serving)时,一个绕不开的痛点越来越明显:延迟。你设计了一个能调用工…

高炉炉况智能诊断与预警实战~系列文章01:炉况诊断-从经验判断到数据驱动的范式跃迁

高炉炉况智能诊断与预警实战~系列文章01:炉况诊断-从经验判断到数据驱动的范式跃迁

2026/8/18 10:56:56

第 1 期 | 炉况诊断总论:从经验判断到数据驱动的范式跃迁一座 3200m 高炉,休风 1 小时的直接损失以十万元计;一次恶性管道行程若处置失当,可能引发炉况大滑、数日难以恢复。炉况诊断的价值,从来不在于"判断得准不…

论人工个体生命状态元素工程的理论基础与系统实现

论人工个体生命状态元素工程的理论基础与系统实现

2026/8/18 10:56:56

论人工个体生命状态元素工程的理论基础与系统实现——基于WSaiOS-ICAI框架的Individual State Element Model研究摘要:在人工智能个体建模领域,身份、性格、价值、经历等静态元素体系已相对成熟,但个体在时间维度上的动态性始终缺乏系统化的工…

还在被系统激活弹窗烦?KMS激活工具KMS_VL_ALL_AIO使用教程:从安装到自动续期

还在被系统激活弹窗烦?KMS激活工具KMS_VL_ALL_AIO使用教程:从安装到自动续期

2026/8/18 12:07:01

还在被系统激活弹窗烦?KMS激活工具KMS_VL_ALL_AIO使用教程:从安装到自动续期 【免费下载链接】KMS_VL_ALL_AIO Smart Activation Script 项目地址: https://gitcode.com/gh_mirrors/km/KMS_VL_ALL_AIO 周一早晨,你打开电脑准备开始一天…

奇点大会 insights,动态数据蒸馏如何过滤噪声样本

奇点大会 insights,动态数据蒸馏如何过滤噪声样本

2026/8/18 12:07:01

动态数据蒸馏:用可信权重过滤回流噪声 在大模型持续学习的工程实践中,数据回流往往是一把双刃剑。线上推理产生的海量反馈数据虽然能弥补静态训练集的分布漂移,但其中混杂的低置信度预测和错误标注若直接注入训练管道,极易引发“…

深入解析epoll:Linux高并发IO的核心机制

深入解析epoll:Linux高并发IO的核心机制

2026/8/18 12:07:01

1. 为什么面试官总爱问epoll?记得我第一次被问到epoll的场景,是在2016年某大厂的技术终面。当时面试官突然放下简历,盯着我问:"知道为什么nginx性能比apache好吗?"我支支吾吾答了些多进程模型,结…

大模型防退化指南,奇点大会推荐三阶段检测法

大模型防退化指南,奇点大会推荐三阶段检测法

2026/8/18 12:07:01

从单点筛查到闭环防御:三阶段污染检测实战 大模型上线只是开始,真正的挑战在于如何让模型在持续的数据回流中保持“清醒”。很多团队在初期只部署了简单的在线采样,结果发现误报率居高不下,或者漏掉了隐蔽的分布漂移。奇点智能大…

终极方案:3步快速让Windows 10/11显示HEIC照片缩略图

终极方案:3步快速让Windows 10/11显示HEIC照片缩略图

2026/8/18 12:07:01

终极方案:3步快速让Windows 10/11显示HEIC照片缩略图 【免费下载链接】windows-heic-thumbnails Enable Windows Explorer to display thumbnails for HEIC/HEIF files 项目地址: https://gitcode.com/gh_mirrors/wi/windows-heic-thumbnails 周五晚上&#…

史上最详细的Western blot实验流程,每个研究生新生都应该看一下!

史上最详细的Western blot实验流程,每个研究生新生都应该看一下!

2026/8/18 11:57:01

蛋白免疫印记(Western blot,WB)是分子生物学和生物化学领域检测特定蛋白质的“金标准”,但很多人明明步骤都对,却要么没条带、要么背景糊或条带畸形,熬了无数个夜也难得出一张满意的结果。今天我们整理了史…

【文章复现】非线性值迭代自适应动态规划(ADP):离散时间非线性系统的策略迭代自适应动态规划算法研究附Matlab代码

【文章复现】非线性值迭代自适应动态规划(ADP):离散时间非线性系统的策略迭代自适应动态规划算法研究附Matlab代码

2026/8/17 1:28:42

✅作者简介:热爱科研的Matlab仿真开发者,擅长毕业设计辅导、数学建模、数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。🍎 往期回顾关注个人主页:Matlab科研工作室👇 关注我领取海量matlab电子书和…

【双层规划,节点出清价,绿证交易,CVaR方法】两级电力市场环境下计及风险的省间交易商最优购电模型附Matlab代码

【双层规划,节点出清价,绿证交易,CVaR方法】两级电力市场环境下计及风险的省间交易商最优购电模型附Matlab代码

2026/8/18 1:03:22

✅作者简介:热爱科研的Matlab仿真开发者,擅长毕业设计辅导、数学建模、数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。🍎 往期回顾关注个人主页:Matlab科研工作室👇 关注我领取海量matlab电子书和…

隐式mpc+自适应mpc+时变mpc,线性时变模型预测控制附Simulink仿真

隐式mpc+自适应mpc+时变mpc,线性时变模型预测控制附Simulink仿真

2026/8/17 8:40:51

✅作者简介:热爱科研的Matlab仿真开发者,擅长毕业设计辅导、数学建模、数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。🍎 往期回顾关注个人主页:Matlab科研工作室👇 关注我领取海量matlab电子书和…

多智能体大模型辩论中的立场收敛:从伪共识到理性说服的评估方法

多智能体大模型辩论中的立场收敛:从伪共识到理性说服的评估方法

2026/8/18 0:06:29

1. 从一场“假辩论”说起:为什么大模型辩论会走向“伪共识”?最近在折腾多智能体大语言模型(Multi-Agent LLM)的辩论实验,发现一个挺有意思的现象。我让几个基于GPT-4的智能体就一个争议性话题(比如“远程办…

Frida动态代码插桩框架:从原理到实战的移动安全与逆向工程指南

Frida动态代码插桩框架:从原理到实战的移动安全与逆向工程指南

2026/8/18 0:06:29

1. 从“黑盒”到“白盒”:为什么我们需要Frida在移动安全、逆向工程甚至是一些自动化测试的场景里,我们经常会遇到一个让人头疼的问题:面对一个编译好的、没有源代码的应用程序,我们如何知道它在运行时内部发生了什么?…

ECharts饼图中心文字配置指南:从label与title区别到动态交互实现

ECharts饼图中心文字配置指南:从label与title区别到动态交互实现

2026/8/18 0:06:29

1. 从“空心”到“有魂”:为什么要在饼图中间加文字?如果你用过ECharts画饼图,大概率会注意到一个现象:默认生成的饼图中间是空心的。这个设计本身没问题,它清晰地展示了各个扇区的占比关系。但在很多实际的业务场景里…

摆脱论文困扰!盘点2026年全网爆红的的AI论文写作工具

摆脱论文困扰!盘点2026年全网爆红的的AI论文写作工具

2026/8/17 12:00:53

一天写完毕业论文在2026年已不再是天方夜谭。2026年最炸裂、实测能大幅提速的AI论文写作工具,覆盖选题构思、文献整理、内容生成、格式排版等核心场景,真正帮你高效搞定论文难题。 一、全流程王者:一站式搞定论文全链路(一天定稿首…

导师推荐!2026最新AI论文工具测评与实用推荐

导师推荐!2026最新AI论文工具测评与实用推荐

2026/8/15 10:10:27

2026年真正好用的AI论文工具,核心看生成的论文质量、低AI味、格式正确、学术适配四大指标。综合实测,千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队,覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。 一、…

告别游戏崩溃:XCOM 2模组管理器的智能革命

告别游戏崩溃:XCOM 2模组管理器的智能革命

2026/8/14 19:35:14

告别游戏崩溃:XCOM 2模组管理器的智能革命 【免费下载链接】xcom2-launcher The Alternative Mod Launcher (AML) is a replacement for the default game launchers from XCOM 2 and XCOM Chimera Squad. 项目地址: https://gitcode.com/gh_mirrors/xc/xcom2-lau…