美文网首页
识别手势语音重点

识别手势语音重点

作者: Mark_ | 来源:发表于2019-10-31 19:23 被阅读0次

不说点废话,看代码是不是蒙圈了呢 😝

环境配置

  Kinect2 SDK直接安装,安装完成后会在系统环境变量中加入变量值 KINECTSDK20_DIR,语音文件安装需要安装多个文件,其中包括 runtime(speech SDK 的运行环境)、speech SDK、语言文件,要先安装运行环境在安装SDK,接下来安装需要的语言包

Kinect for Windows SDK 2.0
Microsoft Speech Platform - Software Development Kit (SDK) (Version 11)

kinect SDK

初始化SDK 并打开

IKinectSensor* m_pKinect ;
GetDefaultKinectSensor(&m_pKinect);
m_pKinect->Open();

读取身体数据

inline HRESULT KinectApp::initBodySource()
{
    //添加身体数据源
    IBodyFrameSource* bodySource = nullptr;
    HRESULT hr = m_pKinect->get_BodyFrameSource(&bodySource);
    if (!SUCCEEDED(hr))
    {
        m_errorCallBack("get_BodyFrameSource failed");
        return hr;
    }
    //读取身体数据源
    INT32 nBodyNum = 0;
    bodySource->get_BodyCount(&nBodyNum);
    hr = bodySource->OpenReader(&bodyReader); // 准备读取body数据
    if (!SUCCEEDED(hr))
    {
        m_errorCallBack("OpenReader failed");
        return hr;
    }
    return hr;
}

获取身体数据

inline void KinectApp::getBody(void){

    Sleep(sleeptime);
    // 获取最近的一帧数据
    IBodyFrame* bodyf = nullptr;
    bodyReader->AcquireLatestFrame(&bodyf);
    if (!bodyf)
    {
        return;
    }
    // 更新所有人身体数据
    IBody* ppBodies[BODY_COUNT] = { 0 };
    bodyf->GetAndRefreshBodyData(BODY_COUNT, ppBodies);

    IBody*pbody = getTrackedBody(ppBodies);
    if (pbody != nullptr)
    {
        getTrackedBodyJoints(pbody);
    }

    SafeRelease(bodyf);
}

每次获取到身体都为6个人的数组,因为是单人控制鼠标,获取到任务的id是无先后顺序的,所以获取到任务之后要进行锁定,下次获取是先判断当前锁定人物还在不,如果在直接获取手势,如果不在则锁定当前第一人

inline IBody* KinectApp::getTrackedBody(IBody* ppBodies[])

获取手势

HandState rightHandState = HandState_Unknown;
pBody->get_HandRightState(&rightHandState);

判断是不是在范围内,因为设备可获取范围为4米这里规定为2.8米内

inline bool KinectApp::isInScope(IBody* pBody)

获取手势坐标

Joint joints[JointType_Count];
HRESULT hr = pBody->GetJoints(_countof(joints), joints);
Joint rightJoint = joints[JointTypeArray[i]];
rightJoint.Position.X;
rightJoint.Position.Y;
rightJoint.Position.Z;

记录历史6个点的位置,用于求每次的位置的平均值,在误差值范围内更准确,显然鼠标的移动显得没有直接取当前那么流畅,还可以接受,不卡顿

inline BodyRect KinectApp::getHandRect(Joint joints[],JointType JointTypeArray[])

数据回调

void KinectApp::m_setActionCallBack(ActionCallBack call)
void KinectApp::m_setErrorActionCallBack(ErrorCallBack call)
void KinectApp::m_setPanActionCallBack(PanActionCallBack call)
void KinectApp::m_actionCallBack(int x,int y,int z,ActionType type)

滑动手势,实现难,操作起来更难,起始点难以确定,最后放弃

void KinectApp::m_panActionCallBack()

Speech SDK

