Skip to content

Commit 2d3518c

Browse files
committed
update readme;
1 parent e0dac17 commit 2d3518c

File tree

2 files changed

+138
-47
lines changed

2 files changed

+138
-47
lines changed

README.md

Lines changed: 137 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,13 @@
66
<img src="https://img.shields.io/badge/Swift-5.9+-orange.svg" alt="Swift 5.9" />
77
<img src="https://img.shields.io/badge/Platforms-visionOS-brightgreen?style=flat-square" alt="Swift 5.9" />
88
</p>
9-
109
[中文版](./README_CN.md)
1110

12-
**HandVector** uses **Cosine Similarity** Algorithm to calculate the similarity of hand gestures in visionOS, and with a macOS tool to test hand tracking in visionOS simulator.
11+
**HandVector** calculates the similarity between different static gestures on visionOS and comes with a macOS utility class that allows you to use gesture tracking in the visionOS simulator as well.
12+
13+
HandVector version 2.0 is a major update, bringing the improved **Cosine Similarity** and the **FingerShape** feature for easier customization.
14+
15+
> Note: HandVector 2.0 has significant API changes and is not compatible with older versions.
1316
1417
<p align="center">
1518
<a href="#requirements">Requirements</a> • <a href="#usage">Usage</a> • <a href="#installation">Installation</a> • <a href="#contribution">Contribution</a> • <a href="#contact">Contact</a> • <a href="#license-mit">License</a>
@@ -23,90 +26,178 @@
2326

2427
## Usage
2528

26-
Your can run demo in package to see how to use it, and also can try an Vision Pro App. And also can see the App in App Store whitch uses `HandVector` to match gesture:
29+
`HandVector 2.0` supports two kinds of gesture matching methods, which differ in their calculation principles and are suitable for different scenarios. They can also be mixed used together in a project:
2730

28-
1. [FingerEmoji](https://apps.apple.com/us/app/fingeremoji/id6476075901) : FingerEmoji Let your finger dance with Emoji, you can Hit the emoji card by hand with the same gesture.
31+
* **Cosine Similarity**: This method matches each joint of the specified fingers precisely, using the matrix information of each joint relative to its parent joint, resulting in high accuracy. Advantages: High precision, applicable to fingers and wrists; Disadvantages: Poor interpretability, difficult to adjust the range.
32+
* **FingerShape**: Referencing Unity's [XRHands](https://docs.unity3d.com/Packages/com.unity.xr.hands@1.5/manual/index.html) framework, this method simplifies the finger shape into five parameters: `baseCurl` (curl at the base of the finger), `tipCurl` (curl at the tip of the finger), `fullCurl` (overall curl of the finger), `pinch` (distance of pinching with the thumb), and `spread` (degree of separation from the adjacent outer finger). Advantages: The values are easy to understand and convenient to control and adjust; Disadvantages: Does not fully utilize joint pose information, thus not as precise, and is only applicable to five fingers.
2933

30-
![960x540mv](./Resources/960x540mv.webp)
34+
### 1. Cosine Similarity Gesture Matching
35+
`HandVector` supports matching built-in gestures as well as recording and saving custom gestures for later use. Currently, there are 8 built-in gestures: 👆✌️✋👌✊🤘🤙🫱🏿‍🫲🏻
36+
> 🫱🏿‍🫲🏻: Grab, grasp
37+
#### a. Matching Built-in Gestures
38+
![MatchAllBuiltin](./Resources/MatchAllBuiltin.gif)
39+
40+
```swift
3141

32-
2. [SkyGestures](https://apps.apple.com/us/app/skygestures/id6499123392): **[SkyGestures](https://github.com/zlinoliver/SkyGestures)** is an innovative app that uses hand gestures to control DJI Tello drones via the Vision Pro platform. It's [Open Source](https://github.com/zlinoliver/SkyGestures) now.
42+
import HandVector
3343

34-
![](./Resources/skygestures_demo1.gif)
3544

3645

46+
//Get current Hand info from `HandTrackingProvider` , and convert to `HVHandInfo`
3747

38-
### 1. Match builtin hand gesture: OK
48+
for await update in handTracking.anchorUpdates {
3949

40-
![](./Resources/handVectorDemoMatchOK.gif)
50+
switch update.event {
4151

42-
`HandVector` allows you to track your hands, and calculate the similarity between your current hand to another recorded hand gesture:
52+
case .added, .updated:
4353

44-
```swift
45-
import HandVector
54+
let anchor = update.anchor
4655

47-
//load recorded hand gesture from json file
48-
model.handEmojiDict = HandEmojiParameter.generateParametersDict(fileName: "HandEmojiTotalJson")!
49-
guard let okVector = model.handEmojiDict["👌"]?.convertToHandVectorMatcher(), let leftOKVector = okVector.left else { return }
56+
guard anchor.isTracked else { continue }
57+
58+
let handInfo = latestHandTracking.generateHandInfo(from: anchor)
59+
60+
case .removed:
61+
62+
...
63+
64+
}
5065

