Voici la démarche pour faire un lecteur de code à barre pour Raspberry en utilisant OpenCV et l’API zbar.
Pré-requis :
- Installer OpenCV sur le Raspberry
- Si vous utiliser la raspicam, alors il faudra aussi installer le pilote uv4l pour qu’elle fonctionne avec OpenCV
- Installer zbar sur le Raspberry
Ensuite, il suffit d’utiliser ce petit programme :
#include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <zbar.h> #include <iostream> using namespace cv; using namespace std; using namespace zbar; int main(int argc, char* argv[]) { VideoCapture cap(0); // open the video camera no. 0 // cap.set(CV_CAP_PROP_FRAME_WIDTH,800); // cap.set(CV_CAP_PROP_FRAME_HEIGHT,640); if (!cap.isOpened()) // if not success, exit program { cout << "Cannot open the video cam" << endl; return -1; } ImageScanner scanner; scanner.set_config(ZBAR_NONE, ZBAR_CFG_ENABLE, 1); double dWidth = cap.get(CV_CAP_PROP_FRAME_WIDTH); //get the width of frames of the video double dHeight = cap.get(CV_CAP_PROP_FRAME_HEIGHT); //get the height of frames of the video cout << "Frame size : " << dWidth << " x " << dHeight << endl; namedWindow("MyVideo", CV_WINDOW_AUTOSIZE); //create a window called "MyVideo" while (1) { Mat frame; bool bSuccess = cap.read(frame); // read a new frame from video if (!bSuccess) //if not success, break loop { cout << "Cannot read a frame from video stream" << endl; break; } Mat grey; cvtColor(frame, grey, CV_BGR2GRAY); int width = frame.cols; int height = frame.rows; uchar *raw = (uchar *)grey.data; // wrap image data Image image(width, height, "Y800", raw, width * height); // scan the image for barcodes int n = scanner.scan(image); // extract results for(Image::SymbolIterator symbol = image.symbol_begin(); symbol != image.symbol_end(); ++symbol) { vector<Point> vp; // do something useful with results cout << "decoded " << symbol->get_type_name() << " symbol \"" << symbol->get_data() << "\"" << endl; int n = symbol->get_location_size(); for(int i=0;i<n;i++) { vp.push_back(Point(symbol->get_location_x(i), symbol->get_location_y(i))); } RotatedRect r = minAreaRect(vp); Point2f pts[4]; r.points(pts); for(int i=0;i<4;i++){ line(frame, pts[i], pts[(i+1)%4], Scalar(255,0,0), 3); } cout<<"Angle: "<<r.angle<<endl; } imshow("MyVideo", frame); //show the frame in "MyVideo" window if (waitKey(30) == 27) //wait for 'esc' key press for 30ms. If 'esc' key is pressed, break loop { cout << "esc key is pressed by user" << endl; break; } } return 0; }
Voici la ligne de commande pour le compiler :
g++ test.cpp -lopencv_highgui -lopencv_core -lopencv_imgproc -lzbar
A noter que pour ceux qui utilisent la raspicam : Elle est montée d’origine pour faire un focus à distance infinie… Ce qui ne nous arrange pas pour passer un code à barre ou un QR Code à 10cm de la lentille (l’image obtenue est floue et donc non reconnue). En fait, l’astuce consiste à dévisser la lentille afin de régler le focus aux alentours de 10cm. J’ai trouvé l’astuce sur ce lien : http://elinux.org/Rpi_Camera_
ATTENTION : Pour ne pas abimer la lentille, il ne faut pas utiliser de pince ! Ça dérape facilement… ^^’ Je pense qu’avec une gomme pressée sur la lentille permettrait de la débloquer. Un fois la lentille débloquée, elle se dévisse / revisse facilement à la main.
Hey, I’ve just looked through your tut by using google translate ( I dont know French). My project is reading the barcode using raspberry pi with webcam and then using the output to compare to a database, whether the code in the database or not.
I dont know how to run your script. It looks like it’s C-language? What I have to do before the compiling process?
Hello !
My script is not a script but a source of C++ code. All you have to do is to compil and install OpenCV Framework (see my post install OpenCV).
Then, if you use raspicam (and only if you use it), you must install uv4l driver (see my post install uv4l driver).
And then, you have to compil and install zbar Framework (see my post install zbar).
Now, this C++ source code can compil. To do this, copy and past the source code to one file (« test.cpp » in my exemple) and run the command Line in this post (« g++ test.cpp -lopencv_highgui -lopencv_core -lopencv_imgproc -lzbar »).
If no error occurs, this command line create a binary named a.out. You can run this program site this command line :
./a.out
Y hope that my English is not too bad ^^’.
Salut,
je suis tombé sur ton site car j’essaye de lire un qrcode et le retranscrire en fichier .txt
J’ai donc tout suivi à la lettre, d’ailleurs l’install d’OpenCV est effectivement bien longue..
Du coup j’ai compilé et lancé la commande ./a.out et j’obtiens cela :
HIGHGUI ERROR: V4L/V4L2: VIDIOC_S_CROP
Frame size : 640 x 480
: cannot connect to X server
Je ne vois pas quand est ce dans le programme qu’il y a c message d’erreur.
Ou est ce que je configure mon server web ?
Merci pour tes informations, je ne suis pas encore expert en développement. =)
Rien a voir avec le serveur Web. Cette erreur survient car l’application est en mode fenêtrée et qu’elle désire afficher son contenu dans une fenêtre, mais qu’aucun gestionnaire de fenêtre n’est disponible (server X). Avez-vous essayé de lancer l’application depuis le bureau du raspberry (branché en HDMI sur un moniteur, session ouverte sur ce moniteur) ?
Bonjour,
j’ai suivi chacune des étapes, mais l’ouverture de la caméra ne fonctionne pas (IsOpen() == false).
Pourtant:
– open cv est bien linké;
– zbar est bien linké;
– le programme s’exécute;
– raspistill fonctionne bien pour prendre des photos;
– j’ai déjà capturé des vidéos de plusieurs minutes en python;
Une piste ?
Cordialement.
La seule piste que je vois est un problème de pilote de la raspicam. En effet, OpenCV ne fonctionne pas nativement avec cette caméra. Il faut obligatoirement installer le pilote uv4l. Mis à part cela, je ne vois pas :-/
bonjour
tout le code fonctionne tres bien, avec le bureau demarré, mais si je veux le lancer en mode console j’obtiens cette erreur :
HIGHGUI ERROR: V4L/V4L2: VIDIOC_S_CROP
Frame size : 640 x 480
: cannot connect to X server
est-il possible de lancer le programme sans avoir le bureau, uniquement en mode console ?
Bonjour,
Le programme tel qu’il a été écrit doit obligatoirement avoir un bureau démarré. Si l’on veut l’utiliser uniquement en mode console, alors il faut en écrire un autre pour qu’il puisse se passer du mode fenêtré.
Salut.
merci pour tes expliquations, c’est exactement ce que je cherchais, on va l’utiliser dans notre projet open source.
n’ésites pas a me contacter si tu veux des informations.
Salut! Merci bien pour partager cette piéce de code 🙂 Si vous utilisez opencv 3.1, J’ai trouvé il faut ajouter encore un autre paramètre a la ligne de commande pour bien contruire le fichier executable, a suivre:
g++ test.cpp -lopencv_highgui -lopencv_imageio -lopencv_core -lopencv_imgproc -lzbar
Et aussi ajouter le header correspondant aux fichier source:
#include
Hi,
you’ve made a very nice tutorial. It just won’t work for me. I do every part as told and by trying to run the test.cpp I get errors that the predicted functions like videocapture from opencv can’t be found. I tried different approaches. Best guess would be that it’s triggered by some differences do you have this setup as an image of your sd card or something like this? I would appreciate it very much.
Best Wishes
kallell
…some differences between opencv2 and opencv3…
Hello,
I think you dont have exactly the same versions of my tools… If I have time, i can update my post with the last version of tools.
Regards.
Bonjour,
J’ai à priori tout installé, le driver V4L aussi.
La compilation ne donne pas d’erreur.
Quand je lance le programme a.out j’ai les messages suivants :
/dev/video0 does not support memory mapping
munmap : Invalid argument
munmap : Invalid argument
munmap : Invalid argument
munmap : Invalid argument
Unable to stop the stram. : Bad file descriptor
munmap : Invalid argument
munmap : Invalid argument
munmap : Invalid argument
munmap : Invalid argument
Frame size : 640 x 480
et sur mon écran, j’ai deux fenêtres vidéo qui s’ouvrent, une petite centée et une autre appelée MyVideo que je peux déplacer sur l’écran.
De plus, je ne peux pas sortir du programme sinon en fermant la fenêtre du terminal.
Si vous avez des pistes, je vous remercie d’avance.
Cordialement
bonjour
j’ai compiler ce programme mais j’ai trouvée une erreur .est ce que c’est possible de me guider que ce que je fais .
cordialement .
||=== Build: Debug in code barre (compiler: GNU GCC Compiler) ===|
/home/pi/Desktop/Haifa/code barre /main.cpp|3|fatal error: zbar.h: No such file or directory|
||=== Build failed: 1 error(s), 0 warning(s) (0 minute(s), 2 second(s)) ===|
c’est erreur au niveau #include
Bonjour,
Visiblement la librairie zbar n’est pas présente dans ton environnement. Il faut d’abord installer cet outil.
Bonjour,
Lorsque je compile le source présenté avec openCV 3.3.0 j’obtiens l’erreur suivante:
/usr/bin/ld: /tmp/ccVcFtfJ.o: undefined reference to symbol ‘_ZN2cv12VideoCaptureD1Ev’
//usr/local/lib/libopencv_videoio.so.3.3: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
root@Rpi-Dev:/home/pi/BarCode# make
make: *** No targets specified and no makefile found. Stop.
A priori tout s’est bien installé correctement.
Ca pourrait venir de la version 3.3.0 que j’utilise ?
Merci
Bonjour,
Oui, la version d’openCV 3.3 n’a pas les même pré-requis que celle que j’ai utilisée. Il faut regarder ce dont à besoin openCV en version 3.3 et voir s’il est possible de les récupérer.