色婷婷AⅤ一区二区三区|亚洲精品第一国产综合亚AV|久久精品官方网视频|日本28视频香蕉

          "); //-->

          博客專欄

          EEPW首頁(yè) > 博客 > 教你一招!如何用技術(shù)實(shí)現(xiàn)時(shí)序羽毛球動(dòng)作預(yù)測(cè)

          教你一招!如何用技術(shù)實(shí)現(xiàn)時(shí)序羽毛球動(dòng)作預(yù)測(cè)

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

          作者 | 李秋鍵

          出品 | AI科技大本營(yíng)(ID:rgznai100)

          引言:隨著計(jì)算機(jī)視覺(jué)領(lǐng)域中視頻動(dòng)作識(shí)別技術(shù)的發(fā)展,體育動(dòng)作識(shí)別研究在統(tǒng)計(jì)運(yùn)動(dòng)動(dòng)作特點(diǎn)、運(yùn)動(dòng)學(xué)研究、體育教學(xué)展示等方面的應(yīng)用越來(lái)越廣泛。對(duì)于各種球類比賽,依據(jù)比賽類型,  可以將它們的結(jié)構(gòu)特征分為時(shí)間和比分兩種類型。時(shí)間類型的體育項(xiàng)目如籃球、足球和橄欖球等,在比賽過(guò)程中沒(méi)有屬于某一方球員專門的區(qū)域,雙方球員在位置上處于混合交錯(cuò)狀態(tài),在一定時(shí)間間隔內(nèi)通過(guò)團(tuán)隊(duì)合作來(lái)取得比賽的勝利。比分類型的項(xiàng)目包括網(wǎng)球、羽毛球、乒乓球等,比賽時(shí)雙方球員始終在屬于自己的區(qū)域內(nèi)運(yùn)動(dòng),和對(duì)手在位置上處于對(duì)峙狀態(tài),這種類型通常是球員經(jīng)過(guò)自身水平的發(fā)揮來(lái)贏取比賽。觀看該類比賽時(shí),觀眾往往會(huì)關(guān)注球員的動(dòng)作特點(diǎn)。

          在羽毛球比賽中,運(yùn)動(dòng)員的動(dòng)作姿態(tài)信息可為理解比賽過(guò)程、發(fā)現(xiàn)球員動(dòng)作特點(diǎn)提供重要線索。羽毛球運(yùn)動(dòng)與排球、網(wǎng)球和乒乓球運(yùn)動(dòng)特點(diǎn)相似,均滿足馬爾可夫過(guò)程條件,比賽中運(yùn)動(dòng)員的每次擊球動(dòng)作在瞬間完成。為了更好地輔助教練或觀眾理解并把握羽毛球視頻中球員動(dòng)作等關(guān)鍵信息,實(shí)現(xiàn)對(duì)羽毛球運(yùn)動(dòng)員的動(dòng)作智能識(shí)別是有意義的。

          目前計(jì)算機(jī)視覺(jué)技術(shù)在視頻動(dòng)作識(shí)別方向的相關(guān)研究已經(jīng)取得重大突破,但大多是針對(duì)不同日常動(dòng)作的廣義性動(dòng)作識(shí)別,缺乏針對(duì)羽毛球視頻動(dòng)作識(shí)別的相關(guān)研究。若能對(duì)羽毛球視頻中的擊球動(dòng)作進(jìn)行時(shí)序定位并且能比較準(zhǔn)確地判斷出羽毛球視頻中的擊球動(dòng)作類型,則可為觀眾提供各類擊球動(dòng)作類型的視頻集錦。此外,在體育視頻分析領(lǐng)域中,也可根據(jù)羽毛球的動(dòng)作分類遷移至網(wǎng)球等項(xiàng)目,因它們的比賽形式與羽毛球有許多相同之處,更容易進(jìn)行運(yùn)動(dòng)特征的遷移。

          故今天我們將使用torch搭建LSTM實(shí)現(xiàn)對(duì)羽毛球動(dòng)作的實(shí)時(shí)訓(xùn)練并預(yù)測(cè),本文將其分為數(shù)據(jù)集制作、數(shù)據(jù)處理、模型搭建以及可視化幾個(gè)步驟,模型在訓(xùn)練2000輪實(shí)現(xiàn)效果如下如下(左側(cè)為當(dāng)前動(dòng)作,右側(cè)為預(yù)測(cè)出的未來(lái)10幀后的羽毛球動(dòng)作): 

          1.png


          羽毛球動(dòng)作識(shí)別發(fā)展介紹

          針對(duì)羽毛球的擊球動(dòng)作識(shí)別,Chu 等人采用了基于姿態(tài)識(shí)別的方法,從球員的邊界框提取方向梯度直方圖 HOG,并在 HOG 基礎(chǔ)上基于支持向量機(jī) SVM對(duì)擊球動(dòng)作進(jìn)行分類,但其使用的訓(xùn)練和測(cè)試數(shù)據(jù)是擊球瞬間的單個(gè)圖像,而對(duì)于擊球姿態(tài)十分相似的不同擊球動(dòng)作很可能會(huì)混淆,如殺球與高遠(yuǎn)球,平抽與吊球。Careelmont對(duì)壓縮羽毛球視頻的鏡頭進(jìn)行分類,并通過(guò)檢測(cè)羽毛球的移動(dòng)軌跡來(lái)識(shí)別擊球動(dòng)作。Ramasinghe 等提出了一種基于密集軌跡和軌跡對(duì)齊的 HOG 特征的羽毛球視頻動(dòng)作識(shí)別方法,將球員擊球動(dòng)作分為正手擊球、反手擊球、殺球和其他類型,但 HOG 本身不具有尺度不變性,且由于梯度的性質(zhì),HOG 對(duì)噪點(diǎn)相當(dāng)敏感。楊靜等人在體育視頻時(shí)常具有像素品質(zhì)欠佳、非靜態(tài)視頻及圖像的分辨率較低的問(wèn)題背景下,提出一種基于光流的運(yùn)動(dòng)描述符,并通過(guò)檢測(cè)關(guān)鍵音頻元素捕獲球員的揮拍擊球圖像,最后采用支持向量機(jī),對(duì)運(yùn)動(dòng)員的三種典型揮拍動(dòng)作——上揮拍、左揮拍、右揮拍進(jìn)行分類。Wang 等提出了一種基于身體傳感器網(wǎng)絡(luò)的雙層隱馬爾可夫模型分類算法來(lái)識(shí)別羽毛球擊球類型,但其針對(duì)于傳感器捕獲的擊球狀態(tài)數(shù)據(jù),并不適用于對(duì)視頻中的羽毛球動(dòng)作進(jìn)行有效識(shí)別。Rahmad 等人比較了 AlexNet、GoogLeNet、VggNet-16 和 VggNet-19 四種不同的深度卷積預(yù)訓(xùn)練模型在對(duì)羽毛球比賽圖像進(jìn)行分類時(shí)的表現(xiàn),以識(shí)別運(yùn)動(dòng)員的不同動(dòng)作,最終表明 GoogLeNet 的分類準(zhǔn)確率最高,但其針對(duì)的仍是羽毛球比賽擊球瞬間的靜態(tài)圖像,未能對(duì)羽毛球動(dòng)作元視頻進(jìn)行動(dòng)作分類識(shí)別。


          羽毛球動(dòng)作預(yù)測(cè)搭建

          為了更好的研究對(duì)羽毛球視頻動(dòng)作識(shí)別,我們這里實(shí)現(xiàn)對(duì)羽毛球視頻球員擊球動(dòng)作進(jìn)行時(shí)域定位。

          這里程序的設(shè)計(jì)分為以下幾個(gè)步驟,分別為數(shù)據(jù)集制作、數(shù)據(jù)處理、模型搭建以及可視化幾個(gè)步驟。

          2.1 骨骼數(shù)據(jù)集提取

          這里我們將準(zhǔn)備好的視頻素材放置項(xiàng)目文件下,使用data_deal.py提取骨骼點(diǎn)存儲(chǔ)。針對(duì)2.mp4視頻文件使用openpose逐幀提取骨骼數(shù)據(jù)并存入txt文件中。代碼如下:

          parser = argparse.ArgumentParser(description='Action Recognition by OpenPose')
          parser.add_argument('--video', help='Path to video file.')
          args = parser.parse_args()
          # 導(dǎo)入相關(guān)模型
          estimator = load_pretrain_model('VGG_origin')
          # 參數(shù)初始化
          realtime_fps = '0.0000'
          start_time = time.time()
          fps_interval = 1
          fps_count = 0
          run_timer = 0
          frame_count = 0
          # 讀寫視頻文件
          cap =cv.VideoCapture("2.mp4")
          #video_writer = set_video_writer(cap, write_fps=int(7.0))
          # 保存關(guān)節(jié)數(shù)據(jù)的txt文件,用于訓(xùn)練過(guò)程(for training)
          f = open('origin_data.txt', 'a+')
          num=0
          while cv.waitKey(1) < 0:
              has_frame, show = cap.read()
              if has_frame:
                  fps_count += 1
                  frame_count += 1
                  # pose estimation
                  humans = estimator.inference(show)
                  # get pose info
                  pose = TfPoseVisualizer.draw_pose_rgb(show, humans)  # return frame, joints, bboxes, xcenter
                  #video_writer.write(show)
                  if len(pose[-1])==36:
                      num+=1
                      print(num)
                      # 采集數(shù)據(jù),用于訓(xùn)練過(guò)程(for training)
                      joints_norm_per_frame = np.array(pose[-1]).astype(np.str)
                      f.write(' '.join(joints_norm_per_frame))
                      f.write('\n')
                  cv.imshow("tets",show)
                  cv.waitKey(1)
              else:
                  break
          cap.release()
          f.close()

          2.png

          2.2 數(shù)據(jù)處理

          通過(guò)對(duì)數(shù)據(jù)觀察發(fā)現(xiàn),由于拍攝的視頻遮擋較多,部分肢體提取為0會(huì)較大的影響模型效果,這里將這幾個(gè)部位去除。代碼如下:

          f=open('origin_data.txt')
          text=f.read()
          f.close()
          datasets=[]
          text=text.split("\n")
          for i in text:
              temp=i.split(" ")
              temp1=[]
              state=True
              for j in range(len(temp)):
                  try:
                      temp1.append(float(temp[j]))
                  except:
                      pass
              if len(temp1) == 36:
                  temp1.pop(28)
                  temp1.pop(28)
                  temp1.pop(30)
                  temp1.pop(30)
                  for t in temp1:
                      if t==0.:
                          state=False
                  if state:
                      datasets.append(temp1)
          flap=30#
          x_data = datasets[:-1-flap]
          y_data=datasets[flap:-1]
          n=len(x_data)

          2.3 LSTM模型搭建和訓(xùn)練

          這里設(shè)置LSTM層神經(jīng)元64,設(shè)置損失函數(shù)為為MSE誤差函數(shù),優(yōu)化器為adam優(yōu)化器,迭代次數(shù)為100輪,并將其損失圖動(dòng)態(tài)繪制。代碼如下:

          times=[]
          losss=[]
          nums=0
          Epoch=100
          correct=0
          for k in range(Epoch):
              for i in range(n):
                  x_np=np.array(x_data[i],dtype='float32')#此時(shí)x的維度為1維
                  y_np=np.array(y_data[i],dtype='float32')
                  #需要把x維度擴(kuò)充到三個(gè)維度,[batch,time_step,input_size]
                  x=variable(torch.from_numpy(x_np[np.newaxis,:,np.newaxis]))
                  y=variable(torch.from_numpy(y_np[np.newaxis,:,np.newaxis]))
                  prediction=rnn(x)
                  if prediction.flatten().data.numpy().any==y.flatten().data.numpy().any:
                      correct+=1
                  loss=loss_func(prediction,y)
                  optim.zero_grad()
                  loss.backward()
                  optim.step()
                  nums += 1
                  accuracy=float(correct/nums)
          print("|Epoch:",k,"|step:",nums,"|loss:",loss.data.numpy(),"|accuracy:%.4f"%accuracy)
                  times.append(nums)
                  losss.append(float(loss.data))
                  plt.plot(times,losss)
                  plt.pause(0.05)

          3.png

          2.4 模型可視化

          根據(jù)預(yù)測(cè)出的骨骼坐標(biāo),定義基本骨骼連接方法和顏色,同時(shí)這里還要考慮到已經(jīng)去除的骨骼,最終代碼如下:

          import cv2
          def draw(test):
              back=cv2.imread("back.jpg")
              image_h, image_w ,c= back.shape
              centers = {}
              CocoColors = [[255, 0, 0], [255, 85, 0], [255, 170, 0], [255, 255, 0], [170, 255, 0], [85, 255, 0], [0, 255, 0],
                            [0, 255, 85], [0, 255, 170], [0, 255, 255], [0, 170, 255], [0, 85, 255], [0, 0, 255], [85, 0, 255],
                            [170, 0, 255], [255, 0, 255], [255, 0, 170], [255, 0, 85], [255, 0, 85]]
              CocoPairs = [
                  (1, 2), (1, 5), (2, 3), (3, 4), (5, 6), (6, 7), (1, 8), (8, 9), (9, 10), (1, 11),
                  (11, 12), (12, 13), (1, 0), (0, 14), (14, 15),  (5, 15)
              ]#修改了
              for pos in range(0,16):
                  center = (int((test[2*pos] * (image_w//2) + 0.5)), int((test[2*pos+1] * (image_h//2) )))
                  centers[pos] = center
                  cv2.circle(back, center, 3, CocoColors[pos], thickness=3, lineType=8, shift=0)
              for pair_order, pair in enumerate(CocoPairs):
                  cv2.line(back, centers[pair[0]], centers[pair[1]], CocoColors[pair_order], 3)

          4.png

          完整代碼:

          https://download.csdn.net/download/qq_42279468/72398200

          李秋鍵,CSDN博客專家,CSDN達(dá)人課作者。碩士在讀于中國(guó)礦業(yè)大學(xué),開(kāi)發(fā)有taptap競(jìng)賽獲獎(jiǎng)等。

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

          紅外遙控器相關(guān)文章:紅外遙控器原理
          聲控?zé)粝嚓P(guān)文章:聲控?zé)粼?/a>



          相關(guān)推薦

          技術(shù)專區(qū)

          關(guān)閉