51-
//update current handTracking from HandTrackingProvider
52-
for await update in handTracking.anchorUpdates {
53-
switch update.event {
54-
case .added, .updated:
55-
let anchor = update.anchor
56-
guard anchor.isTracked else { continue }
57-
await latestHandTracking.updateHand(from: anchor)
58-
case .removed:
59-
...
60-
}
6166
}
6267

6368

64-
//calculate the similarity
65-
let leftScore = model.latestHandTracking.leftHandVector?.similarity(to: leftOKVector) ?? 0
66-
model.leftScore = Int(abs(leftScore) * 100)
67-
let rightScore = model.latestHandTracking.rightHandVector?.similarity(to: leftOKVector) ?? 0
68-
model.rightScore = Int(abs(rightScore) * 100)
69+
70+
//Load built-in gesture from json file
71+
72+
let builtinHands = HVHandInfo.builtinHandInfo
73+
74+
//Calculate the similarity with the built-in gestures, `.fiveFingers` indicates matching only the 5 fingers, ignoring the wrist and palm.
75+
76+
builtinHands.forEach { (key, value) in
77+
78+
leftScores[key] = latestHandTracking.leftHandVector?.similarity(of: .fiveFingers, to: value)
79+
80+
rightScores[key] = latestHandTracking.rightHandVector?.similarity(of: .fiveFingers, to: value)
81+
82+
}
83+
6984
```
7085

7186
the score should be in `[-1.0,1.0]`, `1.0` means fully matched and both are left or right hands, `-1.0 `means fully matched but one is left hand, another is right hand, and `0` means not matched.
7287

73-
### 2. Record a new gesture and match
88+
#### b. Record custom gesture and match it
89+
90+
91+
92+
![RecordAndMatch](./Resources/RecordAndMatch.gif)
93+
94+
95+
96+
Record a custom gesture and save it as a JSON string using `HVHandJsonModel`:
7497

75-
![](./Resources/handVectorDemoRecordMatch.gif)
7698

77-
`HandVector` allows you to record your custom hands gesture, and save as JSON string:
7899

79100
```swift
80-
let para = HandEmojiParameter.generateParameters(name: "both", leftHandVector: model.latestHandTracking.leftHandVector, rightHandVector: model.latestHandTracking.rightHandVector)
81-
model.recordHand = para
82101

83-
jsonString = para?.toJson()
102+
if let left = model.latestHandTracking.leftHandVector {
103+
104+
let para = HVHandJsonModel.generateJsonModel(name: "YourHand", handVector: left)
105+
106+
jsonString = para.toJson()
107+
108+
//Save jsonString to disk or network
109+
110+
...
111+
112+
}
113+
84114
```
85115

86-
And then, you can turn this JSON string to `HandVectorMatcher`,so you can use it to match your gesture now:
116+
117+
118+
Next, convert the saved JSON string into the `HVHandInfo` type for gesture matching:
119+
120+
87121

88122
```swift
89-
guard let targetVector = model.recordHand?.convertToHandVectorMatcher(), targetVector.left != nil || targetVector.right != nil else { return }
90123

91-
let targetLeft = targetVector.left ?? targetVector.right
92-
let targetRight = targetVector.right ?? targetVector.left
124+
//Convert from JSON string
125+
126+
let handInfo = jsonStr.toModel(HVHandJsonModel.self)!.convertToHVHandInfo()
127+
128+
//Load JSON file from disk, and convert
129+
130+
let handInfo = HVHandJsonModel.loadHandJsonModel(fileName: "YourJsonFileName")!.convertToHVHandInfo()
131+
132+
133+
134+
//Using the `HVHandInfo` type for gesture matching allows you to calculate the similarity for each finger individually.
135+
136+
if let handInfo {
137+
138+
averageAndEachLeftScores = latestHandTracking.leftHandVector?.averageAndEachSimilarities(of: .fiveFingers, to: recordHand)
139+
140+
averageAndEachRightScores = latestHandTracking.rightHandVector?.averageAndEachSimilarities(of: .fiveFingers, to: recordHand)
141+
142+
}
143+
144+
93145

