溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

如何用python實(shí)現(xiàn)專業(yè)評(píng)估舞蹈程序

發(fā)布時(shí)間:2020-06-24 14:32:06 來(lái)源:億速云 閱讀:323 作者:清晨 欄目:編程語(yǔ)言

小編給大家分享一下如何用python實(shí)現(xiàn)專業(yè)評(píng)估舞蹈程序,希望大家閱讀完這篇文章后大所收獲,下面讓我們一起去探討方法吧!

整體實(shí)現(xiàn)思路

主要以安崎小甜心的主題曲直拍視頻作為標(biāo)準(zhǔn)視頻,謝可寅shaking的主題曲直拍視頻作為測(cè)試視頻

1、將標(biāo)準(zhǔn)視頻進(jìn)行爬取,將視頻逐幀讀取成圖片;

2、由于圖片背景光線不太利于關(guān)鍵點(diǎn)捕抓,利用deeplabv3p_xception65_humanseg進(jìn)行摳圖處理;

3、基于pose_resnet50_mpii模型進(jìn)行關(guān)鍵點(diǎn)檢測(cè)并存儲(chǔ)檢測(cè)結(jié)果;

4、然后對(duì)測(cè)試視頻作同樣處理存儲(chǔ)檢測(cè)結(jié)果;

5、基于單通道的直方圖對(duì)標(biāo)準(zhǔn)檢測(cè)結(jié)果集以及測(cè)試檢測(cè)結(jié)果集進(jìn)行圖片相似度計(jì)算,取結(jié)果均值作為選手的主題曲實(shí)力值;

6、將獲取的實(shí)力值合成到選手圖片并輸出

7、爬取微博測(cè)試選手相關(guān)評(píng)論,統(tǒng)計(jì)高頻詞輸出圖

8、對(duì)評(píng)論進(jìn)行情感分析,輸出總體評(píng)論積極與消極的對(duì)比餅圖

提前披露效果

看了那么長(zhǎng)我的肺腑之言,來(lái)看點(diǎn)效果,提升閱讀欲望

首先我們接下來(lái)會(huì)用人體關(guān)鍵點(diǎn)識(shí)別模型去識(shí)別動(dòng)作,識(shí)別的效果大概是這樣的,可以看到我們把安崎小甜心的四肢都能識(shí)別到。

如何用python實(shí)現(xiàn)專業(yè)評(píng)估舞蹈程序

然后為了方便比對(duì),我們直接把四肢關(guān)鍵點(diǎn)畫(huà)線部分單獨(dú)提取出來(lái),方便后面對(duì)比

對(duì)比項(xiàng):

如何用python實(shí)現(xiàn)專業(yè)評(píng)估舞蹈程序

計(jì)算每一幀的對(duì)比結(jié)果,得出評(píng)估分值,合成到選手圖片上

如何用python實(shí)現(xiàn)專業(yè)評(píng)估舞蹈程序

最后通過(guò)爬取微博評(píng)論,經(jīng)過(guò)LSTM模型進(jìn)行情感分析后,得出選手的大眾好感度對(duì)比

如何用python實(shí)現(xiàn)專業(yè)評(píng)估舞蹈程序

舞蹈實(shí)力評(píng)估

舞蹈實(shí)力評(píng)估主要對(duì)選手的舞蹈動(dòng)作進(jìn)行關(guān)鍵點(diǎn)檢測(cè)與標(biāo)準(zhǔn)的動(dòng)作進(jìn)行對(duì)比,得出相似度,計(jì)算每一幀的動(dòng)作相似度均值,得出選手舞蹈實(shí)力評(píng)估值。

模型介紹

主要使用的模型是pose_resnet50_mpii

人體骨骼關(guān)鍵點(diǎn)檢測(cè)(Pose Estimation) 是計(jì)算機(jī)視覺(jué)的基礎(chǔ)性算法之一,

在諸多計(jì)算機(jī)視覺(jué)任務(wù)起到了基礎(chǔ)性的作用,如行為識(shí)別、人物跟蹤、步態(tài)識(shí)別等相關(guān)領(lǐng)域。

具體應(yīng)用主要集中在智能視頻監(jiān)控,病人監(jiān)護(hù)系統(tǒng),人機(jī)交互,虛擬現(xiàn)實(shí),人體動(dòng)畫(huà),智能家居,智能安防,運(yùn)動(dòng)員輔助訓(xùn)練等等。

環(huán)境準(zhǔn)備

終端下載最新版的paddlehub以及paddlepaddle

