Autore Topic: Leggere codici a barre con GStreamer mediante una webcam  (Letto 124 volte)

Offline vuott

  • Senatore Gambero
  • ******
  • Post: 6.738
    • Mostra profilo
Il sistema multimediale "GStreamer" offre, fra l'altro, la possibilità di leggere i codici a barre mediante una webcam.
Il particolare plugin di GStreamer, chiamato "ZBAR", restituirà il tipo ed il codice.

Putroppo, almeno per ora, sono costretto :-X a passarvi un esempio potendo fare solo uso  di Shell - ahimé !  :'(  -   e della riga testuale delle istruzioni degli Elementi richiesti all'uopo da GStreamer.

Fasi necessarie:
- collegare una webcam al computer;
- lanciare il codice;
- avvicinare (...non troppo) il codice a barre alla webcam, cercando (...con pazienza) la distanza e l'inclinazione ottimali.

Per chiudere il programma attenersi rigorosamente a quanto scritto in commento alla sub-routine "Application_Read( ) " in fondo al seguente programma.

Codice: [Seleziona]
Private pr As Process


Public Sub Main()

pr = Shell "gst-launch-1.0 -m v4l2src ! videoconvert ! zbar ! videoconvert ! xvimagesink" For Read As "processo"

End


Public Sub processo_Read()
 
  Dim s As String
  Dim ss As String[]
  Dim qlt As Short

' Imposta il livello minimo di qualità dell'immagine che noi vogliamo che sia accettata da "zbar":
   qlt = 30

' Leggiamo dal processo il messaggio inviato da "zbar":
  Line Input #Pr, s

  If InStr(s, "symbol") Then
    ss = Scan(s, "*(element): *,*type=(string)*, symbol=(string)*, quality=(int)*;*")
    If Val(ss[5]) >= qlt Then
      Print "\n\nElemento: "; ss[1], "Tipo: "; ss[3], "Codice rilevato: "; ss[4]
    Else
      Print "Codice a barre riconosciuto, ma qualità dell'immagine rilevata troppo bassa !"
    Endif
  Endif
 
End


Public Sub Application_Read()   '' Per chiudere il programma, cliccare nella console e premere il tasto "Invio" della tastiera.
 
  pr.Kill

  Quit
 
End


« Ultima modifica: 12 Agosto 2017, 05:02:27 da vuott »
" Chi non vede il non senso del mondo, è vano a sua volta. "

(B. Pascal, 1623 – 1662)

Offline vuott

  • Senatore Gambero
  • ******
  • Post: 6.738
    • Mostra profilo
Re:Leggere codici a barre con GStreamer mediante una webcam
« Risposta #1 il: 12 Agosto 2017, 05:00:18 »
Dopo uno studio ed una ricerca matti e disperatissimi, sono riuscito a fare un passo in avanti nella lettura dei codici a barra con una WebCam mediante le risorse di GStreamer, riuscendo a scrivere così il necessario codice senza uso di Shell ! :D

E' un piccolo passo, poiché per ora sarà ncessario richiamare alcune funzioni esterne della libreria di Gstreamer. Al riguardo va precisato che bisogna avere installata nel proprio sistema la libreria di GStreamer versione non inferiore alla 1.0 !

Di seguito il codice:

Codice: [Seleziona]
Private webcam As Pointer
Private bs As Pointer
Private cnt As Integer


Library "libgstreamer-1.0"

Private Enum GST_STATE_VOID_PENDING = 0, GST_STATE_NULL, GST_STATE_READY, GST_STATE_PAUSED, GST_STATE_PLAYING
Private Const GST_MESSAGE_ERROR As Integer = 2
Private Const GST_MESSAGE_ELEMENT As Integer = 32768

' gst_init (int *argc, char **argv[])
' Initializes the GStreamer library, setting up internal path lists, registering built-in elements, and loading standard plugins.
Private Extern gst_init(argc As Pointer, argv As Pointer)

' GMainLoop * g_main_loop_new (GMainContext *context, gboolean is_running)
' Creates a new GMainLoop structure.
Private Extern g_main_loop_new(context As Pointer, is_running As Boolean) As Pointer

' GstElement * gst_parse_launch (const gchar *pipeline_description, GError **error)
' Create a new pipeline based on command line syntax.
Private Extern gst_parse_launch(description As String, gerror As Pointer) As Pointer

' GstBus * gst_pipeline_get_bus (GstPipeline *pipeline)
' Gets the GstBus of pipeline.
Private Extern gst_pipeline_get_bus(pipeline As Pointer) As Pointer

' guint gst_bus_add_watch (GstBus *bus, GstBusFunc func, gpointer user_data)
' Adds a bus watch to the default main context with the default priority.
Private Extern gst_bus_add_watch(bus As Pointer, func As Pointer, user_data As Pointer) As Integer

' GstStateChangeReturn gst_element_set_state(GstElement *element, GstState state)
' Sets the state of the element.
Private Extern gst_element_set_state(element As Pointer, state As Integer) As Integer
 
' void g_main_loop_run (GMainLoop *loop)
' Runs a main loop until g_main_loop_quit() is called on the loop.
Private Extern g_main_loop_run(gloop As Pointer)

' const gchar * gst_structure_get_name (const GstStructure *structure)
' Get the name of structure as a string.
Private Extern gst_structure_get_name(gstructure As Pointer) As String

' const GstStructure * gst_message_get_structure (GstMessage *message)
' Access the structure of the message.
Private Extern gst_message_get_structure(message As Pointer) As Pointer

' gint g_value_get_int (const GValue *value)
' Get the contents of a G_TYPE_INT GValue.
Private Extern g_value_get_int(value As Pointer) As Integer

