Introduzione a Intel Perceptual Computing SDK: i moduli e le webcam

In questo articolo vedremo come sia possibile elencare le web cam disponibili nel nostro pc e come sia possibile selezionarne una da utilizzare con Intel Perceptual SDK.

I moduli della piattaforma 

Le web cam vengono viste dalla piattaforma Intel come dei moduli (alla stregua del riconoscimento facciale, delle gesture o del riconoscimento vocale).
Un modulo altro non è che l'implementazione di funzionalità della piattaforma stessa.
Per questo motivo, recuperare le web cam disponibili si traduce nel recuperare l'elenco dei moduli di un certo tipo presenti nella piattaforma.
Vediamo prima di entrare nello specifico delle web cam cosa significa recuperare i moduli della piattaforma.
I moduli sono strutturati gerarchicamente e suddivisi per funzionalità esposte come mostrato nella seguente figura:

Possiamo vedere, ad esempio, che la piattaforma supporta il modulo di Video Capture e che, nel caso di specie, questo è supportato da due device presenti nel PC (Integrated WebCam e Creative GestureCam).

Recuperare i moduli

Il primo step, quindi, è recuperare làeòenco dei moduli disponibili.
In sostanza, un modulo, altro non è che l'implementazione di una o più interfacce dell'SDK e, quindi, per conoscere quali implementazioni sono disponibili, è sufficiente "chiederlo" all'SDK stesso.
Per questo ci viene in aiuto il metodo QueryImpl della classe PXCMSession che consente di riempire una struttura (la PXCMSession.ImplDesc) contenente tutti i dati relativi ad un singolo modulo.  
Per recuperare l'elenco completo dei moduli a nostra disposizione, dobbiamo procedere in questo modo:

  1. creare un'istanza di PXCMSession (metodo statico CreateInstance);
  2. richiamare il metodo QueryImpl per recuperare la struttura ImplDesc.

Il codice per il recupero dei moduli è il seguente:

Public Function EnumerateAllModules() As List(Of String)
    Dim session As PXCMSession = Nothing
    Dim status As pxcmStatus = PXCMSession.CreateInstance(Session)
    If status <> pxcmStatus.PXCM_STATUS_NO_ERROR Then Return Nothing
 
    Dim modules = New List(Of String)
    Dim modIndex As UInteger = 0
    Do
        Dim modDesc As PXCMSession.ImplDesc
        If session.QueryImpl(modIndex, modDesc) <> pxcmStatus.PXCM_STATUS_NO_ERROR Then Exit Do
        modules.Add(modDesc.friendlyName.get())
        modIndex = modIndex + CUInt(1)
    Loop While True
 
    session.Dispose()
    Return modules
End Function

Osserviamo che dobbiamo iterare su di un indice (modIndex) fino a che non otteniamo un risultato diverso da pxcmStatus.PXCM_STATUS_NO_ERROR. Questa modalità è, come abbiamo già visto per il face detection, standard nel mondo Perceptual.

La struttura PXCMSession.ImplDesc è mostrata nella seguente figura:

Tra gli attributi esposti da PXCMSession.ImplDesc troviamo:

  • friendlyName : contiene il nome del modulo (da recuperare tramite il metodo get());
  • group : è un'enumerazione (PXCMSession.ImplGroup) a maschera di bit che identifica il gruppo fnzionale del modulo. Ad esempio il modulo Video Capture appartiene al modulo IMPL_GROUP_SENSOR, mentre il Face Analysis appartiene al gruppo IMPL_GROUP_OBJECT_RECOGNITION). L'elenco completo dei valori è riportato nella seguente figura:

  • subgroup : è un'enumerazione (PXCMSession.ImplSubgroup, anch'essa a maschera di bit) che definisce un sottogruppo specifico di funzionalità che caratterizza un modulo. Ad esempio il modulo denominato "Hand/Finger Tracking and Gesture Recognition" appartiene al gruppo IMPL_GROUP_OBJECT_RECOGNITION e al sottogruppo IMPL_SUBGROUP_GESTURE_RECOGNITION. L'elenco completo dei valori è riportato dalla seguente figura

  • vendor : è un intero che identifica il produttore del modulo (Intel ha il valore 0x8086);
  • version : identifica la versione del modulo.

