博客專(zhuān)欄

EEPW首頁(yè) > 博客 > ST-GCN 實(shí)現(xiàn)人體姿態(tài)行為分類(lèi)

ST-GCN 實(shí)現(xiàn)人體姿態(tài)行為分類(lèi)

發(fā)布人:AI科技大本營(yíng) 時(shí)間:2021-10-18 來(lái)源:工程師 發(fā)布文章

引用

人體行為識(shí)別是計(jì)算機(jī)視覺(jué)及機(jī)器學(xué)習(xí)方面的熱門(mén)研究領(lǐng)域。它在對(duì)視頻中的人類(lèi)行為進(jìn)行運(yùn)動(dòng)分析、行為識(shí)別乃至延伸至人機(jī)交互領(lǐng)域都有著非常廣泛的應(yīng)用。研究初期,人體行為識(shí)別主要是以基于靜態(tài)圖像為研究對(duì)象。通過(guò)提取靜態(tài)圖像中的人體動(dòng)作特征并對(duì)動(dòng)作進(jìn)行分類(lèi)。然而僅基于靜態(tài)圖像來(lái)進(jìn)行識(shí)別人體行為的局限性在于人體行為是連續(xù)、動(dòng)態(tài)的,單憑一張靜態(tài)圖像無(wú)法進(jìn)行判斷識(shí)別。而基于視頻為研究對(duì)象,可以將視頻看作連續(xù)靜態(tài)圖像的時(shí)間序列。近兩年,很多基于視頻為對(duì)象的人體行為識(shí)別取得了不錯(cuò)的成果,例如,Gao等人以多視角的視頻為基礎(chǔ)開(kāi)發(fā)出了一種自適應(yīng)融合和類(lèi)別級(jí)詞典學(xué)習(xí)模型。

在通常情況下,人體行為識(shí)別有著例如外觀、光流、身體骨骼和深度等多種模態(tài),人們可以通過(guò)這些模態(tài)建模并傳達(dá)重要信息進(jìn)而實(shí)現(xiàn)人體行為識(shí)別。近幾年,比較熱門(mén)的深度領(lǐng)域有著很多的成果,Kamel等人利用使用卷積神經(jīng)網(wǎng)絡(luò)從深度圖和姿勢(shì)數(shù)據(jù)中進(jìn)行人體行為識(shí)別。Ji等人利用深度圖來(lái)將骨骼信息嵌入從而達(dá)到對(duì)人體進(jìn)行分區(qū)的目的,以及Zhao等人提出了一種貝葉斯分層動(dòng)態(tài)模型用于人類(lèi)動(dòng)作識(shí)別也取得了不錯(cuò)的效果。而在這些模態(tài)當(dāng)中,人類(lèi)身體骨骼通常能與其他模態(tài)相輔相成并傳達(dá)重要信息。同時(shí)也因?yàn)楣趋佬畔⒌那逦庇^且不易受到人體外觀等其他因素的影響,具有良好的魯棒性。

基于骨架的人體行為識(shí)別方法因?qū)?fù)雜場(chǎng)景具有較強(qiáng)的魯棒性,因此近些年涌現(xiàn)很多基于骨架的動(dòng)作識(shí)別方法。一般分為兩種方法:

(1)基于人工特征選擇的方法,通過(guò)人工設(shè)定的特性來(lái)捕捉關(guān)節(jié)運(yùn)動(dòng)動(dòng)態(tài)。例如關(guān)節(jié)的相對(duì)位置、關(guān)節(jié)軌跡的協(xié)方差矩陣或是身體部分之間的平移旋轉(zhuǎn)等特性。

(2)深度學(xué)習(xí)方法,基于深度學(xué)習(xí)進(jìn)行骨架建模,端到端的動(dòng)作識(shí)別模型通過(guò)使用遞歸神經(jīng)網(wǎng)絡(luò)和臨時(shí)CNNs來(lái)學(xué)習(xí)。ST-GCN不同于這些方法,雖然強(qiáng)調(diào)了人體關(guān)節(jié)建模的重要性,但這些部分一般使用領(lǐng)域知識(shí)明確分配指定。ST-GCN將GCN應(yīng)用于基于骨架的人體行為識(shí)別系統(tǒng)中,在此基礎(chǔ)上加入了對(duì)識(shí)別人體行為非常重要的關(guān)節(jié)之間的空間關(guān)系這一因素,以人體關(guān)節(jié)為節(jié)點(diǎn),同時(shí)連接關(guān)節(jié)之間的自然聯(lián)系和相同關(guān)節(jié)的跨連續(xù)時(shí)間聯(lián)系,然后以此為基礎(chǔ)構(gòu)造多個(gè)時(shí)空?qǐng)D卷積層,沿時(shí)空維度進(jìn)行集成信息。

