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

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.179
  • Ne mors quidem nos iunget
    • 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 »
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.179
  • Ne mors quidem nos iunget
    • 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 »
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.179
  • Ne mors quidem nos iunget
    • 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
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.179
  • Ne mors quidem nos iunget
    • 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 »
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline milio

  • Senatore Gambero
  • ******
  • Post: 1.252
  • Chi parla poco dice tanto...
    • Mostra profilo
Re:Leggere codici a barre con GStreamer mediante una webcam
« Risposta #4 il: 31 Maggio 2019, 10:27:15 »
Ciao vuott!!!

E' da tempo che non scrivo, ma ultimamente ho necessità di utilizzare la webcam di diversi pc come lettore di qrcode per impostare una determinata lavorazione alle macchine.

Ho provato il tuo esempio partendo dai comandi shell e tutto funziona a dovere. Provando pero' l'esempio che hai fatto con gb.media mi si impianta su pl.Play() nella sub Tasto_Click() ritornandomi l'errore: Cannot set Status.

Ti elenco anche le caratteristiche del mio sistema preso da direttamente da Gambas:

[System]
Gambas=3.13
OperatingSystem=Linux
Kernel=4.18.0-20-generic
Architecture=x86_64
Distribution=Ubuntu 18.04.2 LTS
Desktop=KDE5
Theme=Breeze
Language=it_IT.UTF-8
Memory=15801M

[Libraries]
Cairo=libcairo.so.2.11510.0
Curl=libcurl.so.4.5.0
DBus=libdbus-1.so.3.19.4
GStreamer=libgstreamer-1.0.so.0.1401.0
GTK+2=libgtk-x11-2.0.so.0.2400.32
GTK+3=libgtk-3.so.0.2200.30
OpenGL=libGL.so.1.0.0
Poppler=libpoppler.so.73.0.0
QT4=libQtCore.so.4.8.7
QT5=libQt5Core.so.5.9.5
SDL=libSDL-1.2.so.0.11.4
SQLite=libsqlite3.so.0.8.6

[Environment]
DBUS_SESSION_BUS_ADDRESS=unix:abstract=/tmp/dbus-cmaguCowYk,guid=368de7810fd758cffc5fe5925ce4e9ce
DEFAULTS_PATH=/usr/share/gconf/plasma.default.path
DESKTOP_SESSION=plasma
DISPLAY=:0
GB_GUI=gb.qt4
GPG_AGENT_INFO=/run/user/1000/gnupg/S.gpg-agent:0:1
GS_LIB=<home>/.fonts
HOME=<home>
KDE_FULL_SESSION=true
KDE_SESSION_UID=1000
KDE_SESSION_VERSION=5
LANG=it_IT.UTF-8
LANGUAGE=it_IT.UTF-8
LOGNAME=<user>
MANDATORY_PATH=/usr/share/gconf/plasma.mandatory.path
PAM_KWALLET5_LOGIN=/run/user/1000/kwallet5.socket
PAM_KWALLET_LOGIN=/run/user/1000/kwallet.socket
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
PWD=<home>
QT_ACCESSIBILITY=1
QT_AUTO_SCREEN_SCALE_FACTOR=0
SESSION_MANAGER=local/<hostname>:@/tmp/.ICE-unix/1505,unix/<hostname>:/tmp/.ICE-unix/1505
SHELL=/bin/bash
SHLVL=0
SSH_AGENT_PID=1444
SSH_AUTH_SOCK=/tmp/ssh-36Vlmy6HNV55/agent.1364
S_COLORS=auto
TZ=:/etc/localtime
USER=<user>
XAUTHORITY=<home>/.Xauthority
XCURSOR_THEME=breeze_cursors
XDG_CONFIG_DIRS=/etc/xdg/xdg-plasma:/etc/xdg:/usr/share/kubuntu-default-settings/kf5-settings
XDG_CURRENT_DESKTOP=KDE
XDG_DATA_DIRS=/usr/share/plasma:/usr/local/share:/usr/share:/var/lib/snapd/desktop
XDG_RUNTIME_DIR=/run/user/1000
XDG_SEAT=seat0
XDG_SEAT_PATH=/org/freedesktop/DisplayManager/Seat0
XDG_SESSION_CLASS=user
XDG_SESSION_DESKTOP=KDE
XDG_SESSION_ID=3
XDG_SESSION_PATH=/org/freedesktop/DisplayManager/Session1
XDG_SESSION_TYPE=x11
XDG_VTNR=1

Ciao e buona giornata a te e a tutti!!

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.179
  • Ne mors quidem nos iunget
    • Mostra profilo
Re:Leggere codici a barre con GStreamer mediante una webcam
« Risposta #5 il: 31 Maggio 2019, 10:59:33 »
Ho provato il tuo esempio partendo dai comandi shell e tutto funziona a dovere. Provando pero' l'esempio che hai fatto con gb.media mi si impianta su pl.Play() nella sub Tasto_Click() ritornandomi l'errore: Cannot set Status.
Ciao Milio,
ricordo che avevamo molti anni fa fatto un breve studio su Gambas e QRcode.

Ad ogni modo il problema da te sollevato è stato da poco rilevato in generale anche da qualche altro utente Gambas: pare ci sia un recente problema tra la Classe "MediaPipeline" e il Metodo ".SetWindow( )":
   https://lists.gambas-basic.org/pipermail/user/2019-May/067079.html

