Sie sind auf Seite 1von 8

11/11/2018 Barcode and QR code Scanner using ZBar and OpenCV | Learn OpenCV

Learn OpenCV
Barcode and QR code Scanner using ZBar and OpenCV
FEBRUARY 18, 2018 BY SATYA MALLICK (HTTPS://WWW.LEARNOPENCV.COM/AUTHOR/SPMALLICK/)

(https://www.learnopencv.com/wp-content/uploads/2018/02/barcode-QR-code-scanner-zbar-opencv.png)

In this post, we will share C++ and Python code for writing a barcode and QR code scanner using a library
called ZBar and OpenCV. The Python code works in both Python 2 and Python 3.

If you have never seen a barcode or a QR code, please send me the address of your cave so I can send you
a sample by mail. Jokes aside, barcodes and QR codes are everywhere. In fact, I have a QR code on the
back of my business card as well! Pretty cool, huh?

How to detect and decode barcodes and QR codes in an image?

Step 1 : Install ZBar

The best library for detecting and decoding barcodes and QR codes of different types is called ZBar
(http://zbar.sourceforge.net). Before we begin, you need to download and install ZBar
(http://zbar.sourceforge.net/download.html) by following the instructions here

https://www.learnopencv.com/barcode-and-qr-code-scanner-using-zbar-and-opencv/?fbclid=IwAR3f5WCEWWkBEkGjUerqRU02xYC8Vtl8jnytV-F8Qe… 1/8
11/11/2018 Barcode and QR code Scanner using ZBar and OpenCV | Learn OpenCV

(http://zbar.sourceforge.net/download.html).

macOS users can simply install using Homebrew

1 brew install zbar

Ubuntu users can install using

1 sudo apt-get install libzbar-dev libzbar0

Step 2 : Install pyzbar (for Python users only)


The official version of ZBar does not support Python 3. So we recommend using pyzbar
(https://github.com/NaturalHistoryMuseum/pyzbar) which supports both ython 2 and Python 3. If you just
want to work with python 2, you can install zbar and skip installing pyzbar.

Install ZBar
1 # NOTE: Official zbar version does not support Python 3
2 pip install zbar

Install pyzbar
1 pip install pyzbar

Step 3: Understanding the structure of a barcode / QR code


A barcode / QR code object returned by ZBar has three fields

1. Type: If the symbol detected by ZBar is a QR code, the type is QR-Code. If it is barcode, the type is one
of the several kinds of barcodes ZBar is able to read. In our example, we have used a barcode of type
CODE-128
2. Data: This is the data embedded inside the barcode / QR code. This data is usually alphanumeric, but
other types ( numeric, byte/binary etc. ) are also valid.
3. Location: This is a collection of points that locate the code. For QR codes, it is a list of four points
corresponding to the four corners of the QR code quad. For barcodes, location is a collection of points

that mark the start and end of word boundaries in the barcode. The location points are plotted for a few
different kinds of symbols below.

https://www.learnopencv.com/barcode-and-qr-code-scanner-using-zbar-and-opencv/?fbclid=IwAR3f5WCEWWkBEkGjUerqRU02xYC8Vtl8jnytV-F8Qe… 2/8
11/11/2018 Barcode and QR code Scanner using ZBar and OpenCV | Learn OpenCV

(https://www.learnopencv.com/wp-content/uploads/2018/02/zbar-location.png)
ZBar location points plotted using red dots. For QR codes, it is a vector of 4 corners of the symbol. For
barcodes, it is a collection of points that form lines along word boundaries.

Step 3a : C++ code for scanning barcode and QR code using ZBar
+ OpenCV

Download Code
To easily follow along this tutorial, please download code by clicking on the button below. It’s FREE!

DOWNLOAD CODE
(HTTPS://BIGVISIONLLC.LEADPAGES.NET/LEADBOX/143948B73F72A2%3A173C9390C346DC/5649050225344512/)

We first define a struture to hold the information about a barcode or QR code detected in an image.

1 typedef struct
2 {
3 string type;
4 string data;
5 vector <Point> location;
6 } decodedObject;

The type, data, and location fields are explained in the previous section.

Let’s look at the decode function that takes in an image and returns all barcodes and QR codes found.

1 // Find and decode barcodes and QR codes


2 void decode(Mat &im, vector<decodedObject>&decodedObjects)
3 {
4
5 // Create zbar scanner
6 ImageScanner scanner;
7

https://www.learnopencv.com/barcode-and-qr-code-scanner-using-zbar-and-opencv/?fbclid=IwAR3f5WCEWWkBEkGjUerqRU02xYC8Vtl8jnytV-F8Qe… 3/8
11/11/2018 Barcode and QR code Scanner using ZBar and OpenCV | Learn OpenCV

7
8 // Configure scanner
9 scanner.set_config(ZBAR_NONE, ZBAR_CFG_ENABLE, 1);
10
11 // Convert image to grayscale
12 Mat imGray;
13 cvtColor(im, imGray,CV_BGR2GRAY);
14
15 // Wrap image data in a zbar image
16 Image image(im.cols, im.rows, "Y800", (uchar *)imGray.data, im.cols * im.rows);
17
18 // Scan the image for barcodes and QRCodes
19 int n = scanner.scan(image);
20
21 // Print results
22 for(Image::SymbolIterator symbol = image.symbol_begin(); symbol != image.symbol_end(); ++symbol)
23 {
24 decodedObject obj;
25
26 obj.type = symbol->get_type_name();
27 obj.data = symbol->get_data();
28
29 // Print type and data
30 cout << "Type : " << obj.type << endl;
31 cout << "Data : " << obj.data << endl << endl;
32
33 // Obtain location
34 for(int i = 0; i< symbol->get_location_size(); i++)
35 {
36 obj.location.push_back(Point(symbol->get_location_x(i),symbol->get_location_y(i)));
37 }
38
39 decodedObjects.push_back(obj);
40 }
41 }

First, in lines 5-9 we create an instance of a ZBar ImageScanner and configure it to detect all kinds of
barcodes and QR codes. If you want only a specific kind of symbol to be detected, you need to change
ZBAR_NONE to a different type listed here
(http://zbar.sourceforge.net/api/zbar_8h.html#f7818ad6458f9f40362eecda97acdcb0). We then convert the
image to grayscale ( lines 11-13). We then convert the grayscale image to a ZBar compatible format in line
16 . Finally, we scan the image for symbols (line 19). Finally, we iterate over the symbols and extract the
type, data, and location information and push it in the vector of detected objects (lines 21-40).

Next, we will explain the code for displaying all the symbols. The code below takes in the input image and a
vector of decoded symbols from the previous step. If the points form a quad ( e.g. in a QR code ), we simply
draw the quad ( line 14 ). If the location is not a quad, we draw the outer boundary of all the points ( also
called the convex hull ) of all the points. This is done using OpenCV function called convexHull shown in
line 12.

1 // Display barcode and QR code location


2 void display(Mat &im, vector<decodedObject>&decodedObjects)
3 {
4 // Loop over all decoded objects
5 for(int i = 0; i < decodedObjects.size(); i++)
6 {
7 vector<Point> points = decodedObjects[i].location;

https://www.learnopencv.com/barcode-and-qr-code-scanner-using-zbar-and-opencv/?fbclid=IwAR3f5WCEWWkBEkGjUerqRU02xYC8Vtl8jnytV-F8Qe… 4/8
11/11/2018 Barcode and QR code Scanner using ZBar and OpenCV | Learn OpenCV

7 vector<Point> points = decodedObjects[i].location;


8 vector<Point> hull;
9
10 // If the points do not form a quad, find convex hull
11 if(points.size() > 4)
12 convexHull(points, hull);
13 else
14 hull = points;
15
16 // Number of points in the convex hull
17 int n = hull.size();
18
19 for(int j = 0; j < n; j++)
20 {
21 line(im, hull[j], hull[ (j+1) % n], Scalar(255,0,0), 3);
22 }
23
24 }
25
26 // Display results
27 imshow("Results", im);
28 waitKey(0);
29
30 }

Finally, we have the main function shared below that simply reads an image, decodes the symbols using the
decode function described above and displays the location using the display function described above.

1 int main(int argc, char* argv[])


2 {
3
4 // Read image
5 Mat im = imread("zbar-test.jpg");
6
7 // Variable for decoded objects
8 vector<decodedObject> decodedObjects;
9
10 // Find and decode barcodes and QR codes
11 decode(im, decodedObjects);
12
13 // Display location
14 display(im, decodedObjects);
15
16 return EXIT_SUCCESS;
17 }

Step 3b : Python code for scanning barcode and QR code using


ZBar + OpenCV

Download Code
To easily follow along this tutorial, please download code by clicking on the button below. It’s FREE!

DOWNLOAD CODE
(HTTPS://BIGVISIONLLC.LEADPAGES.NET/LEADBOX/143948B73F72A2%3A173C9390C346DC/5649050225344512/)

For Python, we use pyzbar, which has a simple decode function to locate and decode all symbols in the
image. The decode function in lines 6-15 simply warps pyzbar’s decode function and loops over the located

https://www.learnopencv.com/barcode-and-qr-code-scanner-using-zbar-and-opencv/?fbclid=IwAR3f5WCEWWkBEkGjUerqRU02xYC8Vtl8jnytV-F8Qe… 5/8
11/11/2018 Barcode and QR code Scanner using ZBar and OpenCV | Learn OpenCV

barcodes and QR codes and prints the data.

The decoded symbols from the previous step are passed on to the display function (lines 19-41). If the
points form a quad ( e.g. in a QR code ), we simply draw the quad ( line 30 ). If the location is not a quad, we
draw the outer boundary of all the points ( also called the convex hull ) of all the points. This is done using
OpenCV function called cv2.convexHull shown in line 27.

Finally, the main function simply reads an image, decodes it and displays the results.

1 from __future__ import print_function


2 import pyzbar.pyzbar as pyzbar
3 import numpy as np
4 import cv2
5
6 def decode(im) :
7 # Find barcodes and QR codes

https://www.learnopencv.com/barcode-and-qr-code-scanner-using-zbar-and-opencv/?fbclid=IwAR3f5WCEWWkBEkGjUerqRU02xYC8Vtl8jnytV-F8Qe… 6/8
11/11/2018 Barcode and QR code Scanner using ZBar and OpenCV | Learn OpenCV

7 # Find barcodes and QR codes


8 decodedObjects = pyzbar.decode(im)
9
10 # Print results
11 for obj in decodedObjects:
12 print('Type : ', obj.type)
13 print('Data : ', obj.data,'\n')
14
15 return decodedObjects
16
17
18 # Display barcode and QR code location
19 def display(im, decodedObjects):
20
21 # Loop over all decoded objects
22 for decodedObject in decodedObjects:
23 points = decodedObject.polygon
24
25 # If the points do not form a quad, find convex hull
26 if len(points) > 4 :
27 hull = cv2.convexHull(np.array([point for point in points], dtype=np.float32))
28 hull = list(map(tuple, np.squeeze(hull)))
29 else :
30 hull = points;
31
32 # Number of points in the convex hull
33 n = len(hull)
34
35 # Draw the convext hull
36 for j in range(0,n):
37 cv2.line(im, hull[j], hull[ (j+1) % n], (255,0,0), 3)
38
39 # Display results
40 cv2.imshow("Results", im);
41 cv2.waitKey(0);
42
43
44 # Main
45 if __name__ == '__main__':
46
47 # Read image
48 im = cv2.imread('zbar-test.jpg')
49
50 decodedObjects = decode(im)
51 display(im, decodedObjects)

Subscribe & Download Code


If you liked this article and would like to download code (C++ and Python) and example images used in this
post, please subscribe
(https://bigvisionllc.leadpages.net/leadbox/143948b73f72a2%3A173c9390c346dc/5649050225344512/) to
our newsletter. You will also receive a free Computer Vision Resource
(https://bigvisionllc.leadpages.net/leadbox/143948b73f72a2%3A173c9390c346dc/5649050225344512/)
Guide. In our newsletter, we share OpenCV tutorials and examples written in C++/Python, and Computer
Vision and Machine Learning algorithms and news.

Subscribe Now
(https://bigvisionllc.leadpages.net/leadbox/143948b73f72a2%3A173c9390c346dc/5649050225344512/)

https://www.learnopencv.com/barcode-and-qr-code-scanner-using-zbar-and-opencv/?fbclid=IwAR3f5WCEWWkBEkGjUerqRU02xYC8Vtl8jnytV-F8Qe… 7/8
11/11/2018 Barcode and QR code Scanner using ZBar and OpenCV | Learn OpenCV

COPYRIGHT © 2018 · BIG VISION LLC

https://www.learnopencv.com/barcode-and-qr-code-scanner-using-zbar-and-opencv/?fbclid=IwAR3f5WCEWWkBEkGjUerqRU02xYC8Vtl8jnytV-F8Qe… 8/8

Das könnte Ihnen auch gefallen