故本項(xiàng)目通過(guò)搭建ST-GCN實(shí)現(xiàn)對(duì)視頻時(shí)空流進(jìn)行姿態(tài)估計(jì)和行為分類(lèi)。最終可實(shí)現(xiàn)效果如下:

1.png

1、ST-GCN 介紹

ST-GCN是香港中文大學(xué)提出一種時(shí)空?qǐng)D卷積網(wǎng)絡(luò),可以用它進(jìn)行人類(lèi)行為識(shí)別。這種算法基于人類(lèi)關(guān)節(jié)位置的時(shí)間序列表示而對(duì)動(dòng)態(tài)骨骼建模,并將圖卷積擴(kuò)展為時(shí)空?qǐng)D卷積網(wǎng)絡(luò)而捕捉這種時(shí)空的變化關(guān)系。


1.1 模型通道

基于骨架的數(shù)據(jù)可以從動(dòng)作捕捉設(shè)備中獲得,也可以從視頻中獲得姿態(tài)估計(jì)算法。通常數(shù)據(jù)是一個(gè)坐標(biāo)系序列,每個(gè)坐標(biāo)系都有一組關(guān)節(jié)坐標(biāo)。ST-GCN就是構(gòu)建一個(gè)以關(guān)節(jié)為圖節(jié)點(diǎn),以人體結(jié)構(gòu)和時(shí)間為圖邊的自然連接為圖節(jié)點(diǎn)的時(shí)空?qǐng)D。ST-GCN的輸入是圖節(jié)點(diǎn)上的關(guān)節(jié)坐標(biāo)向量。這可以看作是對(duì)基于圖像的cnn的模擬,其中輸入是由駐留在2D圖像網(wǎng)格上的像素強(qiáng)度向量構(gòu)成的。對(duì)輸入數(shù)據(jù)進(jìn)行多層次的時(shí)空?qǐng)D卷積運(yùn)算,在圖上生成更高層次的特征圖。然后它將被標(biāo)準(zhǔn)的SoftMax分類(lèi)器分類(lèi)到相應(yīng)的動(dòng)作類(lèi)別。

2.png

1.2 骨骼圖結(jié)構(gòu)

骨骼序列通常由每一幀中每個(gè)人體關(guān)節(jié)的2D或3D坐標(biāo)表示。使用卷積進(jìn)行骨骼動(dòng)作識(shí)別,將所有關(guān)節(jié)的坐標(biāo)向量連接起來(lái),形成每幀的單一特征向量。

3.png

1.3 時(shí)空模型

針對(duì)空間時(shí)間建模。在構(gòu)建了空間圖之后,需要在骨骼序列中建模時(shí)空動(dòng)態(tài)。在構(gòu)建圖的時(shí)候,圖的時(shí)間方面是通過(guò)在連續(xù)的框架中連接相同的關(guān)節(jié)來(lái)構(gòu)建的。從而能夠定義一個(gè)非常簡(jiǎn)單的策略,將空間圖CNN擴(kuò)展到空間時(shí)域。

2、模型實(shí)驗(yàn)

2.1 環(huán)境搭建

1、首先下載好完整無(wú)誤配置好的代碼(包括模型等等,見(jiàn)文末)。

2、搭建最新版的openpose環(huán)境,并使用cmake編譯。

4.png

3、配置好python的cuda環(huán)境,以及opencv等基礎(chǔ)環(huán)境。

4、使用命令

“python main.py demo --openpose E:/cmake/environment/x64/Release --video 2.mp4”進(jìn)行測(cè)試生成結(jié)果。

其中“E:/cmake/environment/x64/Release”需要改成自己的openpose環(huán)境。


2.2 主函數(shù)調(diào)用

其中主函數(shù)通過(guò)使用processors管理的設(shè)定好的分類(lèi)識(shí)別、輸入輸出管理等程序內(nèi)部函數(shù)進(jìn)行整個(gè)程序的布置。

代碼如下:

import argparse
import sys
import torchlight
from torchlight import import_class
if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Processor collection')
    processors = dict()
    processors['recognition'] = import_class('processor.recognition.REC_Processor')
    processors['demo'] = import_class('processor.demo.Demo')
    subparsers = parser.add_subparsers(dest='processor')
    for k, p in processors.items():
        subparsers.add_parser(k, parents=[p.get_parser()])
    arg = parser.parse_args()
    Processor = processors[arg.processor]
    p = Processor(sys.argv[2:])
    p.start()