94-
let leftScore = model.latestHandTracking.leftHandVector?.similarity(of: HandVectorMatcher.allFingers, to: targetLeft!) ?? 0
95-
model.leftScore = Int(abs(leftScore) * 100)
96-
let rightScore = model.latestHandTracking.rightHandVector?.similarity(of: HandVectorMatcher.allFingers, to: targetRight!) ?? 0
97-
model.rightScore = Int(abs(rightScore) * 100)
98146
```
99147

100148

101149

150+
### 2.Finger Shape Parameter
151+
152+
153+
154+
![XRHandsCoverImage](./Resources//UntityXRHandsCoverImage.png)
155+
156+
157+
158+
This method draws significant reference from the well-known XR gesture framework in Unity: [XRHands](https://docs.unity3d.com/Packages/com.unity.xr.hands@1.5/manual/index.html).
159+
160+
161+
162+
![FingerShaper](./Resources/FingerShaper.gif)
163+
164+
165+
166+
The definitions of the related parameters are similar:
167+
* **baseCurl**: The degree of curl at the root joint of the finger. For the thumb, it is the `IntermediateBase` joint, and for the other fingers, it is the `Knuckle` joint, with a range of 0 to 1.
168+
169+
![FingerShapeBaseCurl](./Resources/FingerShapeBaseCurl.png)
170+
171+
172+
173+
* **tipCurl**:The degree of curl at the upper joint of the finger. For the thumb, it is the `IntermediateTip` joint, and for the other fingers, it is the average value of the `IntermediateBase` and `IntermediateTip` joints, with a range of 0 to 1.
174+
175+
![FingerShapeTipCurl](./Resources/FingerShapeTipCurl.png)
176+
177+
* **fullCurl**:The average value of baseCurl and tipCurl, with a range of 0 to 1.
178+
179+
![FingerShapFullCurl](./Resources/FingerShapFullCurl.png)
180+
181+
* **pinch**:The distance from the tip of the thumb, with a range of 0 to 1. For the thumb, this parameter is `nil`.
182+
183+
![FingerShapePinch](./Resources/FingerShapePinch.png)
184+
185+
* **spread**:Only the horizontal spread angle is calculated, with a range of 0 to 1. For the little finger, this parameter is `nil`.
186+
187+
![FingerShapeSpread](./Resources/FingerShapeSpread.png)
188+
189+
Regarding the differences between the three types of curl degrees, you can refer to the following image:
190+
191+
![FingerShapeDifferenceCurl](./Resources/FingerShapeDifferenceCurl.png)
192+
102193
### 3. Test hand gesture on Mac simulator
103194

104195
The test method of`HandVector` is inspired by [VisionOS Simulator hands](https://github.com/BenLumenDigital/VisionOS-SimHands), it allow you to test hand tracking on visionOS simulator:
105196

106197
It uses 2 things:
107198

108199
1. A macOS helper app, with a bonjour service
109-
2. A Swift class for your VisionOS project which connects to the bonjour service (already in this package, and already turn JSON data to hand gestures)
200+
2. A Swift class for your VisionOS project which connects to the bonjour service (It comes with this package, and automatically receives and converts to the corresponding gesture; HandVector 2.0 version has updated mathematical "black magic" to achieve the new matching algorithm.)
110201

111202
#### macOS Helper App
112203

@@ -131,7 +222,7 @@ To go further, take a look at the documentation and the demo project.
131222
To integrate using Apple's Swift package manager, without Xcode integration, add the following as a dependency to your `Package.swift`:
132223

133224
```
134-
.package(url: "https://github.com/XanderXu/HandVector.git", .upToNextMajor(from: "0.3.0"))
225+
.package(url: "https://github.com/XanderXu/HandVector.git", .upToNextMajor(from: "2.0.0"))
135226
```
136227

137228
#### Manually

README_CN.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
[English](./README.md)
1111

12-
**HandVector**vsionOS 上计算不同静态手势之间的相似度,并且带有一个 macOS 的工具类能让你在 visionOS 模拟器上也能使用手势追踪功能。
12+
**HandVector**visionOS 上计算不同静态手势之间的相似度,并且带有一个 macOS 的工具类能让你在 visionOS 模拟器上也能使用手势追踪功能。
1313

1414
HandVector 2.0 版本是一个大更新,带来更好的 **余弦相似度Cosine Similarity** 匹配效果和 **手指形状参数FingerShape** 功能,更方便自定义使用。
1515

0 commit comments

Comments
 (0)