pip install --upgrade paddlepaddle
pip install --upgrade paddlehub

引入庫(kù)

#相關(guān)庫(kù)的導(dǎo)入
import os
import cv2
import paddlehub as hub
from moviepy.editor import *
from matplotlib import pyplot as plt
import numpy as np  
import matplotlib.pyplot as plt 
import matplotlib.image as mpimg 
from PIL import ImageFont, ImageDraw, Image
import requests

打開(kāi)終端下載模型

hub install pose_resnet50_mpii

引入模型

pose_resnet50_mpii = hub.Module(name="pose_resnet50_mpii")

人體骨骼關(guān)鍵點(diǎn)檢測(cè)

定義數(shù)據(jù)轉(zhuǎn)化格式

函數(shù)change_data(result)

輸入?yún)?shù):人體骨骼關(guān)鍵點(diǎn)檢測(cè)模型的輸出結(jié)果

輸出參數(shù):關(guān)于人體關(guān)鍵點(diǎn)的全局變量

函數(shù)功能 :將位置點(diǎn)預(yù)測(cè)模型輸出的數(shù)據(jù)形式轉(zhuǎn)為預(yù)期的數(shù)據(jù)

def change_data(result):
  global left_ankle,left_knee,left_hip,right_hip,right_knee,right_ankle,pelvis,thorax,upper_neck
  global right_wrist,right_elbow,right_shoulder,left_shoulder,left_elbow,left_wrist,head_top
  left_ankle = result['data']['left_ankle']
  left_knee = result['data']['left_knee']
  left_hip = result['data']['left_hip']
  right_hip = result['data']['right_hip']
  right_knee = result['data']['right_knee']
  right_ankle = result['data']['right_ankle']
  pelvis = result['data']['pelvis']
  thorax = result['data']['thorax']
  upper_neck = result['data']['upper neck']
  head_top = result['data']['head top']
  right_wrist = result['data']['right_wrist']
  right_elbow = result['data']['right_elbow']
  right_shoulder = result['data']['right_shoulder']
  left_shoulder = result['data']['left_shoulder']
  left_elbow = result['data']['left_elbow']
  left_wrist = result['data']['left_wrist']

將位置點(diǎn)連線

格式 cv2.circle(img, point, point_size, point_color, thickness)

輸入?yún)?shù):predict_img_path為輸入圖片的地址

輸出參數(shù):由兩個(gè)分別是將人體關(guān)鍵點(diǎn)的線畫(huà)在空白背景上/模型輸出的圖片上

功能:給圖片劃線并寫入將圖片按一定順序保存

def write_line(predict_img_path,output_path):
    global count_frame 
    print(predict_img_path)
    img = cv2.imread(predict_img_path)
    thickness = 2
    point_color = (0, 255, 0) # BGR  
    # 格式cv2.circle(img, point, point_size, point_color, thickness)
    cv2.line(img, (head_top[0],head_top[1]), (upper_neck[0],upper_neck[1]), point_color, 1)
    cv2.line(img, (upper_neck[0],upper_neck[1]), (thorax[0],thorax[1]), point_color, thickness)
    cv2.line(img, (upper_neck[0],upper_neck[1]), (left_shoulder[0],left_shoulder[1]), point_color, thickness)
    cv2.line(img, (upper_neck[0],upper_neck[1]), (right_shoulder[0],right_shoulder[1]), point_color, thickness)
    cv2.line(img, (left_shoulder[0],left_shoulder[1]), (left_elbow[0],left_elbow[1]), point_color, thickness)
    cv2.line(img, (left_elbow[0],left_elbow[1]), (left_wrist[0],left_wrist[1]), point_color, thickness)
    cv2.line(img, (right_shoulder[0],right_shoulder[1]), (right_elbow[0],right_elbow[1]), point_color, thickness)
    cv2.line(img, (right_elbow[0],right_elbow[1]), (right_wrist[0],right_wrist[1]), point_color, thickness)
    cv2.line(img, (left_hip[0],left_hip[1]), (left_knee[0],left_knee[1]), point_color, thickness)
    cv2.line(img, (left_knee[0],left_knee[1]), (left_ankle[0],left_ankle[1]), point_color, thickness)
    cv2.line(img, (right_hip[0],right_hip[1]), (right_knee[0],right_knee[1]), point_color, thickness)
    cv2.line(img, (right_knee[0],right_knee[1]), (right_ankle[0],right_ankle[1]), point_color, thickness)
    cv2.line(img, (thorax[0],thorax[1]), (left_hip[0],left_hip[1]), point_color, thickness)
    cv2.line(img, (thorax[0],thorax[1]), (right_hip[0],right_hip[1]), point_color, thickness)
    true_count = count_frame //2
    cv2.imwrite(output_path+ str(true_count) +".jpg",img)
    count_frame = count_frame +1

