3230浏览
查看: 3230|回复: 0

[项目] 【智控万物】手势识别+OpenCV 单目测距实现控灯

[复制链接]
本帖最后由 云天 于 2021-12-19 18:44 编辑

【OpenCV 单目测距】
以上是一个典型的小孔成像模型,与单目相机的成像原理类似。

中间通过红蓝的垂线是相机的主光轴,d是被测物体至镜头的距离,f为相机镜头的焦距,w为被测物体的实际宽度(高度),w'为物体在成像平面(感光元件)上的宽度(高度)。

       根据相似三角形公式可得:f / d = w' / w
【计算f(相机镜头焦距)
OpenCV识别颜色块来计算f(相机镜头焦距)
【智控万物】手势识别+OpenCV 单目测距实现控灯图1

绘制已知间距的颜色块
【智控万物】手势识别+OpenCV 单目测距实现控灯图2


【智控万物】手势识别+OpenCV 单目测距实现控灯图3


利用以下程序,在实际“实际宽度”w=12cm,"测物体至镜头的距离"d=20,测得:“物体在成像平面(感光元件)上的宽度”,w'=384

根据公式可得:f=20/12*384=640


  1. import cv2
  2. import math
  3. import numpy as np
  4. ball_color = 'green'
  5. boxs=[]
  6. color_dist = {'red': {'Lower': np.array([0, 60, 60]), 'Upper': np.array([6, 255, 255])},
  7.               'blue': {'Lower': np.array([100, 80, 46]), 'Upper': np.array([124, 255, 255])},
  8.               'green': {'Lower': np.array([35, 43, 35]), 'Upper': np.array([90, 255, 255])},
  9.               }
  10. cap = cv2.VideoCapture(0)
  11. cv2.namedWindow('camera', cv2.WINDOW_AUTOSIZE)
  12. while cap.isOpened():
  13.     ret, frame = cap.read()
  14.     if ret:
  15.         if frame is not None:</p><p>           #图像处理</p><p>           gs_frame = cv2.GaussianBlur(frame, (5, 5), 0)                     # 高斯模糊
  16.             hsv = cv2.cvtColor(gs_frame, cv2.COLOR_BGR2HSV)                 # 转化成HSV图像
  17.             erode_hsv = cv2.erode(hsv, None, iterations=2)                   # 腐蚀 粗的变细,用于去除噪声点
  18.             inRange_hsv = cv2.inRange(erode_hsv, color_dist[ball_color]['Lower'], color_dist[ball_color]['Upper'])  #去除背景部分,将绿色以外的其他部分去除掉,并将图像转化为二值化图像</p><p>           #绘制矩形边框
  19.            cnts = cv2.findContours(inRange_hsv.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2]  #使用该函数找出方框外边界,并存储在cnts中
  20.             k=1
  21.             if cnts:
  22.               #找到两个相邻的方块,并计算中心间距
  23.               for i in cnts:
  24.               
  25.                rect = cv2.minAreaRect(i)
  26.                box = cv2.boxPoints(rect)
  27.                if k==1:
  28.                 boxs1=box
  29.                if k==2:
  30.                 boxs2=box   
  31.                k=k+1
  32.                cv2.drawContours(frame, [np.int0(box)], -1, (0, 255, 255), 2)  #在原图像上将分析出的矩形边界绘制出来
  33.             
  34.             if k>2:
  35.                 x1=int((boxs1[0][0]+boxs1[1][0]+boxs1[2][0]+boxs1[3][0])/4)
  36.                 y1=int((boxs1[0][1]+boxs1[1][1]+boxs1[2][1]+boxs1[3][1])/4)
  37.                 x2=int((boxs2[0][0]+boxs2[1][0]+boxs2[2][0]+boxs2[3][0])/4)
  38.                 y2=int((boxs2[0][1]+boxs2[1][1]+boxs2[2][1]+boxs2[3][1])/4)
  39.                
  40.                 cv2.line(frame,(x1,y1),(x2,y2), (0, 0, 255), 4,8)  #在原图像上将找到的相邻方块的中心点连线
  41.                 lenght=math.sqrt((x1-x2)**2+(y1-y2)**2)
  42.                 print(lenght)
  43.             cv2.imshow('camera', frame)
  44.             cv2.waitKey(1)
  45.         else:
  46.             print("无画面")
  47.     else:
  48.         print("无法读取摄像头!")
  49. cap.release()
  50. cv2.waitKey(0)
  51. cv2.destroyAllWindows()