' const GValue * gst_structure_get_value (const GstStructure *structure, const gchar *fieldname)
' Get the value of the field with name fieldname .
Private Extern gst_structure_get_value(gstructure As Pointer, fieldname As String) As Pointer

' const gchar * g_value_get_string (const GValue *value)
' Get the contents of a G_TYPE_STRING GValue.
Private Extern g_value_get_string(value As Pointer) As String

' void gst_object_unref(gpointer object)
' Decrements the reference count on object.
Private Extern gst_object_unref(gobject As Pointer)


Public Sub Main()
 
  Dim lp As Pointer
   
   gst_init(0, 0)
   
   lp = g_main_loop_new(0, False)
   
' Imposta gli elementi necessari per la ripresa video e per la estrazione del codice a barre:
   webcam = gst_parse_launch("v4l2src ! videoconvert ! zbar ! videoconvert ! xvimagesink", 0)
   
' Poiché l'elemento "zbar" inserisce il testo afferente al codice a barre nel puntatore "GstBus", è necessario estrapolarlo dalla pipeline:
   bs = gst_pipeline_get_bus(webcam)
   
' Resta in osservazione se è pronto un messaggio nel bus, nel qual caso invoca la funzione "Gestione_messaggio_bus()":
   gst_bus_add_watch(bs, Gestione_messaggio_bus, lp)
   
' Avvia la ripresa video:
   gst_element_set_state(webcam, GST_STATE_PLAYING)
   
' Avvia un loop infinito:
   g_main_loop_run(lp)
   
End


Public Function Gestione_messaggio_bus(bus As Pointer, msg As Pointer, data As Pointer) As Boolean

  Select Case Int@(msg + 64)      ' GstMessage->type
    Case GST_MESSAGE_ELEMENT
      Inc cnt
      Print "\nMessaggio n. "; cnt, ": "; gst_structure_get_name(gst_message_get_structure(msg)),
' Informa sulla qualità della ripresa video, affinché così l'utente sia possa valutare il grado di affidabilità
' dei dati inviati dal plug-in "zbar" attinenti al codice a barre ripreso con la webcam:
      Print "qualità: "; g_value_get_int(gst_structure_get_value(gst_message_get_structure(msg), "quality"))
      Print "   Tipo: "; g_value_get_string(gst_structure_get_value(gst_message_get_structure(msg), "type"))
      Print "   Codice: "; g_value_get_string(gst_structure_get_value(gst_message_get_structure(msg), "symbol"))
    Case GST_MESSAGE_ERROR
      Print "Errore durante la ripresa video !"
      Chiude()
  End Select
 
  Return True
 
End


Private Procedure Chiude()
 
  ' Arresta la ripresa video e chiude la libreria GStreamer:
     gst_element_set_state(webcam, GST_STATE_NULL)
     gst_object_unref(bs)
     gst_object_unref(webcam)
     Print "\nEsecuzione terminata."
     Quit
 
End


« Ultima modifica: 13 Agosto 2017, 03:16:10 da vuott »
" Chi non vede il non senso del mondo, è vano a sua volta. "

(B. Pascal, 1623 – 1662)

Offline vuott

  • Senatore Gambero
  • ******
  • Post: 6.738
    • Mostra profilo
Re:Leggere codici a barre con GStreamer mediante una webcam
« Risposta #2 il: 12 Agosto 2017, 17:24:40 »
Per analogia di argomento segnalo questa pagina:

http://www.gambas-it.org/smf/index.php?topic=2864.0
" Chi non vede il non senso del mondo, è vano a sua volta. "

(B. Pascal, 1623 – 1662)

Offline vuott

  • Senatore Gambero
  • ******
  • Post: 6.738
    • Mostra profilo
Re:Leggere codici a barre con GStreamer mediante una webcam
« Risposta #3 il: 13 Agosto 2017, 20:06:55 »
Dopo molto studio e tanto penare ecco finalmente la soluzione tutta solo Gambas usando il Componente gb.media.  ;D

Codice: [Seleziona]
Private pl As MediaPipeline
Private tb As ToggleButton
Private drar As DrawingArea


Public Sub _new()

  With Me
    .W = 600
    .H = 600
  End With
 
  drar = New DrawingArea(Me)
  drar.Background = Color.Transparent
 
  With tb = New ToggleButton(Me) As "Tasto"
    .X = 500
    .Y = 550
    .W = 80
    .H = 40
    .Text = "Avvia"
  End With
 
End

Public Sub Form_Open()

  Dim src, zbr, snk As MediaControl
 
   pl = New MediaPipeline As "Pipeline"
   
   src = New MediaControl(pl, "v4l2src")
   zbr = New MediaControl(pl, "zbar")
   snk = New MediaControl(pl, "xvimagesink")
   
   src.LinkTo(zbr)
   zbr.LinkTo(snk)
   
   snk.SetWindow(drar)
 
End


Public Sub Tasto_Click()
 
 If tb.Value Then
   pl.Play()
   tb.Text = "Chiudi"
 Else
   pl.Stop()
   pl.Close()
   Me.Close
 Endif
 
End


Public Sub Pipeline_Event(Message As MediaMessage)
 
  Dim b As Byte

  If Message.Name = "barcode" Then
    For b = 1 To Message.count - 1
      With Message
        Print .Keys[b], Message[.Keys[b]],
      End With
    Next
    Print
  Endif
 
End

« Ultima modifica: 13 Agosto 2017, 21:25:45 da vuott »
" Chi non vede il non senso del mondo, è vano a sua volta. "

(B. Pascal, 1623 – 1662)