連接監(jiān)測(cè)點(diǎn)進(jìn)行畫(huà)線并輸出

def GetOutputPose(frame_path,output_black_path,output_pose_path):
    "輸入需要進(jìn)行關(guān)鍵點(diǎn)檢測(cè)的圖片目錄,進(jìn)行檢測(cè)后分別輸出原圖加線的圖片以及只有關(guān)鍵點(diǎn)連線的圖"
    "black_path:只有關(guān)鍵點(diǎn)連線的圖片目錄"
    "frame_path:需要處理的圖片目錄"
    "output_pose_path:帶原圖加連線的圖片目錄"
    # 配置
    num = os.listdir(frame_path)
    for i in range(0,len(num)-1):
        img_black = np.zeros((size_x,size_y,3), np.uint8)
        img_black.fill(255)
        img_black_path =output_black_path + str(i) + ".jpg"
        cv2.imwrite(img_black_path,img_black)
    for i in range(0,len(num)-1):
        path_dict = frame_path + str(i) + ".jpg"
        input_dict = {"image":[path_dict]}
        print("This is OutputPose {} pictrue".format(i))
        results = pose_resnet50_mpii.keypoint_detection(data=input_dict)
        for result in results:
            change_data(result)
            write_line(path_dict,output_pose_path)
            write_line(img_black_path,output_black_path)

輸出結(jié)果,獲取每一幀的人體骨骼檢測(cè)圖

如何用python實(shí)現(xiàn)專業(yè)評(píng)估舞蹈程序

動(dòng)作評(píng)估

上面我們已經(jīng)生成了青春有你2的主題曲標(biāo)準(zhǔn)舞蹈的關(guān)鍵點(diǎn)畫(huà)線集合,接下來(lái),我們需要實(shí)現(xiàn)對(duì)比標(biāo)準(zhǔn)舞蹈動(dòng)作以及測(cè)試舞蹈動(dòng)作,計(jì)算每一幀圖片的相似度,然后通過(guò)均值計(jì)算獲取選手主題曲的舞蹈實(shí)力分?jǐn)?shù)

相似值計(jì)算

基于直方圖計(jì)算兩個(gè)圖片之間的相似度

import cv2
# 計(jì)算單通道的直方圖的相似值
def calculate(image1, image2):
    hist1 = cv2.calcHist([image1], [0], None, [256], [0.0, 255.0])
    hist2 = cv2.calcHist([image2], [0], None, [256], [0.0, 255.0])
    # 計(jì)算直方圖的重合度
    degree = 0
    for i in range(len(hist1)):
        if hist1[i] != hist2[i]:
            degree = degree + (1 - abs(hist1[i] - hist2[i]) / max(hist1[i], hist2[i]))
        else:
            degree = degree + 1
    degree = degree / len(hist1)
    return degree

將實(shí)力值合成到測(cè)試選手的圖片上面

from PIL import Image
from PIL import ImageFilter
from PIL import ImageEnhance
from PIL import ImageDraw , ImageFont
 
def draw_text(bg_path,text,output_path):
    """
    實(shí)現(xiàn)圖片上面疊加中文
    bg_path:需要加中文的圖片
    text: 添加的中文內(nèi)容
    output_path: 合成后輸出的圖片路徑
    """
    
    im = Image.open(bg_path)
    draw = ImageDraw.Draw(im)
    fnt = ImageFont.truetype(r'fonts/SimHei.ttf',32)
    draw.text((100, 600), text, fill='red', font=fnt)
    im.show()
    im.save(output_path)

輸出結(jié)果

如何用python實(shí)現(xiàn)專業(yè)評(píng)估舞蹈程序

大眾好感分析

主要是基于LSTM模型對(duì)微博評(píng)論進(jìn)行情感分析

1.爬取與測(cè)試選手相關(guān)微博評(píng)論

2.訓(xùn)練模型

3.得出選手好感度以及搜索輸出選手話題詞頻統(tǒng)計(jì)

模型介紹