HRESULT MKSpeech::init_speech_recognizer()
{
    HRESULT hr = S_OK;
    // 创建语音输入流
    hr = CoCreateInstance(CLSID_SpStream, nullptr, CLSCTX_INPROC_SERVER, __uuidof(ISpStream), (void**)&m_pSpeechStream);
    if (!SUCCEEDED(hr))
    {
        m_errorCallBack("CoCreateInstance CLSID_SpStream failed");
        return hr;
    }
    // 创建语言识别器
    hr = CoCreateInstance(CLSID_SpInprocRecognizer, nullptr, CLSCTX_INPROC_SERVER, __uuidof(ISpRecognizer), (void**)&m_pSpeechRecognizer);
    if (!SUCCEEDED(hr))
    {
        m_errorCallBack("CoCreateInstance CLSID_SpInprocRecognizer failed");
        return hr;
    }
    //创建默认音频输入对象
    CComPtr<ISpObjectToken> ISPToken = nullptr;
    hr = SpGetDefaultTokenFromCategoryId(SPCAT_AUDIOIN,&ISPToken);
    if (!SUCCEEDED(hr))
    {
        m_errorCallBack("SpGetDefaultTokenFromCategoryId failed");
        return hr;
    }
    //设置识别引擎输入源
    hr = m_pSpeechRecognizer->SetInput(ISPToken,TRUE);
    if (!SUCCEEDED(hr))
    {
        m_errorCallBack("SetInput failed");
        return hr;
    }
    // 创建语音识别对象
    ISpObjectToken *pEngineToken = nullptr;
    hr = SpFindBestToken(SPCAT_RECOGNIZERS, L"language=804", nullptr, &pEngineToken);
    if (!SUCCEEDED(hr))
    {
        m_errorCallBack("SpFindBestToken failed");
        return hr;
    }
    // 设置待识别语言
    m_pSpeechRecognizer->SetRecognizer(pEngineToken);
    // 创建语音识别上下文
    hr = m_pSpeechRecognizer->CreateRecoContext(&m_pSpeechContext);
    if (!SUCCEEDED(hr))
    {
        m_errorCallBack("m_pSpeechRecognizer CreateRecoContext failed");
        return hr;
    }
    SafeRelease(pEngineToken);
    // 适应性 ON! 防止因长时间的处理而导致识别能力的退化
    hr = m_pSpeechRecognizer->SetPropertyNum(L"AdaptationOn", 0);
    if (!SUCCEEDED(hr))
    {
        m_errorCallBack("m_pSpeechRecognizer SetPropertyNum failed");
        return hr;
    }
    // 创建语法
    hr = m_pSpeechContext->CreateGrammar(1, &m_pSpeechGrammar);
    if (!SUCCEEDED(hr))
    {
        m_errorCallBack("m_pSpeechContext CreateGrammar failed");
        return hr;
    }
    //加载语法规则
    hr = m_pSpeechGrammar->LoadCmdFromFile(s_GrammarFileName, SPLO_DYNAMIC);
    if (!SUCCEEDED(hr)){
        hr = m_pSpeechGrammar->LoadCmdFromFile(L".\\resources\\app\\kinectLib\\Grammar.xml", SPLO_DYNAMIC);     
    }
    if (!SUCCEEDED(hr))
    {
        m_errorCallBack("m_pSpeechGrammar LoadCmdFromFile failed");
        return hr;
    }
    // 激活语法规则
    hr = m_pSpeechGrammar->SetRuleState(nullptr, nullptr, SPRS_ACTIVE);
    if (!SUCCEEDED(hr))
    {
        m_errorCallBack("m_pSpeechGrammar SetRuleState failed");
        return hr;
    }
    // 设置识别器一直读取数据
    hr = m_pSpeechRecognizer->SetRecoState(SPRST_ACTIVE);
    if (!SUCCEEDED(hr))
    {
        m_errorCallBack("m_pSpeechRecognizer SetRecoState failed");
        return hr;
    }
    // 设置对识别事件感兴趣
    hr = m_pSpeechContext->SetInterest(SPFEI(SPEI_RECOGNITION), SPFEI(SPEI_RECOGNITION));
    if (!SUCCEEDED(hr))
    {
        m_errorCallBack("m_pSpeechContext SetInterest failed");
        return hr;
    }
    // 保证语音识别处于激活状态
    m_pSpeechContext->Resume(0);
    // 获取识别事件
    m_hSpeechEvent = m_pSpeechContext->GetNotifyEventHandle();
    
    return hr;
}

音频处理线程,语音识别是异步的,这里用了WaitForMultipleObjects 查看信号量是否改变, 在异步线程中执行该方法

void MKSpeech::AudioThread(MKSpeech* pointer){
    // 先设置
    HANDLE events[] = { pointer->m_hSpeechEvent };
    bool exit = false;
    while (!exit) {
        switch (::WaitForMultipleObjects(lengthof(events), events, FALSE, 8000)){
        case WAIT_OBJECT_0:
            // 语言识别
            pointer->speech_process();
            exit = true;
            pointer->close();
            break;
        case WAIT_TIMEOUT:
            pointer->m_audioCallBack("faild",AudioCallStatus_Faild);
            exit = true;
            pointer->close();
            break;
        }
    }
}

音频处理

void MKSpeech::speech_process()

音频文件格式介绍
item tag 这里采用了base64字符串 5qyn5rSy,亚洲、青海、黑龙江、欧洲 等语音识别到都返回 5qyn5rSy 作为识别到的字符

<item>
<tag>5qyn5rSy</tag>
<one-of>
<item>河南大写</item>
<item>欧洲</item>
<item>亚洲</item>
<item>青海</item>
<item>黑龙江</item>
</one-of>
</item>

<grammar root="rootRule" tag-format="semantics/1.0-literals" version="1.0" xml:lang="zh-CN" xmlns="http://www.w3.org/2001/06/grammar">
  <rule id="rootRule">
    <one-of>
      <item>
        <tag>5qyn5rSy</tag>
        <one-of>
          <item>河南大写</item>
          <item>欧洲</item>
          <item>亚洲</item>
          <item>青海</item>
          <item>黑龙江</item>
        </one-of>
      </item>
      <item>
        <tag>5qyn5rSy</tag>
        <one-of>
          <item>河南大写</item>
          <item>欧洲</item>
          <item>亚洲</item>
          <item>青海</item>
          <item>黑龙江</item>
        </one-of>
      </item>
    </one-of>
  </rule>
</grammar>

代码地址:链接: https://pan.baidu.com/s/1aY8S2VWOBIsW-JbAqcdEow 提取码: kujw

相关文章

  • 识别手势语音重点

    不说点废话,看代码是不是蒙圈了呢 ? 环境配置   Kinect2 SDK直接安装,安装完成后会在系统环境变量中加...

  • 手势控制:点击、滑动、平移、捏合、旋转、长按、轻扫

    手势识别器(Gesture Recognizer)用于识别触摸序列并触发响应事件。当手势识别器识别到一个手势或手势...

  • 3.6 iOS手势识别的状态和手势识别器幕后原理

    2.2手势识别的状态和手势识别器幕后原理 (一)手势的状态 (二)离散型手势识别器和连续型手势识别器之间的对比: ...

  • Gesture手势

    手势识别器 手势识别器是对触摸事件做了封装,我们无需自己去判断某个手势是否触发,手势识别器本身起到了识别作用,我们...

  • 手势识别

    手势识别 6种手势识别 在iOS开发中有6中手势识别:点按、捏合、拖动、轻扫、旋转、长按苹果推出手势识别主要是为了...

  • UIGestureRecognizer

    什么是手势识别器? 手势识别器就是对触摸事件做了封装,我们不需要判断某个手势是否触发,手势识别器本身起到了识别作用...

  • 手势——UIGestureRecognizer

    一、简介 UIGestureRecognizer是具体手势识别器的基类。 手势识别器对象(或简单地说是手势识别器)...

  • EasyAR手势姿势识别

    简介 简单试了下EasyAR的手势识别以及姿势识别 手势识别 目前官方是有两种手势 测试了感觉识别度蛮高的 也蛮快...

  • iOS手势识别

    UIGestureRecognizer手势识别器手势识别器是特殊的触摸事件UIGestureRecognizer是...

  • UIGestureRecognizer手势识别器学习笔记

    UIGestureRecognizer 具体手势识别器的基类。一个手势识别器对象,或者简单地说一个手势识别器,解耦...

网友评论

      本文标题:识别手势语音重点

      本文链接:https://www.haomeiwen.com/subject/wzgtbctx.html