TAG Park

分享自己觉得好玩的技术和有趣的游戏理解

0%

基于mediaPipe和OpenCV手势识别

手部追踪模块(HandTrackingModule.py):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# -*- coding:utf-8 -*-

import cv2
import mediapipe as mp

class HandDetector:
"""
使用mediapipe库查找手。导出地标像素格式。添加了额外的功能。
如查找方式,许多手指向上或两个手指之间的距离。而且提供找到的手的边界框信息。
"""
def __init__(self, mode=False, maxHands=2, detectionCon=0.5, minTrackCon = 0.5):
"""
:param mode: 在静态模式下,对每个图像进行检测
:param maxHands: 要检测的最大手数
:param detectionCon: 最小检测置信度
:param minTrackCon: 最小跟踪置信度
"""
self.mode = mode
self.maxHands = maxHands
self.modelComplex = False
self.detectionCon = detectionCon
self.minTrackCon = minTrackCon

# 初始化手部识别模型
self.mpHands = mp.solutions.hands
self.hands = self.mpHands.Hands(self.mode, self.maxHands, self.modelComplex,
self.detectionCon, self.minTrackCon)
self.mpDraw = mp.solutions.drawing_utils # 初始化绘图器
self.tipIds = [4, 8, 12, 16, 20] # 指尖列表
self.fingers = []
self.lmList = []

def findHands(self, img, draw=True):
"""
从图像(BRG)中找到手部。
:param img: 用于查找手的图像。
:param draw: 在图像上绘制输出的标志。
:return: 带或不带图形的图像
"""
imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # 将传入的图像由BGR模式转标准的Opencv模式——RGB模式,
self.results = self.hands.process(imgRGB)

if self.results.multi_hand_landmarks:
for handLms in self.results.multi_hand_landmarks:
if draw:
self.mpDraw.draw_landmarks(img, handLms,
self.mpHands.HAND_CONNECTIONS)
return img

def findPosition(self, img, handNo=0, draw=True):
"""
查找单手的地标并将其放入列表中像素格式。还可以返回手部周围的边界框。
:param img: 要查找的主图像
:param handNo: 如果检测到多只手,则为手部id
:param draw: 在图像上绘制输出的标志。(默认绘制矩形框)
:return: 像素格式的手部关节位置列表;手部边界框
"""

xList = []
yList = []
bbox = []
bboxInfo =[]
self.lmList = []
if self.results.multi_hand_landmarks:
myHand = self.results.multi_hand_landmarks[handNo]
for id, lm in enumerate(myHand.landmark):
h, w, c = img.shape
px, py = int(lm.x * w), int(lm.y * h)
xList.append(px)
yList.append(py)
self.lmList.append([px, py])
if draw:
cv2.circle(img, (px, py), 5, (255, 0, 255), cv2.FILLED)
xmin, xmax = min(xList), max(xList)
ymin, ymax = min(yList), max(yList)
boxW, boxH = xmax - xmin, ymax - ymin
bbox = xmin, ymin, boxW, boxH
cx, cy = bbox[0] + (bbox[2] // 2), \
bbox[1] + (bbox[3] // 2)
bboxInfo = {"id": id, "bbox": bbox,"center": (cx, cy)}

if draw:
cv2.rectangle(img, (bbox[0] - 20, bbox[1] - 20),
(bbox[0] + bbox[2] + 20, bbox[1] + bbox[3] + 20),
(0, 255, 0), 2)

return self.lmList, bboxInfo

def fingersUp(self):
"""
查找列表中打开并返回的手指数。会分别考虑左手和右手
:return:竖起手指的列表
"""
if self.results.multi_hand_landmarks:
myHandType = self.handType()
fingers = []
# Thumb
if myHandType == "Right":
if self.lmList[self.tipIds[0]][0] > self.lmList[self.tipIds[0] - 1][0]:
fingers.append(1)
else:
fingers.append(0)
else:
if self.lmList[self.tipIds[0]][0] < self.lmList[self.tipIds[0] - 1][0]:
fingers.append(1)
else:
fingers.append(0)
# 4 Fingers
for id in range(1, 5):
if self.lmList[self.tipIds[id]][1] < self.lmList[self.tipIds[id] - 2][1]:
fingers.append(1)
else:
fingers.append(0)
return fingers

def handType(self):
"""
检查传入的手部是左还是右
:return: "Right" 或 "Left"
"""
if self.results.multi_hand_landmarks:
if self.lmList[17][0] < self.lmList[5][0]:
return "Right"
else:
return "Left"
阅读全文 »

由浅入深了解优化器(Optimizer)

目录

1.什么是优化器?

2.有哪些优化器

3.优化算法的选择与使用策略

1.什么是优化器?

(1)解释

优化器就是在深度学习反向传播过程中,指引损失函数(目标函数)的各个参数往正确的方向更新合适的大小,使得更新后的各个参数让损失函数值不断逼近全局最小。

阅读全文 »

大二时暑假无聊做的开源键盘(基于Atmega32u4主控)

开源文件包含定位板的cad图纸、作者本人画的两个3d建模外壳、固件程序、pcb板等文件

开源地址

阅读全文 »

目录

  1. 标题
  2. 列表
  3. 引用
  4. 图片和超链接
  5. 粗体与斜体
  6. 代码框
  7. 转义字符
  8. 其他快捷键
  9. 最后

1.标题

标题的设置很简单,有三种添加方式:①手动添加;②快捷键添加;③选项卡添加,下面分别对这三种方式进行介绍。

Ⅰ. 手动添加

一级标题对应的是#一级标题#,二级标题对应##二级标题##,以此类推。

Ⅱ. 快捷键添加

直接在键盘上输入ctrl+num就能得到对应标题的级数

Ⅲ. 选项卡设置

在菜单栏中选择插入选项卡,找到需要插入的标题,添加即可。

阅读全文 »