Nel codice mostrato in precedenza abbiamo recuperato l'intero elenco dei moduli, ma l'SDK ci mette a disposizione anche un overload del metodo QueryImpl che consente di "filtrare" la ricerca dei moduli in base al group e al subgroup desiderati.

Ad esempio se volessimo recuperare tutti i moduli che supportano il video capture, potremo utilizzare il seguente codice:

Public Function EnumerateWebCamModules() As List(Of String)
    Dim session As PXCMSession = Nothing
    Dim status As pxcmStatus = PXCMSession.CreateInstance(session)
    If status <> pxcmStatus.PXCM_STATUS_NO_ERROR Then Return Nothing
 
    Dim desc = New PXCMSession.ImplDesc()
    desc.group = PXCMSession.ImplGroup.IMPL_GROUP_SENSOR
    desc.subgroup = PXCMSession.ImplSubgroup.IMPL_SUBGROUP_VIDEO_CAPTURE
 
    Dim modules = New List(Of String)
    Dim modIndex As UInteger = 0
    Do
        Dim modDesc As PXCMSession.ImplDesc
        If session.QueryImpl(desc, modIndex, modDesc) <> pxcmStatus.PXCM_STATUS_NO_ERROR Then Exit Do
        modules.Add(modDesc.friendlyName.get())
        modIndex = modIndex + CUInt(1)
    Loop While True
 
    session.Dispose()
    Return modules
End Function

La differenza rispetto al precedente è nella creazione della struittura desc di tipo PXCMSession.ImplDesc che ci serve da filtro di ricerca e che utilizziamo nella chiamata al metodo QueryImpl.

Recuperare le device che implementano i moduli

Una volta recuperato un modulo tramite la QueryImpl, possiamo cercare di recuperare le device presenti nel sistema in grado di gestirlo.

Per fare questo possiamo procedere in questo modo:

  1. richiedere all'SDK di create l'implementazione definita del modulo in oggetto (istanza della classe PXCMCapture)
  2. se l'implementazione può essere creata (significa che esiste qualche device in grado di gestirlo), possiamo recuperare l'elenco delle device utilizzando il metodo QueryDevice della classe PXCMCapture.

Public Function EnumerateAllDevices() As List(Of String)
    Dim session As PXCMSession = Nothing
    Dim status As pxcmStatus = PXCMSession.CreateInstance(session)
    If status <> pxcmStatus.PXCM_STATUS_NO_ERROR Then Return Nothing
    Dim devices = New List(Of String)
    Dim modIndex As UInteger = 0
    Do
        ' recupero le informazioni sul modulo 
        Dim desc1 As PXCMSession.ImplDesc
        If session.QueryImpl(modIndex, desc1) <> pxcmStatus.PXCM_STATUS_NO_ERROR Then Exit Do
        ' provo a ricchiedere l'implementazione del modulo
        Dim capture As PXCMCapture = Nothing
        If session.CreateImpl(Of PXCMCapture)(desc1, PXCMCapture.CUID, capture) = pxcmStatus.PXCM_STATUS_NO_ERROR Then
            Dim devIndex As UInteger = 0
            Do
                ' Recupero le informazioni sul device
                Dim dinfo As PXCMCapture.DeviceInfo
                If capture.QueryDevice(devIndex, dinfo) <> pxcmStatus.PXCM_STATUS_NO_ERROR Then Exit Do
                devices.Add(String.Format("{0} - [{1}]", dinfo.name.get(), desc1.friendlyName.get))
                devIndex = devIndex + CUInt(1)
            Loop While True
            capture.Dispose()
        End If
        modIndex = modIndex + CUInt(1)
    Loop While True
 
    session.Dispose()
    Return devices