Infatti, andando a verificare i codici da me scritti nella Wiki nella sezione "Video" sull'uso della Webcam, ho anch'io riscontrato il tuo stesso problema.

Io ho risolto nei miei esempi inserendo il plugin "videoconvert".

Dovresti quindi inserirlo dopo la riga:
src = New MediaControl(pl, "v4l2src")
così:
Codice: [Seleziona]
cnv = New MediaControl(pl, "videoconvert")
Non dimenticare di collegarlo agli altri plugin presenti mediante il Metodo ".LinkTo( )" !
Stai anche attento ai valori di "framerate", qualora previsti nell'oggetto MediaFilter( ) eventualmente da te inserito.
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline milio

  • Senatore Gambero
  • ******
  • Post: 1.252
  • Chi parla poco dice tanto...
    • Mostra profilo
Re:Leggere codici a barre con GStreamer mediante una webcam
« Risposta #6 il: 31 Maggio 2019, 11:02:02 »
Ancora ciao...

Tramite questa guida: https://www.gambas-it.org/wiki/index.php?title=Effettuare_una_ripresa_video_mediante_una_WebCam_con_il_Componente_gb.media ho modificato la tua sub Form_Open() come segue prendendo spunto anche dal comando shell che avevi postato nel primo post:

Codice: [Seleziona]
Public Sub Form_Open()

  Dim src, zbr, snk, cnv, cnv2 As MediaControl
 
   pl = New MediaPipeline As "Pipeline"

   src = New MediaControl(pl, "v4l2src")
   src["device"] = "/dev/video0"
   
   cnv = New MediaControl(pl, "videoconvert")
   zbr = New MediaControl(pl, "zbar")
   cnv2 = New MediaControl(pl, "videoconvert")
   snk = New MediaControl(pl, "xvimagesink")
   
   src.LinkTo(cnv)
   cnv.LinkTo(zbr)
   zbr.LinkTo(cnv2)
   cnv2.LinkTo(snk)
   
   snk.SetWindow(drar)
 
End

Adesso funziona  ;)

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.179
  • Ne mors quidem nos iunget
    • Mostra profilo
Re:Leggere codici a barre con GStreamer mediante una webcam
« Risposta #7 il: 31 Maggio 2019, 11:08:39 »
Tramite questa guida: https://www.gambas-it.org/wiki/index.php?title=Effettuare_una_ripresa_video_mediante_una_WebCam_con_il_Componente_gb.media

Adesso funziona  ;)
Sì, come ti ho detto, dopo aver letto il post nella MailingList ufficiale di Gambas, ho dovuto studiare per trovare la soluzione al problema (che tra l'altro non ho neanche comunicato lì nella ML). La soluzione è basata sull'inserimento del plugin "videoconvert" di GStreamer attraverso l'oggetto "MediaControl".
« Ultima modifica: 31 Maggio 2019, 11:09:31 da vuott »
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline milio

  • Senatore Gambero
  • ******
  • Post: 1.252
  • Chi parla poco dice tanto...
    • Mostra profilo
Re:Leggere codici a barre con GStreamer mediante una webcam
« Risposta #8 il: 19 Giugno 2019, 10:58:43 »
Ecco il componente...  ;)

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.179
  • Ne mors quidem nos iunget
    • Mostra profilo
Re:Leggere codici a barre con GStreamer mediante una webcam
« Risposta #9 il: 19 Giugno 2019, 11:38:55 »
Bene, ho inserito il riferimento al tuo Componente nella Guida della Comunità:

   https://www.gambas-it.org/wiki/index.php?title=Guide_della_comunit%C3%A0#Componenti_della_Comunit.C3.A0_Gambas-it.org
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline Gianluigi

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 4.114
  • Tonno verde
    • Mostra profilo
Re:Leggere codici a barre con GStreamer mediante una webcam
« Risposta #10 il: 19 Giugno 2019, 14:26:01 »
All'avvio ottengo questo errore : Unable to create media control nel QrCodeReader: 72
Con questi warning in console:
gb.sdl2.audio: warning: MP3 support not available
gb.sdl2.audio: warning: OGG support not available
gb.sdl2.audio: warning: MOD support not available
gb.sdl2.audio: warning: FLAC support not availabl

Cosa mi manca?
nuoto in attesa del bacio di una principessa che mi trasformi in un gambero azzurro

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.179
  • Ne mors quidem nos iunget
    • Mostra profilo
Re:Leggere codici a barre con GStreamer mediante una webcam
« Risposta #11 il: 19 Giugno 2019, 15:49:55 »
...ma funziona la lettura ?
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline Gianluigi

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 4.114
  • Tonno verde
    • Mostra profilo
Re:Leggere codici a barre con GStreamer mediante una webcam
« Risposta #12 il: 19 Giugno 2019, 16:54:00 »
No, non si avvia proprio.
nuoto in attesa del bacio di una principessa che mi trasformi in un gambero azzurro

Offline kicco

  • Senatore Gambero
  • ******
  • Post: 1.696
  • So dove andare, seguitemi, ci perderemo insieme!
    • Mostra profilo
Re:Leggere codici a barre con GStreamer mediante una webcam
« Risposta #13 il: 19 Giugno 2019, 21:50:56 »
Citazione
No, non si avvia proprio.
anche per me è così!
Ma non ho messaggi in console.
« Ultima modifica: 19 Giugno 2019, 21:52:35 da kicco »
Chi ha paura muore ogni giorno, chi non ha paura muore una volta sola. (Paolo Borsellino)