碼農(nóng)也來玩奧運(yùn)開幕式“超級(jí)變變變”!相機(jī)動(dòng)捕,實(shí)時(shí)轉(zhuǎn)換賽事圖標(biāo),項(xiàng)目開源可試玩
大家都有在看奧運(yùn)會(huì)嗎?
根據(jù)發(fā)稿前的數(shù)據(jù)統(tǒng)計(jì),目前中國(guó)金牌數(shù)量24,位列第一,獎(jiǎng)牌總數(shù)51,僅次于美國(guó)的59,位列第二。
在為運(yùn)動(dòng)員們加油助威的同時(shí),我們不妨再回顧一下本屆奧運(yùn)會(huì)開幕式。
7月23日,東京時(shí)間晚上8點(diǎn),延期一年的東京奧運(yùn)會(huì)終于開幕,本應(yīng)座無虛席可容納6.8萬人的看臺(tái)上,因防疫需要幾乎空無一人。
在開幕儀式上,最讓人驚喜的節(jié)目之一便是將日本老牌節(jié)目《超級(jí)變變變》的風(fēng)格搬運(yùn)到了各個(gè)項(xiàng)目圖標(biāo)中,表演者們相互配合,用道具搭配肢體動(dòng)作,展現(xiàn)了乒乓球、射擊、鐵人三項(xiàng)等50個(gè)圖標(biāo)。
其實(shí),在1964年的東京奧運(yùn)會(huì)上,日本人就首次發(fā)明了體育項(xiàng)目圖標(biāo),隨后這也逐漸成為奧運(yùn)會(huì)的傳統(tǒng)之一,得以延續(xù)。
借著奧運(yùn)熱潮,不少象形文字項(xiàng)目也受到了關(guān)注。
比如,日本一位叫做高橋的嵌入式工程師就親自開發(fā)了一個(gè)軟件,通過相機(jī)捕捉動(dòng)作和姿勢(shì),然后把它們變成奧運(yùn)風(fēng)格的象形動(dòng)圖,就像這樣:
最終識(shí)別效果如下圖所示,文摘菌只能說,都是“動(dòng)作不夠,機(jī)器來湊”啊。
手把手教你把自己變成象形動(dòng)圖
目前,該項(xiàng)目已經(jīng)在GitHub上開源了。
GitHub鏈接:
https://github.com/Kazuhito00/Tokyo2020-Pictogram-using-MediaPipe
首先,我們需要?jiǎng)?chuàng)建一個(gè)GitHub的存儲(chǔ)庫(kù)。
$ git clone https://github.com/Kazuhito00/Tokyo2020-Pictogram-using-MediaPipe.git $ cd Tokyo2020-Pictogram-using-MediaPipe
然后,需要?jiǎng)?chuàng)建一個(gè)Python虛擬環(huán)境,并安裝所需要的庫(kù)。
$ python -m venv .venv $ source .venv/bin/activate $ pip install mediapipe opencv-python
準(zhǔn)備工作做完之后,可能會(huì)遇到在本地代碼無效的情況,可以對(duì)VideoCapture的寬度和高度適當(dāng)做出調(diào)整。
- parser.add_argument("--width", help='cap width', type=int, default=640) - parser.add_argument("--height", help='cap height', type=int, default=360) + parser.add_argument("--width", help='cap width', type=int, default=960) + parser.add_argument("--height", help='cap height', type=int, default=540)
隨后就可以運(yùn)行該項(xiàng)目了。
$ python main.py
這時(shí)候你就會(huì)發(fā)現(xiàn),相機(jī)識(shí)別出來的圖變成了這個(gè)樣子:
最后,高橋也大方地給出了試玩地址,感興趣的同學(xué)可別錯(cuò)過了:
試玩地址:
https://pictogram-san.com/
象形動(dòng)圖升級(jí):霹靂舞也能玩出花!
這么有意思的項(xiàng)目?jī)H限于此未免有些可惜了。
于是,一位叫做巖田智哉的同學(xué)就對(duì)高橋的程序進(jìn)行了進(jìn)一步的改進(jìn)和完善,比如說,用來跳霹靂舞。
由于身體機(jī)能的下降,巖田放棄了在轉(zhuǎn)動(dòng)攝像機(jī)時(shí)實(shí)時(shí)制作象形圖,轉(zhuǎn)而嘗試通過讓程序讀取視頻,來制作象形圖。
考慮到這點(diǎn)后,他做出了如下修改,把程序改成了由命令行參數(shù)傳遞的視頻文件的象形圖,同時(shí)還刪除了反轉(zhuǎn)視頻的邏輯。
- parser.add_argument("--device", type=int, default=0) + parser.add_argument('--file', type=str, required=True, help="video file path") parser.add_argument("--width", help='cap width', type=int, default=960) parser.add_argument("--height", help='cap height', type=int, default=540) @@ -43,7 +43,7 @@ def main(): # 引數(shù)解析 ################################################################# args = get_args() - cap_device = args.device + cap_file = args.file cap_width = args.width cap_height = args.height @@ -55,7 +55,7 @@ def main(): rev_color = args.rev_color # カメラ準(zhǔn)備 ############################################################### - cap = cv.VideoCapture(cap_device) + cap = cv.VideoCapture(cap_file) cap.set(cv.CAP_PROP_FRAME_WIDTH, cap_width) cap.set(cv.CAP_PROP_FRAME_HEIGHT, cap_height) @@ -86,7 +86,7 @@ def main(): ret, image = cap.read() if not ret: break - image = cv.flip(image, 1) # ミラー表示 + #image = cv.flip(image, 1) # ミラー表示 debug_image01 = copy.deepcopy(image) debug_image02 = np.zeros((image.shape[0], image.shape[1], 3), np.uint8) cv.rectangle(debug_image02, (0, 0), (image.shape[1], image.shape[0]),
然后就能得到這樣的視頻識(shí)別效果:
想看動(dòng)圖?滿足你:
怎么樣,是不是覺得竟然還有一絲酷炫?
最后,巖田表示,既然都做到這一步了,我們就順理成章地再添加邏輯,把這個(gè)栩栩如生的視頻保存為一個(gè)單獨(dú)的mp4文件。
第一次加載作為命令行參數(shù)傳遞的視頻文件時(shí),需要?jiǎng)?chuàng)建一個(gè)文件名為<UTC時(shí)間戳>-pictgram-output.mp4的視頻文件,并在每次循環(huán)后添加一個(gè)進(jìn)程來導(dǎo)出象形圖象即可。
#!/usr/bin/env python # -*- coding: utf-8 -*- import copy +from datetime import datetime import math import argparse @@ -79,6 +80,8 @@ def main(): color = (100, 33, 3) bg_color = (255, 255, 255) + is_first = True + output_video = None while True: display_fps = cvFpsCalc.get() @@ -86,6 +89,7 @@ def main(): ret, image = cap.read() if not ret: break + #image = cv.flip(image, 1) # ミラー表示 debug_image01 = copy.deepcopy(image) debug_image02 = np.zeros((image.shape[0], image.shape[1], 3), np.uint8) @@ -125,7 +129,18 @@ def main(): cv.imshow('Tokyo2020 Debug', debug_image01) cv.imshow('Tokyo2020 Pictogram', debug_image02) + if is_first: + fmt = cv.VideoWriter_fourcc('m', 'p', '4', 'v') + fps = cap.get(cv.CAP_PROP_FPS) + now = datetime.now().strftime('%Y-%m-%d-%H%M%S') + output_video = cv.VideoWriter(f'{now}-pictgram-output.mp4', fmt, fps, (debug_image02.shape[1], debug_image02.shape[0])) + is_first = False + + output_video.write(debug_image02) + cap.release() + if output_video: + output_video.release() cv.destroyAllWindows()
基于機(jī)器學(xué)習(xí)技術(shù)的手勢(shì)識(shí)別算法MediaPipe
據(jù)了解,高橋所使用的為谷歌開源機(jī)器學(xué)習(xí)工具“MediaPipe”。
MediaPipe是一種基于機(jī)器學(xué)習(xí)技術(shù)的手勢(shì)識(shí)別算法,其特點(diǎn)是準(zhǔn)確率高,支持五指和手勢(shì)追蹤,可根據(jù)一幀圖像推斷出單手21個(gè)立體節(jié)點(diǎn)。
與目前市面上較先進(jìn)的手勢(shì)識(shí)別技術(shù)相比,MediaPipe不需要依賴臺(tái)式機(jī),在手機(jī)上就能進(jìn)行實(shí)時(shí)追蹤,還支持同時(shí)追蹤多只手,識(shí)別遮擋等。
MediaPipe框架有3個(gè)模型組成,包括:手掌識(shí)別模型BlazePalm(用于識(shí)別手的整體框架和方向)、Landmark模型(識(shí)別立體手部節(jié)點(diǎn))、手勢(shì)識(shí)別模型(將識(shí)別到的節(jié)點(diǎn)分類成一系列手勢(shì))。
其中,BlazePalm是一個(gè)可識(shí)別單幀圖像的模型,主要為L(zhǎng)andmark模型提供準(zhǔn)確剪裁的手掌圖像,在經(jīng)過訓(xùn)練后手掌識(shí)別準(zhǔn)確率可達(dá)95.7%。這大大降低了對(duì)旋轉(zhuǎn)、轉(zhuǎn)化和縮放等數(shù)據(jù)增強(qiáng)方式的依賴,讓算法將更多計(jì)算能力用在提高預(yù)測(cè)準(zhǔn)確性上。
此外,BlazePalm可識(shí)別多種不同手掌大小,還能識(shí)別手部遮擋,并且能通過對(duì)手臂、軀干或個(gè)人特征等的識(shí)別來準(zhǔn)確定位手部。
Landmark模型在BlazePalm基礎(chǔ)上識(shí)別到的21個(gè)立體節(jié)點(diǎn)坐標(biāo),這些節(jié)點(diǎn)之間的位置遮擋也可被識(shí)別。
通過手勢(shì)識(shí)別模型,從Landmark提取的數(shù)據(jù)來推斷每根手指伸直或彎曲等動(dòng)作,接著將這些動(dòng)作與預(yù)設(shè)的手勢(shì)匹配,以預(yù)測(cè)基礎(chǔ)的靜態(tài)手勢(shì)。預(yù)設(shè)手勢(shì)包括美國(guó)、歐洲、中國(guó)通用手勢(shì),以及豎大拇指、握拳、OK、“蜘蛛俠”等。
對(duì)于MediaPipe,更為主流是將其作為手語識(shí)別和翻譯的輔助方式,如果再結(jié)合AR/VR頭顯的輸入方式,或許可以進(jìn)一步提升聽障人士溝通效率。
當(dāng)然,我們也十分期待高橋這種腦洞大開的項(xiàng)目。
*博客內(nèi)容為網(wǎng)友個(gè)人發(fā)布,僅代表博主個(gè)人觀點(diǎn),如有侵權(quán)請(qǐng)聯(lián)系工作人員刪除。