5.png

2.3 模型網(wǎng)絡(luò)

通過(guò)調(diào)用空間-時(shí)間圖卷積網(wǎng)絡(luò)建立這個(gè)網(wǎng)絡(luò)模型。其中參數(shù)in_channels (int)為輸入數(shù)據(jù)中的通道數(shù);

num_class (int)表示用于分類(lèi)任務(wù)的類(lèi)的數(shù)量;

graph_args (dict)表示構(gòu)建圖的參數(shù);

edge_importance_weighting (bool)表示如果“True”,添加一個(gè)可學(xué)習(xí)的對(duì)圖的邊進(jìn)行重要性加權(quán)。代碼如下:

def __init__(self, in_channels, num_class, graph_args,
             edge_importance_weighting, **kwargs):
    super().__init__()
    self.graph = Graph(**graph_args)
    A = torch.tensor(self.graph.A, dtype=torch.float32, requires_grad=False)
    self.register_buffer('A', A)
    spatial_kernel_size = A.size(0)
    temporal_kernel_size = 9
    kernel_size = (temporal_kernel_size, spatial_kernel_size)
    self.data_bn = nn.BatchNorm1d(in_channels * A.size(1))
    kwargs0 = {k: v for k, v in kwargs.items() if k != 'dropout'}
    self.st_gcn_networks = nn.ModuleList((
        st_gcn(in_channels, 64, kernel_size, 1, residual=False, **kwargs0),
        st_gcn(64, 64, kernel_size, 1, **kwargs),
        st_gcn(64, 64, kernel_size, 1, **kwargs),
        st_gcn(64, 64, kernel_size, 1, **kwargs),
        st_gcn(64, 128, kernel_size, 2, **kwargs),
        st_gcn(128, 128, kernel_size, 1, **kwargs),
        st_gcn(128, 128, kernel_size, 1, **kwargs),
        st_gcn(128, 256, kernel_size, 2, **kwargs),
        st_gcn(256, 256, kernel_size, 1, **kwargs),
        st_gcn(256, 256, kernel_size, 1, **kwargs),
    ))

6.png

2.4 ST-GCN網(wǎng)絡(luò)建立

建立ST-GCN網(wǎng)絡(luò)模型,其中in_channels (int)表示輸入序列數(shù)據(jù)中的通道數(shù);

out_channels (int)表示卷積產(chǎn)生的通道數(shù);

kernel_size (tuple)為時(shí)態(tài)卷積核和圖卷積核的大小;

stride (int,可選)為時(shí)間卷積的步幅。默認(rèn)值:1;

dropout (int,可選)為最終輸出的輟學(xué)率。默認(rèn)值:0;

residual (bool,可選)表示如果”True “,應(yīng)用殘留機(jī)制。默認(rèn)值:“True”。

代碼如下:

   

def __init__(self,
                 in_channels,
                 out_channels,
                 kernel_size,
                 stride=1,
                 dropout=0,
                 residual=True):
        super().__init__()
        assert len(kernel_size) == 2
        assert kernel_size[0] % 2 == 1
        padding = ((kernel_size[0] - 1) // 2, 0)
        self.gcn = ConvTemporalGraphical(in_channels, out_channels,
                                         kernel_size[1])
        self.tcn = nn.Sequential(
            nn.BatchNorm2d(out_channels),
            nn.ReLU(inplace=True),
            nn.Conv2d(
                out_channels,
                out_channels,
                (kernel_size[0], 1),
                (stride, 1),
                padding,
            ),
            nn.BatchNorm2d(out_channels),
            nn.Dropout(dropout, inplace=True),
        )
        if not residual:
            self.residual = lambda x: 0
        elif (in_channels == out_channels) and (stride == 1):
            self.residual = lambda x: x

運(yùn)行過(guò)程如下可見(jiàn),在這里通過(guò)雙擊“test.bat”即可直接運(yùn)行:

7.png8.png

完整代碼:

鏈接:

https://pan.baidu.com/s/1Ht7Mr6hJMt5oUKu6ue05fw

提取碼:0nqh

*博客內(nèi)容為網(wǎng)友個(gè)人發(fā)布,僅代表博主個(gè)人觀點(diǎn),如有侵權(quán)請(qǐng)聯(lián)系工作人員刪除。



關(guān)鍵詞: AI

相關(guān)推薦

技術(shù)專(zhuān)區(qū)

關(guān)閉