情感傾向分析(Sentiment Classification,簡(jiǎn)稱Senta)針對(duì)帶有主觀描述的中文文本,可自動(dòng)判斷該文本的情感極性類別并給出相應(yīng)的置信度,能夠幫助企業(yè)理解用戶消費(fèi)習(xí)慣、分析熱點(diǎn)話題和危機(jī)輿情監(jiān)控,為企業(yè)提供有利的決策支持。該模型基于一個(gè)LSTM結(jié)構(gòu),情感類型分為積極、消極。該P(yáng)addleHub Module支持預(yù)測(cè)和Fine-tune。

引入模型

下載

hub install senta_lstm

引入

senta = hub.Module(name="senta_lstm")

爬取微博評(píng)論

import requests
from pyquery import PyQuery as pq
import time
from urllib.parse import quote
import os
def get_page(page): 
    """
    通過(guò)微博api獲取微博數(shù)據(jù)
    page: 分頁(yè)頁(yè)數(shù)
    """
    headers = {
        'Host': 'm.weibo.cn',
        'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36',
        'X-Requested-With': 'XMLHttpRequest',
    }
    url = 'https://m.weibo.cn/api/container/getIndex?containerid=100103type%3D1%26q%3D'+quote(m)+'&page_type=searchall&page='+str(page)#將你檢索內(nèi)容轉(zhuǎn)為超鏈接
    print(url)
    try:
        response = requests.get(url, headers=headers)
        if response.status_code == 200:
            print(page)
            return response.json()
    except requests.ConnectionError as e:
        print('Error', e.args)
def parse_page(json):
    f_comments=open('comment/comment.txt','a')
    f_user=open('comment/weibo_user.txt','a')
    if json:
        items = json.get('data').get('cards')
        for i in items:
      
            item = i.get('mblog')
            if item == None:
                continue
            weibo = {}
            weibo['id'] = item.get('id')
            weibo['text'] = pq(item.get('text')).text()
            weibo['name'] = item.get('user').get('screen_name')
            if item.get('longText') != None :#要注意微博分長(zhǎng)文本與文本,較長(zhǎng)的文本在文本中會(huì)顯示不全,故我們要判斷并抓取。
                weibo['longText'] = item.get('longText').get('longTextContent')
            else:
                weibo['longText'] =None
            # print(weibo['name'])
            # print(weibo['text'])
            if weibo['longText'] !=None:
                f_comments.write(weibo['longText'])
                
            f_comments.write(weibo['text']+'\n')
            f_user.write(weibo['name']+'\n')
              
            #     yield weibo
    f_comments.close()
    f_user.close()
if __name__ == '__main__':
    m = '謝可寅'
    n = 50
  
    for page in range(1,n+1):
        time.sleep(1)         #設(shè)置睡眠時(shí)間,防止被封號(hào)
        json = get_page(page)
        parse_page(json)

爬取評(píng)論結(jié)果:

如何用python實(shí)現(xiàn)專業(yè)評(píng)估舞蹈程序

清洗評(píng)論以及去除停用詞

由于評(píng)論中含有一些表情包什么的,得處理一下

import re #正則匹配
import jieba #中文分詞
#去除文本中特殊字符
def clear_special_char(content):
    '''
    正則處理特殊字符
    參數(shù) content:原文本
    return: 清除后的文本
    '''
    f_clear = open('comment/clear_comment.txt','a')
    clear_content = re.findall('[\u4e00-\u9fa5a-zA-Z0-9]+',content,re.S)   #只要字符串中的中文,字母,數(shù)字
    str=','.join(clear_content)
    f_clear.write(str+'\n')
    f_clear.close
    return str
def fenci(content):
    '''
    利用jieba進(jìn)行分詞
    參數(shù) text:需要分詞的句子或文本
    return:分詞結(jié)果
    '''
    jieba.load_userdict(r"dic/user_dic.txt")
    seg_list = jieba.cut(content)
    return seg_list
def stopwordslist():
    '''
    創(chuàng)建停用詞表
    參數(shù) file_path:停用詞文本路徑
    return:停用詞list
    '''
    stopwords = [line.strip() for line in open('work/stopwords.txt',encoding='UTF-8').readlines()]
    acstopwords=['哦','因此','不然','謝可寅','超話']
    stopwords.extend(acstopwords)
    return stopwords
import pandas as pd
def movestopwords(sentence_depart,stopwords):
    '''
    去除停用詞,統(tǒng)計(jì)詞頻
    參數(shù) file_path:停用詞文本路徑 stopwords:停用詞list counts: 詞頻統(tǒng)計(jì)結(jié)果
    return:None
    '''
    segments = []
   
    # 去停用詞
    for word in sentence_depart:
        if word not in stopwords:
            if word != '\t':
                # outstr += word
                # outstr += " "
                segments.append(word)
   
    return segments

