本帖最后由 云天 于 2021-12-19 18:44 编辑
【OpenCV 单目测距】 以上是一个典型的小孔成像模型,与单目相机的成像原理类似。
中间通过红蓝的垂线是相机的主光轴,d是被测物体至镜头的距离,f为相机镜头的焦距,w为被测物体的实际宽度(高度),w'为物体在成像平面(感光元件)上的宽度(高度)。
根据相似三角形公式可得:f / d = w' / w
【计算f(相机镜头焦距)】
用 OpenCV识别颜色块 ,来计算 f(相机镜头焦距)
绘制已知间距的颜色块
利用以下程序,在实际“实际宽度”w=12cm,"测物体至镜头的距离"d=20,测得:“物体在成像平面(感光元件)上的宽度”,w'=384
根据公式可得:f=20/12*384=640
复制代码 【手距控灯】
测量实际中指到腕关节的距离,估测为18cm

-
- import cv2
- import math
- from handutil import HandDetector
- import numpy as np
- import time
- from pinpong.board import Board,Pin,NeoPixel #导入neopixel类
- Board("uno").begin() #初始化,选择板型(uno、leonardo、xugu)和端口号,不输入端口号则进行自动识别
- NEOPIXEL_PIN = Pin(Pin.D7)
- PIXELS_NUM = 7 #灯数
- np = NeoPixel(NEOPIXEL_PIN,PIXELS_NUM)
- # 打开摄像头
- cap = cv2.VideoCapture(0)
- # 创建一个手势识别对象
- detector = HandDetector()
-
- # 指尖列表,分别代表腕关节,大拇指、食指、中指、无名指和小指的指尖
- tip_ids = [0,4, 8, 12, 16, 20]
- lenght=0
- num=0
- while True:
- success, img = cap.read()
-
- if success:
- # 检测手势
- img = detector.find_hands(img, draw=True)
- # 获取手势数据
- lmslist = detector.find_positions(img)
- if len(lmslist) > 0:
- fingersX = []
- fingersY = []
- for tid in tip_ids:
- # 找到每个指尖的位置
- x, y = lmslist[tid][1], lmslist[tid][2]
- cv2.circle(img, (x, y), 8, (255, 255, 0), cv2.FILLED)
-
- if tid == 0:
- fingersX.append(x)
- fingersY.append(y)
-
- if tid == 4:
- fingersX.append(x)
- fingersY.append(y)
-
- if tid == 8:
- fingersX.append(x)
- fingersY.append(y)
-
- if tid == 12:
- fingersX.append(x)
- fingersY.append(y)
-
- if tid == 16:
- fingersX.append(x)
- fingersY.append(y)
-
- if tid == 20:
- fingersX.append(x)
- fingersY.append(y)
- #计算图像中指到腕关节的距离,并求和
-
- lenght=math.sqrt((fingersX[0]-fingersX[3])**2+(fingersY[0]-fingersY[3])**2)
- #18为实际中指到腕关节的距离
- lenght=640/lenght*18
- for num in range(0,int(lenght/80*7)):
- # 找到对应的手势图片并显示
- if num>6:
- num=6
- np[num] = (255, 0 ,0)
- if num<6:
- for k in range(num,7):
- np[k] = (0, 0 ,0)
- for i in range(1,6):
- cv2.line(img, (fingersX[0], fingersY[0]), (fingersX[i], fingersY[i]), (0, 0, 255), 4,8)
- print(lenght)
-
- cv2.imshow('Image', img)
-
- k = cv2.waitKey(1)
- if k == ord('q'):
- break
-
- cap.release()
- cv2.destroyAllWindows()
复制代码
|
|
|
|
|
|
|
|
|