01:什么是 HandtrackJS
HandtrackJS 是一個(gè)基于 JavaScript 的開源庫(kù),用于實(shí)時(shí)手部檢測(cè)和手勢(shì)識(shí)別。它利用了機(jī)器學(xué)習(xí)模型來檢測(cè)手的位置和姿勢(shì),使得開發(fā)者可以在網(wǎng)頁(yè)和其他 JavaScript 環(huán)境中輕松地實(shí)現(xiàn)手勢(shì)控制和交互功能。
HandtrackJS 提供了對(duì)應(yīng)的案例,我們可以一起來看下對(duì)應(yīng)的效果:
根據(jù)示例 DEMO 我們可以發(fā)現(xiàn),利用 HandtrackJS 可以直接捕獲到人像與手勢(shì),同時(shí)還可以根據(jù)不同的手勢(shì)進(jìn)行識(shí)別,如下圖所示:
整個(gè)手勢(shì)的狀態(tài)被識(shí)別并分為了:open、pinch、closed 三種不同的狀態(tài)
02:實(shí)現(xiàn)一個(gè)動(dòng)作捕捉功能
整個(gè) HandtrackJS 使用也非常方便,根據(jù)官方文檔所示,我們可以分別通過 npm 或 cdn 的形式直接進(jìn)行安裝,這里為了方便,直接通過 cdn 的形式引入:
html 部分
<body class="bx--body p20">
<div class="mb10">
<button
id="trackbutton"
class="bx--btn bx--btn--secondary"
type="button"
disabled
>
點(diǎn)擊啟動(dòng)
</button>
</div>
<!-- 捕捉和展示實(shí)時(shí)視頻流 -->
<video
class="videobox canvasbox"
autoplay="autoplay"
id="myvideo"
style="display: none"
></video>
<!-- 視頻流渲染到 canvas 之中 -->
<canvas id="canvas" class="border canvasbox"></canvas>
<!-- cdn 引入 handtrack -->
<script src="lib/handtrack.min.js"></script>
<script src="js/index.js"></script>
</body>
在上面代碼中,核心有兩個(gè)標(biāo)簽:
video:它的主要作用是開啟一個(gè)視頻流,用來捕獲攝像頭圖像的。但是真正的展示并不是通過它來做,所以這里直接 display: none 隱藏即可
canvas:這是真正用來展示捕獲內(nèi)容的界面
JS 部分
搞定了 html 之后,接下來我們來處理 js 的內(nèi)容
1:利用 handTrack 加載模型
handTrack 是 HandtrackJS 的核心類,可以利用它的 load 方法加載配置、模型:
let model = null // 存儲(chǔ)加載的模型
let trackButton = document.getElementById('trackbutton') // 獲取按鈕元素
// 模型參數(shù)配置
const modelParams = {
maxNumBoxes: 20, // 最大檢測(cè)框數(shù)量
iouThreshold: 0.5, // IOU閾值
scoreThreshold: 0.6 // 分?jǐn)?shù)閾值
}
// 加載模型
handTrack.load(modelParams).then((lmodel) => {
model = lmodel // 保存加載的模型
trackButton.disabled = false // 啟用按鈕
})
2:按鈕按下,開啟視頻捕捉
監(jiān)聽 trackButton 按鈕的點(diǎn)擊行為,利用 video 開啟攝像頭
// 獲取HTML中的video和canvas元素
const video = document.getElementById('myvideo')
const canvas = document.getElementById('canvas')
const context = canvas.getContext('2d') // 獲取canvas的2D繪圖上下文
let isVideo = false // 標(biāo)記視頻是否正在播放
// 開始視頻捕捉
function startVideo() {
handTrack.startVideo(video).then(function (status) {
if (status) {
// 如果視頻啟動(dòng)成功
isVideo = true // 設(shè)置視頻狀態(tài)為正在播放
runDetection() // 開始檢測(cè)
} else {
// 視頻啟動(dòng)失敗處理(未實(shí)現(xiàn))
}
})
}
// 運(yùn)行檢測(cè)
function runDetection() {
model.detect(video).then((predictions) => {
model.renderPredictions(predictions, canvas, context, video) // 在canvas上繪制檢測(cè)結(jié)果
if (isVideo) {
requestAnimationFrame(runDetection) // 如果視頻正在播放,繼續(xù)檢測(cè)
}
})
}
// 切換視頻播放狀態(tài)
function toggleVideo() {
if (!isVideo) {
startVideo() // 如果視頻未播放,則啟動(dòng)視頻
} else {
handTrack.stopVideo(video) // 停止視頻
isVideo = false // 設(shè)置視頻狀態(tài)為未播放
}
}
// 按鈕點(diǎn)擊事件監(jiān)聽,點(diǎn)擊按鈕時(shí)切換視頻狀態(tài)
trackButton.addEventListener('click', function () {
toggleVideo()
})
至此整個(gè)的檢測(cè)就已經(jīng)全部完成了,是不是還是挺簡(jiǎn)單的。咱們來看看效果!
轉(zhuǎn)自公眾號(hào)程序員Sunday
該文章在 2024/7/24 16:53:33 編輯過