處理結(jié)果:

如何用python實(shí)現(xiàn)專業(yè)評(píng)估舞蹈程序

統(tǒng)計(jì)選手高頻TOP10詞

通過(guò)微博評(píng)論 統(tǒng)計(jì)選手高頻TOP10詞

import collections 
def drawcounts(segments):
    '''
    繪制詞頻統(tǒng)計(jì)表
    參數(shù) counts: 詞頻統(tǒng)計(jì)結(jié)果 num:繪制topN
    return:none
    '''
    # 詞頻統(tǒng)計(jì)
    word_counts = collections.Counter(segments) # 對(duì)分詞做詞頻統(tǒng)計(jì)
    word_counts_top10 = word_counts.most_common(10) # 獲取前10最高頻的詞
    print (word_counts_top10) 
    dic=dict(word_counts_top10)
    print(dic)
    x_values=[]
    y_values=[]
    for k in dic: 
        x_values.append(k)
        y_values.append(dic[k])
    # 設(shè)置顯示中文
    plt.rcParams['font.sans-serif'] = ['SimHei'] # 指定默認(rèn)字體
    plt.figure(figsize=(20,15))
    plt.bar(range(len(y_values)), y_values,color='r',tick_label=x_values,facecolor='#9999ff',edgecolor='white')
    # 這里是調(diào)節(jié)橫坐標(biāo)的傾斜度,rotation是度數(shù),以及設(shè)置刻度字體大小
    plt.xticks(rotation=45,fontsize=20)
    plt.yticks(fontsize=20)
    plt.legend()
    plt.title('''謝可寅微博評(píng)論詞頻統(tǒng)計(jì)''',fontsize = 24)
    plt.savefig('highwords.jpg')
    plt.show()
    return word_counts
if __name__ == '__main__':
    stopwords=stopwordslist()
    f = open(r"comment/comment.txt")
    line = f.readline()
    segments=[]
    while line:
        line = f.readline()
        clear_line=clear_special_char(line)
        seg_list= fenci(clear_line)
        segments_list=movestopwords(seg_list,stopwords)
        segments.extend(segments_list)
    f.close()
    drawcounts(segments)

 輸出結(jié)果:

如何用python實(shí)現(xiàn)專業(yè)評(píng)估舞蹈程序

對(duì)評(píng)論進(jìn)行情感分析

定義餅圖繪制方法

使用pyecharts庫(kù)進(jìn)行餅圖繪制

# from pyecharts import Pie
# from pyecharts.charts.basic_charts.pie import Pie
from pyecharts.charts import Pie
from pyecharts import options as opts
def draw_pie(data,labels):
    """
    繪制餅圖
  
    """
    data_pie = [list(i) for i in zip(labels,data)]
 # 創(chuàng)建實(shí)例對(duì)象
    pie = Pie(init_opts=opts.InitOpts(width='1000px',height='600px'))
    # 添加數(shù)據(jù)
    pie.add(series_name="情感類型",data_pair=data_pie)
    # 設(shè)置全局項(xiàng)
    pie.set_global_opts(title_opts=opts.TitleOpts(title="謝可寅好感分析",pos_left='center',pos_top=20))
    #設(shè)置每項(xiàng)數(shù)據(jù)占比
    pie.set_series_opts(tooltip_opts=opts.TooltipOpts(trigger='item',formatter="{a} <br/> :{c} (ynicmep%)"))
    pie.render("pie_charts.html")

lstm模型分析評(píng)論

if __name__ == '__main__':
    f = open(r"comment/clear_comment.txt")
    line = f.readline()
    comments=[]
    while line:
        comments.append(line)
        line = f.readline()
    f.close()
    input_dict = {"text": comments}
    ## 情感分析
    results = senta.sentiment_classify(data=input_dict,batch_size=5)
    positive_num=0
    negative_num=0
    for result in results:
        if result['sentiment_key'] == 'positive':
            positive_num+=1
        else:
            negative_num+=1
    print("total:%f,pos:%f,neg:%f"%(len(results),positive_num,negative_num))
    data=[positive_num,negative_num]
    labels=['積極評(píng)論','消極評(píng)論']
    draw_pie(data,labels)

輸出結(jié)果:

如何用python實(shí)現(xiàn)專業(yè)評(píng)估舞蹈程序

看完了這篇文章,相信你對(duì)如何用python實(shí)現(xiàn)專業(yè)評(píng)估舞蹈程序有了一定的了解,想了解更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道,感謝各位的閱讀!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI