1

I am new to programming and image processing. Recently i developed a system that detects faces from video feed and recognizes the person. If the person is already available on the database it tags his/her name to the frame, else if the person is new, it asks for their name and takes sufficient photos and stores in the database so that it can identify the person the next time. I am using the fisher-faces algorithm for this task. Now my question is , i want the system to talk. I want it to tell the name of the person it identified recently. I can use

static class Once { public: Once(){talk();}} Once_; 

to call the function talk once. but it is not organic and the talk function is not accepting input from the user.

Can anyone please suggest me a solution, or where to start the solution for this problem.

The talk function is

int speech(char* value)
{

ISpVoice * pVoice = NULL;

if (FAILED(::CoInitialize(NULL)))
    return FALSE;

HRESULT hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void **)&pVoice);
if( SUCCEEDED( hr ) )
{
    hr = pVoice->Speak(L"userINPUT", SPF_IS_XML, NULL);
    pVoice->Release();
    pVoice = NULL;
}

::CoUninitialize();
return TRUE;
}
raj3209812
  • 33
  • 1
  • 7
  • what's the purpose of your static class Once ? why not just call speed after the recognition, where you know the name ? (and please edit and call it 'speak' or such, not 'speed' – berak Jan 25 '14 at 11:57
  • i am calling speech after recognition, but the function hr = pVoice->Speak(L"userINPUT", SPF_IS_XML, NULL); dont support userInput. It just reads userIndut as a text – raj3209812 Jan 25 '14 at 17:29
  • I need a function that speech function that can take user input as a attribute or parameter for passing – raj3209812 Jan 25 '14 at 17:30
  • no problem passing a string in see [here](http://msdn.microsoft.com/en-us/library/ms723609%28v=vs.85%29.aspx) just *skip* the SPF_IS_XML flag and pass the name as input. and you probably want SPF_ASYNC ;) – berak Jan 25 '14 at 18:19
  • oh, if you use async, you can't release it instantly after calling Speak, ofc. maybe make a 'Voice' class around ? – berak Jan 25 '14 at 18:22

1 Answers1

0

so, here's my proposal:

// -- >8 ---------- speech.h --------------------------
#ifndef __speech_onboard__
#define __speech_onboard__


struct ISpVoice; // fwd ref, since mixing opencv and windows headers is a receipt for desaster

namespace Speech
{
    class Voice
    {
        ISpVoice * spVoice;

    public:

        Voice();
        ~Voice();


        int speak( const char * txt, int flags=0 ) const ;

        // Supported values range from -10 to 10 
        int setRate( int s );

        // Supported values range from 0 to 100 
        int setVolume( int s );
    };
};


#endif // __speech_onboard__



// ---- >8 speech.cpp ------------------------------
#include <windows.h>
#include <sapi.h>
#include "speech.h"


#define COM_RELEASE(x) { if ((x)) (x)->Release(); (x) = NULL; }


namespace Speech
{
    struct _ComUser
    {
        _ComUser()  {CoInitialize(0);}
        ~_ComUser() {CoUninitialize();}
    } _we_need_a_singleton_per_module;


    inline int w2a( WCHAR *in, char *out )
    {
        out[0]=0;
        return WideCharToMultiByte(CP_ACP, 0, in, -1, out, MAX_PATH, 0, 0); 
    }

    inline int a2w( const char *in, WCHAR *out )
    {
        out[0]=0;
        return MultiByteToWideChar(CP_ACP, 0, in, -1, out, MAX_PATH); 
    }




    Voice::Voice()
        : spVoice(0)
    {
        HRESULT hr = CoCreateInstance( CLSID_SpVoice, NULL, CLSCTX_INPROC_SERVER, IID_ISpVoice, (LPVOID *)&(spVoice) ); 
    }


    Voice::~Voice()
    {
        COM_RELEASE( spVoice );
    }

    //SPF_ASYNC = ( 1L << 0 ) ,
    //SPF_PURGEBEFORESPEAK  = ( 1L << 1 ) ,
    //SPF_IS_FILENAME   = ( 1L << 2 ) ,
    //SPF_IS_XML    = ( 1L << 3 ) ,
    //SPF_IS_NOT_XML    = ( 1L << 4 ) ,
    //SPF_PERSIST_XML   = ( 1L << 5 ) ,
    //SPF_NLP_SPEAK_PUNC    = ( 1L << 6 ) ,
    //SPF_PARSE_SAPI    = ( 1L << 7 ) ,
    //SPF_PARSE_SSML    = ( 1L << 8 ) ,
    //SPF_PARSE_AUTODETECT  = 0,
    int Voice::speak( const char * txt, int flags ) const 
    {
        if ( ! spVoice )
            return 0;

        WCHAR wtxt[800];
        a2w(txt,wtxt);

        ULONG pulstream = 0;
        HRESULT hr = spVoice->Speak( wtxt, flags, &pulstream );

        return hr==S_OK; 
    }


    // Supported values range from -10 to 10 
    int Voice::setRate( int s )
    {
        if ( ! spVoice )
            return 0;

        HRESULT hr = spVoice->SetRate( s );

        return hr==S_OK; 
    }

    // Supported values range from 0 to 100 
    int Voice::setVolume( int s )
    {
        if ( ! spVoice )
            return 0;

        HRESULT hr = spVoice->SetVolume ( s );

        return hr==S_OK; 
    }
}



// ----- >8 main.cpp --------------------------------------------

#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"

using namespace cv;

#include "speech.h"

int main(int argc, char** argv)
{
    Speech::Voice voice;
    voice.speak("hello , oh, hello!", 1); // async

    Mat img(300,300,CV_8UC3,Scalar(255,0,0));
    namedWindow("Display window",0);
    putText(img,"lala la",Point(20,120),0,2.5,Scalar(0,200,0),5);
    imshow("Display window", img);
    waitKey(0);

    voice.speak("bye bye, see you later !"); // sync
    return 0;
}
berak
  • 39,159
  • 9
  • 91
  • 89
  • Looks solid, i am going to try it now and will get back. – raj3209812 Jan 27 '14 at 05:06
  • i have one small question, In voice.speak("hello , oh, hello!", 1); can i pass a string from the user for example voice.speak("hello" inputstring, 1); – raj3209812 Jan 27 '14 at 05:29
  • I found this [link](http://stackoverflow.com/questions/15573246/store-a-variable-that-holds-user-input-data-in-sapi5-speak-function) – raj3209812 Jan 27 '14 at 08:34