End Function

Quello che possiamo notare è che, una volta ottenuto il modulo (le cui informazioni sono contenute nella variabile desc1), proviamo a recuperare l'implementazione dello stesso (grazie al metodo CreateImpl della classe PXCMSession) e, infine, se questo è disponibile, richiediamo le device utilizzando il metodo QueryDevice della classe PXCMCapture che, in caso positivo, riempie la struttura PXCMCapture.DeviceInfo.

L'attributo name della struttura PXCMCapture.DeviceInfo fornisce il nome del device che può essere utilizzato per selezionare il device stesso per làutilizzo.

Se proviamo ad eseguire il precedente codice su un ultrabook con la Creative Gesture Cam collegata potremmo ottenere:

Utilizzare una webcam 

Abbiamo visto, in precedenza, come recuperare l'elenco delle device disponibili all'interno del sistema.

In particolare per recuperare solo ed esclusivamente le webcam, possimao utilizzare il seguente pezzo di codice:

Public Function FillDeviceList() As List(Of String)
    Dim session As PXCMSession = Nothing 
    Dim status As pxcmStatus = PXCMSession.CreateInstance(session)
    If status <> pxcmStatus.PXCM_STATUS_NO_ERROR Then Return Nothing
 
    Dim desc = New PXCMSession.ImplDesc()
    desc.group = PXCMSession.ImplGroup.IMPL_GROUP_SENSOR
    desc.subgroup = PXCMSession.ImplSubgroup.IMPL_SUBGROUP_VIDEO_CAPTURE
    Dim devices = New List(Of String)
    Dim devIndex As UInteger = 0
    Do
        Dim desc1 As PXCMSession.ImplDesc
        If session.QueryImpl(desc, devIndex, desc1) <> pxcmStatus.PXCM_STATUS_NO_ERROR Then Exit Do
        If desc1.subgroup = PXCMSession.ImplSubgroup.IMPL_SUBGROUP_VIDEO_CAPTURE Then
            Dim capture As PXCMCapture
            If session.CreateImpl(Of PXCMCapture)(desc1, PXCMCapture.CUID, capture) = pxcmStatus.PXCM_STATUS_NO_ERROR Then
                Dim subDevIndex As UInteger = 0
                Do
                    Dim dinfo As PXCMCapture.DeviceInfo
                    If capture.QueryDevice(subDevIndex, dinfo) <> pxcmStatus.PXCM_STATUS_NO_ERROR Then Exit Do
                    devices.Add(dinfo.name.get())
                    subDevIndex = subDevIndex + CUInt(1)
                Loop While True
                capture.Dispose()
            End If
        End If
        devIndex = devIndex + CUInt(1)
    Loop While True
    session.Dispose()
    Return Devices
End Function

Nel codice recuperiamo i moduli di gruppo IMPL_GROUP_SENSOR e sottogruppo IMPL_SUBGROUP_VIDEO_CAPTURE e selezioniamo quelli che hanno il solo sottogruppo IMPL_SUBGROUP_VIDEO_CAPTURE (tralasciamo, tanto per fare un esempio la parte infrarossi della Creative Gesture Cam che ha come sottogruppo sia il IMPL_SUBGROUP_VIDEO_CAPTURE che il IMPL_SUBGROUP_VOICE_RECOGNITION).

Se utilizziamo la UtilMPipeline per gestire il flusso di dati provenienti dall'SDK, ci basta impostare il device utilizzando il metodo SetFilter della classe UtilMCapture ottenuta, a partire dalla UtilMPipeline, tramite il metoro QueryCapture:

Dim capture = QueryCapture()
If capture IsNot Nothing Then
    capture.SetFilter(DeviceName)
End If


AnexoTamanho
Download deviceselection.zip37.6 KB
Para obter mais informações sobre otimizações de compiladores, consulte Aviso sobre otimizações.