复制代码
【手距控灯】
【智控万物】手势识别+OpenCV 单目测距实现控灯图5

测量实际中指到腕关节的距离,估测为18cm
【智控万物】手势识别+OpenCV 单目测距实现控灯图4


  1. import cv2
  2. import math
  3. from handutil import HandDetector
  4. import numpy as np
  5. import time
  6. from pinpong.board import Board,Pin,NeoPixel #导入neopixel类
  7. Board("uno").begin()               #初始化,选择板型(uno、leonardo、xugu)和端口号,不输入端口号则进行自动识别
  8. NEOPIXEL_PIN = Pin(Pin.D7)
  9. PIXELS_NUM = 7 #灯数
  10. np = NeoPixel(NEOPIXEL_PIN,PIXELS_NUM)
  11. # 打开摄像头
  12. cap = cv2.VideoCapture(0)
  13. # 创建一个手势识别对象
  14. detector = HandDetector()
  15. # 指尖列表,分别代表腕关节,大拇指、食指、中指、无名指和小指的指尖
  16. tip_ids = [0,4, 8, 12, 16, 20]
  17. lenght=0
  18. num=0
  19. while True:
  20.     success, img = cap.read()
  21.     if success:
  22.         # 检测手势
  23.         img = detector.find_hands(img, draw=True)
  24.         # 获取手势数据
  25.         lmslist = detector.find_positions(img)
  26.         if len(lmslist) > 0:
  27.             fingersX = []
  28.             fingersY = []
  29.             for tid in tip_ids:
  30.                 # 找到每个指尖的位置
  31.                 x, y = lmslist[tid][1], lmslist[tid][2]
  32.                 cv2.circle(img, (x, y), 8, (255, 255, 0), cv2.FILLED)
  33.               
  34.                 if tid == 0:
  35.                     fingersX.append(x)
  36.                     fingersY.append(y)
  37.             
  38.                 if tid == 4:
  39.                     fingersX.append(x)
  40.                     fingersY.append(y)
  41.                 if tid == 8:
  42.                     fingersX.append(x)
  43.                     fingersY.append(y)
  44.             
  45.                 if tid == 12:
  46.                     fingersX.append(x)
  47.                     fingersY.append(y)
  48.                     
  49.                 if tid == 16:
  50.                     fingersX.append(x)
  51.                     fingersY.append(y)
  52.             
  53.                 if tid == 20:
  54.                     fingersX.append(x)
  55.                     fingersY.append(y)
  56.             #计算图像中指到腕关节的距离,并求和   
  57.             
  58.             lenght=math.sqrt((fingersX[0]-fingersX[3])**2+(fingersY[0]-fingersY[3])**2)
  59.             #18为实际中指到腕关节的距离
  60.             lenght=640/lenght*18
  61.             for num in range(0,int(lenght/80*7)):
  62.             # 找到对应的手势图片并显示
  63.                 if num>6:
  64.                     num=6
  65.                 np[num] = (255, 0 ,0)
  66.             if num<6:
  67.              for k in range(num,7):
  68.                np[k] = (0, 0 ,0)
  69.             for i in range(1,6):
  70.               cv2.line(img, (fingersX[0], fingersY[0]), (fingersX[i], fingersY[i]), (0, 0, 255), 4,8)
  71.             print(lenght)
  72.         cv2.imshow('Image', img)
  73.     k = cv2.waitKey(1)
  74.     if k == ord('q'):
  75.         break
  76. cap.release()
  77. cv2.destroyAllWindows()
复制代码



您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4

© 2013-2024 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail