An OpenCV barcode and QR code scanner with ZBar

Today’s blog post on reading barcodes and QR codes with OpenCV is inspired by a question I received from PyImageSearch reader, Hewitt:

Hey Adrian, I really love the PyImageSearch blog. I look forward to your emails each week. Keep doing what you’re doing.

I have a question for you:

Does OpenCV have any modules that can be used to read barcodes or QR codes? Or do I need to use an entirely separate library?

Thanks Adrian.

Great question, Hewitt.

The short answer is no, OpenCV does not have any dedicated modules that can be used to read and decode barcodes and QR codes.

However, what OpenCV can do is facilitate the process of reading barcodes and QR codes, including loading an image from disk, grabbing a new frame from a video stream, and processing it.

Once we have the image or frame we can then pass it to a dedicated Python barcode decoding library such as a Zbar.

The ZBar library will then decode the barcode or QR code. OpenCV can come back in to perform any further processing and display the result.

If this sounds like a complicated process, it’s actually pretty straightforward. The ZBar library, along with its various forks and variations, have come a long way. One set of ZBar bindings in particular, pyzbar , is my personal favorite.

Inside today’s tutorial, I will show you how to read barcodes and QR codes with OpenCV and ZBar.

And as an added bonus, I’ll demonstrate how to deploy our barcode scanner to the Raspberry Pi as well!

To learn more about reading barcodes and QR codes with OpenCV and ZBar, just keep reading.

Looking for the source code to this post?
Jump right to the downloads section.

An OpenCV barcode and QR code scanner with ZBar

Today’s blog post is broken into four parts.

In the first part, I’ll show you how to install the ZBar library (with Python bindings).

The ZBar library will be used together with OpenCV to scan and decode barcodes and QR codes.

Once ZBar and OpenCV are properly configured I’ll demonstrate how to scan barcodes and QR codes in a single image.

Starting with a single image will give us the practice we need to prepare for the next step: Reading barcodes and QR codes in real-time with OpenCV and ZBar,

Finally, I’ll demonstrate how to deploy our real-time barcode scanner to the Raspberry Pi.

Installing ZBar (with Python bindings) for barcode decoding

A few weeks ago Satya Mallick from the LearnOpenCV blog posted a really great tutorial on using the ZBar library to scan barcodes.

The instructions to install ZBar in today’s post are largely based on his instructions, but with a few updates, the largest one being related to how we install the Python zbar  bindings themselves, ensuring we can:

  1. Use Python 3 (the official zbar  Python bindings only support Python 2.7)
  2. Detect and localize exactly where in the image the barcode is.

Installing the necessary software is an easy 3-step process.

Step 1: Install zbar  from the apt  or brew  repository

Installing ZBar for Ubuntu or Raspbian

Installing ZBar for Ubuntu can be accomplished with the following command:

Installing ZBar for macOS

Installing ZBar for macOS using brew is equally as easy (assuming you have Homebrew installed):

Step 2 (Optional): Create a virtual environment and install OpenCV

You have two options here:

  1. Use an existing virtual environment that has OpenCV ready to go (skip this step and head to Step 3).
  2. Or create a new, isolated virtual environment which involves installing OpenCV.

Virtual environments are a best practice for Python development and I highly encourage you to make use of them.

I elected to create a new, isolated Python 3 virtual environment and followed the Ubuntu (or macOS, depending on which machine I was using) OpenCV installation instructions linked on this page. The only change I made while following those instructions was to name my environment barcode :

Note: If you already have OpenCV installed on your system you can skip the OpenCV compile process and simply sym-link your  bindings into the site-packages  directory of your new Python virtual environment.

Step 3: Install pyzbar

Now that I have a Python 3 virtual environment named barcode  on my machine, I activated the barcode  environment (yours might have a different name) and installed pyzbar :

If you are not using a Python virtual environment you can just do:

If you’re trying to install pyzbar  into the system version of Python make sure you use the sudo  command as well.

Decoding barcodes and QR codes with OpenCV in single images

Figure 1: Both QR and 1D barcodes can be read with our Python app using ZBar + OpenCV.

Before we implement real-time barcode and QR code reading, let’s first start with a single image scanner to get our feet wet.

Open up a new file, name it  and insert the following code:

On Lines 2-4 we import our required packages.

Both pyzbar  and cv2  (OpenCV) need to be installed following the instructions in the previous section.

In contrast, argparse  is included with the Python install and it is responsible for parsing command line arguments.

We have one required command line argument for this script ( --image ) and it is parsed on Lines 7-10.

You’ll see at the end of this section how to run the script while passing a command line argument containing the input image path.

Now, let’s take the input image and put pyzbar  to work:

On Line 13, we load the input image  via its path (contained in our convenient args  dictionary).

From there, we call pyzbar.decode  to find and decode the barcodes  in the image  (Line 16). This is where all the magic of ZBar happens.

We aren’t finished yet — now we need to parse the information contained within the barcodes  variable:

Beginning on Line 19, we loop over the detected barcodes .

In this loop, we proceed to:

  1. Extracting the bounding box (x, y)-coordinates from the barcode.rect  object (Line 22), enabling us to localize and determine where in the input image the current barcode is.
  2. Draw draw a bounding box rectangle on the image  around the detected barcode  (Line 23).
  3. Decode the barcode  into a "utf-8"  string and extract the type of barcode (Lines 27 and 28). It is critical to call the .decode("utf-8")  function on the object to convert from a byte array to a string. You can experiment by removing/commenting it out to see what happens — I’ll leave this as an experiment for you to try.
  4. Format and draw the barcodeData  and barcodeType  on the image (Lines 31-33).
  5. And finally, output the same data and type information to the terminal for debugging purposes (Line 36).

Let’s test our OpenCV barcode scanner. You should use the “Downloads” section at the bottom of this blog post to download the code and example image.

From there, open up your terminal and execute this command:

As you can see in the terminal, all four of the barcodes were found and properly decoded!

Refer to Figure 1 for the processed image which has overlaid red rectangles and text for each barcode our software found.

Real-time barcode and QR code reading with OpenCV

In the previous section, we learned how to create a Python + OpenCV barcode scanner for single images.

Our barcode and QR code scanner worked well — but it raises the question, can we detect and decode barcode + QR codes in real-time?

To find out, open up a new file, name it , and insert the following code:

On Lines 2-8 we import our required packages.

At this point, recalling the above explanation, you should recognize pyzbar , argparse , and cv2 .

We’ll also use VideoStream  to handle capturing video frames in an efficient, threaded approach. You can learn more about the VideoStream class here. And if you do not have imutils  installed on your system, just use the following command:

We’re going to parse one optional command line argument, --output , which contains the path to the output Comma Separated Values (CSV) file. This file will contain the timestamp and payload of each detected and decoded barcode from our video stream. If this argument isn’t specified, the CSV file will be placed in our current working directory with a name of "barcodes.csv"  (Lines 11-14).

From there, let’s initialize our video stream and open our CSV file:

On Lines 18 and 19 we initialize and start our VideoStream . You may either:

  • Use your USB webcam (uncomment Line 18 and comment Line 19)
  • Or if you’re using a Raspberry Pi (like me) you can use the PiCamera (uncomment Line 19 and comment Line 18).

I chose to use my Raspberry Pi PiCamera, as is shown in the next section.

We then pause for two seconds to allow the camera can warm up (Line 20).

We’ll be writing all barcodes we find to disk in a CSV file (but ensuring duplicates are not written). This is meant to be a (trivial) example of logging barcodes. You could, of course, do whatever you want once a barcode is detected and read such as:

  • Save it in a SQL database
  • Send it to a server
  • Upload it to the cloud
  • Send an email or text message

The actual action is arbitrary — we’re simply using the CSV file as an example.

Feel free to update the code to include any notification you may wish.

We open the csv  file for writing on Line 24. If you are modifying the code to append to the file, you can simply change the 2nd parameter from "w"  to "a"  (but you’ll have to search the file for duplicates in a different way).

We also initialize a set  for found  barcodes. This set will contain unique barcodes while preventing duplicates.

Let’s begin capturing + processing frames:

On Line 28 we start our loop and proceed to grab and and resize a  frame  from our video stream (Lines 31 and 32).

From there, we call pyzbar.decode  to detect and decode any QR + barcodes in the frame .

Let’s proceed to loop over the detected barcodes :

This loop should look very familiar if you read the previous section.

In fact, Lines 38-52 are identical to those the single image script. Please refer to the single image barcode detection and scanning section for a detailed review of this code block.

Lines 56-60 are new. On these lines, we check if we’ve found a unique (not previously found) barcode (Line 56).

If that’s the case, we write the timestamp and data to the csv  file (Lines 57-59). We also append the barcodeData  to a found  set as a simple way to handle duplicates.

In the remaining lines of the real-time barcode scanner script, we display the frame, check if the quit key is pressed, and perform cleanup:

On Line 63 we display the output frame .

Then on Lines 64-68, we check for keys and if "q"  is pressed, we break  out of the main execution loop.

Finally, we perform cleanup on Lines 72-74.

Building a barcode and QR code scanner on the Raspberry Pi

Figure 2: My Raspberry Pi barcode scanner project consists of a Raspberry Pi, PiCamera, 7-inch touchscreen, and battery pack.

What fun is a barcode scanner if I’m limited to my desk?

I decided that I’d like to take my barcode scanner with me using my Pi, touchscreen, and battery pack.

Shown in Figure 2 is my setup — the exact one I used for my mobile Pokedex deep learning project recently. If you’re looking to build your own with the exact peripherals shown, I’ve listed the products and links:

Building the system is really easy and I’ve made step-by-step instructions in this blog post.

Once your mobile ZBar barcode scanner is ready, use the “Downloads” section of this blog post to download the code associated with this blog post.

From there, open up a terminal on your Pi and launch the app with the following command (you’ll need a keyboard/mouse for this step but then you can disconnect and let the app run):

Now you can present barcodes to the camera and when you’re done, you can open the barcodes.csv  file (or if you’re so inclined you can execute tail -f barcodes.csv  in a separate terminal to view the data as it enters the CSV file live).

The first QR code that I tried is shown on a black background — it is very easy for ZBar to detect:

Figure 3: A QR code with the code “PyImageSearch” is recognized with our Python + ZBar application

Then I headed to my kitchen, with Pi, screen, and battery pack in hand, and found another QR code:

Figure 4: My website, “” is encoded in a QR code and recognized with ZBar and Python on my Raspberry Pi.

Success! It even works at many angles.

Now let’s try a QR code that is contains a JSON-blob of data:

Figure 5: An OpenCV barcode and QR scanner with ZBar decodes an image of a QR with ease. I deployed the project to my Raspberry Pi so I can take it on the go.

No match for my OpenCV + ZBar + Python barcode scanner project!

And finally, I tried a traditional 1-D barcode:

Figure 6: ZBar coupled with OpenCV and Python makes for a great Raspberry Pi barcode project. My name, “AdrianRosebrock” is encoded in this CODE128 barcode.

1-D barcodes are slightly more challenging for the system especially with a PiCamera which doesn’t support autofocus. That being said, I achieved a successful detection and decoding of this barcode as well.

You might have best luck with a USB webcam such as the Logitech C920 which has great autofocus. Alternatively, you can actually change the factory focus on your PiCamera using the method that Jeff Geerling describes on his blog.

That’s a wrap!

If you’re interested in reading additional barcode blog posts on my website, check out the posts with the “barcode” tag.


In today’s blog post you learned how to build an OpenCV barcode and QR code scanner.

To accomplish this, we used the ZBar library.

Once the ZBar library was installed on our system, we created two Python scripts:

  1. The first one to scan barcodes and QR codes in a single image
  2. And a second script to read barcodes and QR codes in real-time

In both cases, we used OpenCV to facilitate the process of building our barcode/QR code scanner.

Finally, we wrapped up today’s blog post by deploying our barcode reader to the Raspberry Pi.

The barcode scanner is fast enough to run in real-time on the Raspberry Pi without an issue.

Feel free to use this barcode and QR code scanner functionality in your own projects!

And if you build something fun and interesting with it, be sure to share your project in the comments.

I hope you enjoyed today’s post. I’ll see you next week.

To be notified when future blog posts are published here on PyImageSearch, be sure to enter your email address in the form below!


If you would like to download the code and images used in this post, please enter your email address in the form below. Not only will you get a .zip of the code, I’ll also send you a FREE 17-page Resource Guide on Computer Vision, OpenCV, and Deep Learning. Inside you'll find my hand-picked tutorials, books, courses, and libraries to help you master CV and DL! Sound good? If so, enter your email address and I’ll send you the code immediately!

, , , ,

149 Responses to An OpenCV barcode and QR code scanner with ZBar

  1. Nachiket May 21, 2018 at 12:01 pm #

    Hey Adrian, you have written this following note:
    ” If you already have OpenCV installed on your system you can skip the OpenCV compile process and simply sym-link your bindings into the site-packages directory of your new Python virtual environment”.
    Here you have mentioned to symlink the file with site packages …How to do it? Can you please elaborate on that?
    Thank you

    • Adrian Rosebrock May 21, 2018 at 2:27 pm #

      Hey Nachiket — are you using a Python virtual environment? And did you follow one of my tutorials here on PyImageSearch to install OpenCV? Provided you used one of my tutorials, select the relevant one, and then follow the sym-link steps.

      • Nachiket June 2, 2018 at 1:04 am #

        Yes sir I have always followed your tutorials on creating virtual environment but I couldn’t find the symlink steps. I have recently followed the rpi stretch OS installation on Rpi, are symlink steps are involved there?

        • Adrian Rosebrock June 5, 2018 at 8:08 am #

          If you are struggling with the process I would just recommend installing the ZBar into your current Python virtual environment.

  2. Gilad May 21, 2018 at 5:07 pm #

    Great post.
    I actually open the url with webbrowser

    Now – It will be great to port it to my phone (Android)

    • Adrian Rosebrock May 22, 2018 at 5:57 am #

      Thanks Gilad, I’m glad you enjoyed the post and found it helpful 🙂

  3. Suganya Robert May 21, 2018 at 10:05 pm #

    Hi Adrian,
    It is interesting. You are increasing my hope to continue my research in the field of IoT. Waiting for more posts.

    Thank you.

    • Adrian Rosebrock May 22, 2018 at 5:54 am #

      Thank you for the kind words, Suganya 🙂

  4. Godwine Papin May 23, 2018 at 6:12 am #

    Hello I am very interested in your work on opencv and python. Currently I am working on a project using opencv and python. I have questions of understanding to ask you. Can you send me your email address or directly reply to my email address: EMAIL ADDRESS REMOVED. Thank you Best regards

    • Adrian Rosebrock May 23, 2018 at 7:08 am #

      Please do not share your email address directly within a comment. You can contact me via the PyImageSearch contact form.

  5. TetsFR May 24, 2018 at 4:22 am #

    Hi, first thank you very much for your excellent tutorial, super clear and complete as usual.
    2 quick questions:
    1. How many fps do you achieve on the rpi3?
    2. Why do you always resize to 400px in your tutorial through opencv, especially for video stream? You could setup the frame size h x w at camera init stage at it would save a costly opencv resize at each frame no? (Assuming the sizing is done by the camera, not the video driver)


    • Adrian Rosebrock May 24, 2018 at 6:35 am #

      1. I did not compute the raw FPS but the barcode detector was easily running in real-time on the Raspberry Pi 3.

      2. You could certainly do that as well; however, you should be careful when doing it. There are times were you might want to display the full size output frame but process a smaller version of the frame for efficiency/accuracy. A great example would be processing all frames in a video file and writing them back to disk. It’s a use case decision to be mindful of.

  6. K May 30, 2018 at 10:15 am #

    Hi Adrian, first of all thanks for this great tutorial!

    I have a couple questions on how I can further improve the system.
    I tried running the python file with some images of my own (of objects with QR codes on it) but it would not detect the QR codes at all.

    Is this because of noise? Or could it be that the size of the QR code in respect to the image overall is too small?

    I have also tried to run it with a resized and enlarged photo, but it does not seem to work and I’m not sure what next steps I should be taking and would like some advice.


    • Adrian Rosebrock May 30, 2018 at 5:55 pm #

      This could happen for many reasons, including noise, the QR code being too small, or an issue with your camera sensor. Unfortunately I’m not sure what the issue would be without seeing an example image of what you’re working with.

  7. Markus June 4, 2018 at 4:03 am #

    Hi Adrian, thank you for your great tutorials! For a running project I tried to combine some of your blog posts. I would like to detect DataMatrix Codes in an Image or Video-Stream.
    Unfortunately ZBAR does not Support Datamatrix Codes. I tried pylibdmtx ( ) and it works fine for perfect separated and aligned Codes but (of course) not for detection within an image or video.
    I gave OpenMV a chance but the result was very slow an not suitable for small Codes because of the low resolution of the camera.
    Based on your blog post („Detecting Barcodes in Images with Python and OpenCV“) I also tried to detect the DataMatrix Code with OpenCV. Its perfect for 1D-Barcodes but it failed in detecting 2D-Barcodes…
    Can you give me a hint, how to detect DataMatrix Codes in OpenCV?

    Thank you & Best regards

    • Adrian Rosebrock June 5, 2018 at 7:54 am #

      It sounds like you may want to continue working with the pylibdmtx library for the project. I don’t have any experience with that particular library but if you’re having issues detecting/reading the DataMatrix codes you may want to try cleaning up the image and extracting just the barcode before you try to pass it into the library.

    • Ambarish May 31, 2019 at 10:30 am #

      Hi I have come up with the same problem. If you have solved, can you point me to the right direction to be able to read data matrix in real time? or provide me with the solution?

  8. Saverio Pieri June 11, 2018 at 10:18 am #

    Hi Adrian,
    thanks for this tutorial. I did some experiments: the software recognizes correctly the bar code only if it’s very close to the camera (2/3 inches).
    It will be great to implement an object recognition for bar code images in a frame, crop the rect and pass it to pyzlib.

    Using a HiRes camera (FullHD) it would be possible to increase the results.

    What do you think about it?

  9. ashish June 20, 2018 at 5:36 pm #

    thanks for the tutorial. I was trying real time barcode scanning using a web cam, since the pi camera have fixed focus. can u give me a link or your own work on barcode scanning using web cam. It would be a great help

    • Adrian Rosebrock June 21, 2018 at 5:41 am #

      The code in this blog post already works with a webcam. See Lines 18 and 19 of the script.

      • ashish June 21, 2018 at 9:11 am #

        oh yeah, thanks for the great tutorial

  10. peen June 28, 2018 at 2:51 am #

    hi adrian,
    ive followed each step you taught, but im getting :

    from pyzbar import pyzbar
    ImportError: No module name pyzbar

    • Adrian Rosebrock June 28, 2018 at 7:59 am #

      You need to install the pyzbar library as instructed in the post:

      $ pip install pyzbar

      If you are using a Python virtual environment make sure you access it when you install pyzbar and when you run the code.

  11. peen July 1, 2018 at 1:20 am #


  12. peen July 1, 2018 at 2:39 am #

    hi, im getting error:

    ImportError : no module named

    but, ive already uninstalled and installing it again by using ‘sudo pip3 install –upgrade imutis’

    ive also imported in python and not getting error

    so why did the importError happened?

    • Adrian Rosebrock July 3, 2018 at 8:35 am #

      Are you using a Python virtual environment? If so, you can’t use “sudo” as sudo will install into your system Python. Instead, use “workon” to access your Python virtual environment and then “pip install imutils”. If you’re not using a Python virtual environment let me know.

      • Katherine July 21, 2019 at 1:06 am #

        Hi Adrian,

        I am getting the same error as Peen, that is I get ImportError: No module named even though I have successfully installed imutils. I am NOT using a Python virtual environment (because I cannot create it for some reason, even though I followed your tutorial for installing OpenCV).

        Thank you!

  13. Raymond July 2, 2018 at 8:13 am #

    Hi Adrian,

    I’ve combined this tutorial with your other tutorial to control an LED when an green surface is detected. I need to scan barcodes and check them with a preferred barcode, when the barcode differs from the preferred one it will give a signal to an LED. To ensure a good scan I made a flashlight which will lighten the barcode. Unfortunately the camera change automatically the parameters of the brightness and contrast. How can I set the contrast to an preferred number? I use this for the stream:

    vs = VideoStream(src=0).start()

    frame =
    frame = imutils.resize(frame, width=400)

    I’ve tried to put some set parameters but every time I get aan AttributeError.
    I placed “vs.__init.set(CV_CAP_PROP_BRIGHTNESS, 0.1) after the vs = VideoStream(src=0).start()

    Can you help me with this, please?

    Kind regard,


    • Adrian Rosebrock July 3, 2018 at 7:28 am #

      The VideoStream class is not intended to have the camera properties set that way. I have an idea to update the “src” attribute with a pre-initialized cv2.VideoCapture object in the future but haven’t been able to.

      Instead, I would suggest you use the WebcamVideoStream form imutils instead. Before you run the .start() method of the object you can set any camera properties:, value)

  14. Tenda Support Number July 9, 2018 at 1:52 pm #

    I was thought about to make a mini project on the technology-based something and after visit this blog I have got the idea to try this in my project using zbar for scanning barcode and QR code. keep posting this kind of interesting technology-based experiments.

  15. Po-Hsun July 16, 2018 at 6:22 am #

    Hi Adrian,

    I have followed your instructions, and it works great. However, when I have a small QR code; approximately 0.7 inch x 0.7 inch, the QR code can’t be detected. Is there anyway to improve it? Thank you

    • Adrian Rosebrock July 17, 2018 at 7:19 am #

      You may want to consider resizing your image and increasing the resolution of your input image prior to passing it through the detector.

  16. Felipe Cesar July 18, 2018 at 7:27 am #

    Dear Adrian, firstval i congratulate you for the great qork you’ve done. I have a question, i’m just a beginner, can i get the streaming from an IP Camera with VideoStream Class? Thanks.

    • Adrian Rosebrock July 20, 2018 at 6:45 am #

      Provided you use vs = VideoStream(src="your IP path") it should work.

      • Felipe Cesar August 3, 2018 at 9:20 am #

        Thanks! It worked. The Ip camera detects only QRcode but when i try to detect barcode, it dosn’t work. Dou you have any idea? Thanks

        • Adrian Rosebrock August 7, 2018 at 7:05 am #

          I had some issues with ZBar detecting some barcodes. It always worked really well for QRcodes but not always barcodes. I think it may be a limitation of the ZBar library itself.

        • Robert Reed August 13, 2018 at 6:43 pm #

          My PiCamera was initially unable to detect barcodes because the image itself was too blurry, so it wasn’t able to detect the barcode. Manually adjusting the focus (rotating it counter clockwise) of the camera fixed this for me. Keep in mind, the camera is now essentially set up to only focus on close-up images, and is blurry further away.

          I found the idea here:

          I was able to rotate the focus using my fingernails while supporting the base of the camera. Hope this helps get a more crisp image!

  17. ashish August 1, 2018 at 8:38 am #

    what if i have an entry of almost 50k barcode values in the csv file and i have to cross check one value that i read using a code that goes through the main csv file. How much time in average will it take if the particular barcode value is almost at the last of csv file.

    • Adrian Rosebrock August 2, 2018 at 9:28 am #

      I would suggest you run an experiment and see as it will depend on which hardware you are using. Generate 50K barcode entries and then run your matching algorithm.

  18. john August 1, 2018 at 11:52 am #

    the frame rate for real time barcode snanning is low. any method that can increase the frame rate for video using a webcam.

    • Adrian Rosebrock August 2, 2018 at 9:26 am #

      Hey John, did you try the code on your system? The frame rate is actually much higher than it appears on the GIF animations. To create the GIFs I just wrote a Python script to take a screenshot every two seconds.

  19. Liam Scobey August 9, 2018 at 1:22 pm #

    Hey Adrian, great tutorial, I got this up and running in no time. I was hoping to use this through ssh, and I was able to do that by commenting out the cv2.imshow line, and that allows it to work well enough for me. However, it would be a great bonus if I could stream the actual video via ssh in addition to the data. Is that doable or would that be a whole additional project?

    Thanks for any advice. By the way I’m running this on a Raspberry Pi 3

    • Adrian Rosebrock August 9, 2018 at 2:35 pm #

      You can use “cv2.imshow” and have the result streamed to your machine connected to the Pi by enabling X11 forwarding:

      $ ssh -X pi@your_ip_address

  20. subeesh August 25, 2018 at 4:02 pm #

    hey adrian first of all thanks for this wonderful tutorial,i got the output but i need to print the barcodes in a seperate terminal how can i do that?

    • Adrian Rosebrock August 30, 2018 at 9:34 am #

      What do you mean by a “separate terminal”?

  21. Vedant September 10, 2018 at 2:37 am #

    What if I use this on a raspberry pi controlled drone? Will it be able to detect the QR code while the drone is moving at a certain speed? There is probably a threshold speed for this right? Is that speed high enough?

  22. Fariya hossain September 15, 2018 at 3:19 am #

    Hi adrian
    I am following your tutorial for qr code scanner but when i m trying to import pyzbar its keep saying “no module named pyzbar”
    But i have installed it on my virtual environment… Can you please explain what is the problem here???

    • Adrian Rosebrock September 17, 2018 at 2:51 pm #

      Hey Fariya — my guess is that you may be forgetting to install pyzbar into your Python virtual environment and/or you installed pyzbar outside the Python virtual environment but are trying to execute the code within a virtual environment.

  23. Walid September 27, 2018 at 2:59 pm #

    Thanks a lot.
    Any idea how to try to detect a 3cm*3cm from 3 to 5 m away?
    it seems that far distance will be a large problem
    Thanks a lot

  24. Syed September 29, 2018 at 2:30 pm #

    hi Adrian, thanks for this great topic, I have a question, in my case i have a server that generate qrcode, i want to post them to a raspberrypi connected to turnstile door, so when a person scan the qrcode the raspberrypi will check the database in the server and if the qr exist it will trigger the door.

    do you have an idea what is the best way to implement it and in real time?

    • Adrian Rosebrock October 8, 2018 at 12:12 pm #

      Hey Syed, this sounds less like a computer vision problem and more like an actual “engineering” problem. If you’re new to basic web servers and databases I would suggest you read up on them first. I’m happy to help and provide suggestions but again, I ask that the questions be related to computer vision.

  25. Gabriela October 5, 2018 at 3:31 pm #

    Hi Adrian want to use this code for small QR code (0.75×0.75 in) but It doesnt work with this size, how can I change the frame rate or resolution using imutils? Pleas help is for a Univerity project

    • Adrian Rosebrock October 8, 2018 at 9:49 am #

      Take a look at Line 32 — that line will control the spatial dimensions the input frame is resized to.

  26. Ty October 5, 2018 at 7:16 pm #

    I tried the video stream option with both pi camera and a USB web cam, neither one recognizes the QR code in it. I adjusted the USB web cam focus to make sure the video quality is clear to show the QR code, however it still doesn’t recognize it. When I tried to take still picture of the QR code printed in a piece of paper held in front of the USB Web Cam, it turned out ok. So is this because pyzbar can’t recognize the qr code in the video feed or something else about the web cam? I didn’t see any error message printed out.

  27. daniele October 7, 2018 at 6:50 pm #

    This is absolutely brilliant. Is there a simple way to break down a large text file into several qr codes and then put it back together?

    • Adrian Rosebrock October 8, 2018 at 9:35 am #

      Thanks Daniele, I’m glad you liked the post. As for “breaking down larger text” I’m not sure what you are referring to. Could you elaborate?

  28. Jetlin October 11, 2018 at 9:45 am #

    Nice Tutorial, What should I do if I want to save the detected code(QR) in a text file or redirect the URL in a browser. Could you please explain?

    • Adrian Rosebrock October 12, 2018 at 9:02 am #

      The code covered in “” already shows you how to save the decoded QR code to a text file. Please refer to it.

      • Jetlin October 16, 2018 at 6:41 pm #

        Thank you sir..

  29. Saeed Sahoor October 26, 2018 at 4:24 pm #

    Is Raspberry pi zero could use with the an openCV barcode and QR code scanner with Zbar??
    thank you Adrian Rosebrock

    • Adrian Rosebrock October 29, 2018 at 1:38 pm #

      I haven’t tried but I assume it would work.

  30. Saeed Sahoor October 26, 2018 at 6:03 pm #

    Nice tutorial, I could use it to make a quadcopter.

    • Adrian Rosebrock October 29, 2018 at 1:37 pm #

      A quadcopter that does barcode recognition…?

      • saeed October 30, 2018 at 10:27 am #


        • Adrian Rosebrock November 2, 2018 at 8:19 am #

          I’m not sure how that would work exactly. Quadcopters move very quickly and often introduce motion blurring into frames. Barcode scanners on the other hand normally require high quality images of the barcodes. Realistically I think you would struggle to make such a solution work.

          • Saeed November 9, 2018 at 3:15 am #

            Exactly, but I’m optimizing this issue

  31. shen October 29, 2018 at 12:17 pm #

    thanks adrian for ur awesome tutorial , i have already successfully install open cv in my raspbians…Back to my question, I apologize for asking a newbie question, but may i know WHERE DO U insert all these codes from line 1 onwards , is it through the terminal or other platform ?

    • shen October 29, 2018 at 12:19 pm #

      i mean as in how do u open the “new file”

      • Adrian Rosebrock October 29, 2018 at 1:02 pm #

        You could use your favorite text editor or a full-fledged programming IDE. I really like Sublime Text 2 and PyCharm.

  32. Israel October 29, 2018 at 9:27 pm #

    hi adrian, i have a problem with the code in real time.
    I’m using a PiCamera and I’m getting error:

    from picamera.array import PiRGBArray
    ImportError: No module named ‘picamera’

    so why did the importError happened?

    • Adrian Rosebrock November 2, 2018 at 8:35 am #

      It sounds like you do not have the “picamera” library properly installed on your machine:

      $ pip install "picamera[array]"

      • israel November 2, 2018 at 8:53 am #

        Yes, that was the problem,


  33. James October 29, 2018 at 11:33 pm #

    Hi Adrian,

    Thanks for the post. I have been struggling to get OpenCV to install, so I followed the PIP install, and got that completed, inside the Virtualised env.

    I then installed the ZBar tools in the same environment.

    When i try to process a still image, i get the message:
    : cannot connect to x server

    This seems to be happening with the code
    (x, y, w, h) = barcode.rect

    Any ideas? I am just using an image with two barcodes on it.. taken with the pi cam.



    • James October 29, 2018 at 11:44 pm #

      Hi Adrian..

      The issue was I am trying this via ssh… rather than via the GUI on the Pi.

      Any tips to getting this working via SSH?



      • Adrian Rosebrock November 2, 2018 at 8:34 am #

        Make sure you are enabling X11 forwarding if you are SSH’ing into your Pi:

        $ ssh -X pi@your_ip_address

  34. shen October 31, 2018 at 4:35 am #

    greetings adrian, do u have any idea that i can place the information that i gather from the qr code to compile them in any sheets , eg: google spreadsheet, appreciate ur assistance

    • Adrian Rosebrock November 2, 2018 at 7:41 am #

      I would research the Google Docs APIs. I’m not familiar with them but I’m sure it’s possible to programmatically access a Google Sheet and add the data. That’s really outside the context of the blog post though. Best of luck with the project!

  35. ricky h sinabutar November 2, 2018 at 10:42 am #

    Hello Adrian, Can i get decode qrcode and stop video stream to next step like access door lock or query to database ? i tried your code but i couldn’t query to database because result decode is stream and not stop when take/decode qrcode.

    • Adrian Rosebrock November 6, 2018 at 1:36 pm #

      Sorry Ricky, I’m not sure what you mean here. Is your goal to detect a QR code and then have it perform an automation like open a door?

  36. R November 7, 2018 at 1:18 am #

    On the Raspberry Pi Zero W, I was receiving an “Illegal instruction” error while trying to run the code samples.

    I found a [github issue]( that explained what was happening.

    The solution was to change this line

    > frame = imutils.resize(frame, width=400)

    to this

    > frame = imutils.resize(frame, width=400, inter=cv2.INTER_CUBIC)

    • Adrian Rosebrock November 10, 2018 at 10:21 am #

      Indeed, it’s a strange issue. I truthfully have no idea why it’s happening.

  37. Bobaddababyeatsaboy November 10, 2018 at 11:14 pm #

    how can I break the while loop after i have scanned the code or codes I want?

    • Adrian Rosebrock November 13, 2018 at 4:57 pm #

      Press the “q” key on your keyboard with the window opened by OpenCV active.

  38. Özal November 12, 2018 at 1:36 pm #

    i have a problem. it can not read some Qr Code includes Turkish characters. How can solve the problme

    • Adrian Rosebrock November 13, 2018 at 4:36 pm #

      I would reach out to the zbar developers directly and ask them what else you could do to improve accuracy for Turkish characters.

  39. help November 14, 2018 at 3:06 am #

    Posting was really helpful! 😀 By the way, I want to control the relay using the QR code.
    Can you tell me how I would like to operate the relay if it recognizes the QR code?

    • Adrian Rosebrock November 15, 2018 at 12:08 pm #

      What “relay” are you referring to? I suggest you consult the documentation of your relay.

  40. David Fontecilla November 14, 2018 at 12:20 pm #

    Excelent Adrian but when running my code a “ValueError: too many values to unpack (expected 2) ” appears so i don´t know if it is because it is a utf-8 decoding and zbar asks for a uint8 type. Thank you!!!!!!!!!!!!!!

    • Adrian Rosebrock November 15, 2018 at 11:59 am #

      What line of code is throwing that error, David?

  41. Mickey November 16, 2018 at 4:02 pm #

    Hi Adrian
    I need to make a qr code scanner for a schoolproject so I followed your guide. I copied your code to a text file (with nano) and then changed to rights to make it an executable file. Then I went out of the virtual workspaceto test it using “$ python –image barcode_example.png” but it says “command not found”. do you have any idea what I did wrong? (I’ve also tried to execute it in the ‘barcode’ workspace but same problem. And the image to test is in my download folder. Thanks a lot!

    • Adrian Rosebrock November 19, 2018 at 12:47 pm #

      Don’t copy and paste the code — make sure you use the “Downloads” section of the tutorial to download the source code and example images. You may have introduced an error while copying and pasting.

  42. Moez Messi November 22, 2018 at 10:20 am #

    Hi Adrian,

    Thank you for all your incredible tutorials, they are well explained.
    the library Zbar work only for barecode and QRcode.there is a library for datamatrix decode.Can you help me to decode a datamatrix from a picture.

  43. risa November 26, 2018 at 3:22 am #

    I want to import serial Real-time barcode and QR code reading with OpenCV this code.
    but I get an error. please Could you tell me how?

    • Adrian Rosebrock November 26, 2018 at 2:28 pm #

      What is the error you are receiving? Without knowing the error I cannot provide any suggestions.

      • risa November 28, 2018 at 2:01 am #

        The error message looks like this:
        import serial
        ImportError: No module named ‘serial
        I want to make serial communication with Arduino. Thank you.

        • Adrian Rosebrock November 30, 2018 at 9:17 am #

          It sounds like you haven’t installed the PySerial Python package. Perhaps try:

          $ pip install pyserial

  44. Gaby November 27, 2018 at 5:37 pm #

    Hi Adrian,

    Thank you so much for this example, personally I had to download another lib packages to my raspberry to use imutils and cv2.
    I was getting two errors when importing this files:
    -ImportError: cannot open shared object file: No such file or directory
    This was solved by typing this command:
    sudo apt-get install libatlas-base-dev

    -ImportError: cannot open shared object file: No such file or directory
    This was solved by typing this command:
    sudo apt-get install libjasper-dev

    After this I could manage to get everything running. Just some questions, the reading seems a little bit slow and it shows the rectangle from the raspi cam very small. Do you know how can we improve this to visualize everything better?
    And also, I cannot seem to read any barcode, just some QRs. Does the works for both?

    • Gaby November 28, 2018 at 11:53 am #

      Hello I managed to read barcodes by adjusting the camera lens focus manually because the image was very blurry. Now it works great! I can read almost any barcode and tons of QRs.
      For the reading speed, I didn’t actually needed to store the data on a csv file, so I comment that code lines and the everything improved a lot.
      I changed the code a bit to have live video since the beginning and to toggle a green led whenever it detects a qr and a barcode I stored before and a red led whenever the barcode/qr is different. I will post my code here once I finish everything.
      Thank you!

      • Adrian Rosebrock November 30, 2018 at 9:16 am #

        Congrats on resolving the issue Gaby! And nice job implementing your script 🙂

      • Fairy January 28, 2019 at 8:01 am #

        Please share your code with us. I want to develop same project, it would be so helpy.
        Thanks alot, I look forward to your response.

  45. Jacob c December 1, 2018 at 11:50 pm #

    Hi so I have been having a problem with Zbar and I was hoping you could help. I have it so I can scan and decode the qrcode but the problem is that it just shows it under my command(I am just using the raspberry pi terminal) and doesn’t do anything with it. Say if I have a url encoded into my qrcode and I use the zbar to decode it it just shows a url code verse actually putting the url in a browser or even a text file. Do you know of a way to export the output of pyzbar?

    • Adrian Rosebrock December 4, 2018 at 10:11 am #

      The code in this tutorial is meant to show you how to extract the value of the QR code or barcode. Exactly what you do after you recognize the code is up to you. It sounds like you want to take the URL and automatically open it in a browser. That sounds very OS and GUI specific so I would suggest you research OS and GUI libraries that can control your browser.

  46. Josh Gold December 5, 2018 at 5:46 pm #

    This is fantastic! Looking forward to trying the 2nd part with a webcam.

  47. Bashi December 13, 2018 at 2:16 am #

    Very nice tutorial and Thanks.
    I have one issue , it reads all qr codes except white barcodes . Is there any option for that?
    Thanks in advance.

    • Adrian Rosebrock December 13, 2018 at 8:53 am #

      Have you tried inverting the barcode? I would suggest reaching out to the Zbar library developers if it’s specifically related to a type of barcode.

  48. Francois January 8, 2019 at 1:48 am #

    Hi Adrian,

    Great project you present here !
    i was wondering, is there a way to shut down the streaming once the barcode is detected ?

    thanks in advance

    • Adrian Rosebrock January 8, 2019 at 6:39 am #

      Once you’ve detected a barcode and read it you can break from the while loop and shut down the streaming.

  49. tortoise January 24, 2019 at 3:52 am #

    Hi Adrian,
    Your work is great, thank you very much.
    But I have a problem, that is, the recognition of Chinese garbled.
    For example, “中文” cannot be decoded correctly.
    I have been trying for a long time and can’t realize Chinese recognition.
    Do you have a solution?

  50. Dario January 24, 2019 at 5:29 am #

    Hi Adrian,

    Thanks for your wonderful post.

    I have a problem, I hope you can give me some suggestion to fix it.
    When I run the script the writing “[INFO] starting video stream…” appears. After that only when I put a QRcode in front of the PiCamera the “barcode scanner” window opens, but it is black, no image on it.

    Do you have any idea to fix that?

    Kind Regards

    • Adrian Rosebrock January 25, 2019 at 7:07 am #

      It sounds like a problem with the Raspberry Pi camera module. See this tutorial for a solution.

  51. Fairy January 28, 2019 at 8:06 am #

    Reading a barcode from long distance is not possible. Does it depend hardware or code? How can detect and read barcode from long distance?



  52. Hussain Ali February 9, 2019 at 6:14 am #

    Hi Adrian,
    Thanks for the nice post.
    I’m not able to install zbar library.I’m using ubuntu 18.04.Please help.

    • Adrian Rosebrock February 14, 2019 at 1:55 pm #

      What errors are you running into?

  53. nagasai February 13, 2019 at 8:32 am #

    thanks a lot sir,for the work you shared with us
    but, i am not able to run this code using laptop’s camera.can you help me in solving this issue

    • Adrian Rosebrock February 14, 2019 at 12:57 pm #

      Can you be more specific? Are you getting an error of some sort?

  54. seraj alhamidi February 18, 2019 at 3:28 pm #

    Adrian , thank a lot , it work 100% for me by reading video form my laptop and pass it to your code

    • Adrian Rosebrock February 20, 2019 at 12:24 pm #

      That’s great, I’m glad it worked for you!

  55. Lilly February 26, 2019 at 11:47 am #

    Hey Adrian, thank you so much for the code. Your works is clean and professional. However, I am really new to this so can I use a MAC VMware on my windows laptop and use my laptops camera. Would that work? Thank you

    • Adrian Rosebrock February 27, 2019 at 5:35 am #

      Yes, but you’ll want to refer to the VMware documentation on how to allow access to your host webcam — VMware will block that by default.

  56. Lee March 9, 2019 at 8:32 am #

    Hi, is there any additional argument or parameters which can be passed to the decode function that will allow for identical barcodes found in an image to be N number of Decoded data?

    As of now, only 1 Decoded result was shown when I was trying to decode the attached image. Thanks

    • Adrian Rosebrock March 13, 2019 at 3:56 pm #

      I don’t think there is but you should consider reaching out to the zbar library developers for a more conclusive answer.

  57. Max Hearnden March 14, 2019 at 8:26 am #

    Hi Adrian, I am a design student in the UK and I’m using a Pi and a few different camera modules to optimise your real-time barcode scanner as much as possible. I only need zbar to read QR codes at further distances and I was wondering if you can create the illusion of a higher frame rate using a different camera module or USB camera or even your ‘pi object detection’ blog post? Would I be better running the programme from a laptop? I’m a total beginner to this but I am learning fast with thanks to your blogs, Thanks in advance

  58. Shantanu April 3, 2019 at 11:39 am #

    Hi,Adrian .First of all thank you so much for the code .Actually ,i was running it on Raspberry pi and as i am not having pi camera i was trying to access it using webcam of the laptop but it shows me error :
    “VIDEOIO ERROR: V4L: can’t open camera by index 0 ”
    Please can you help in resolving this issue and Thanks alot.

    • Adrian Rosebrock April 4, 2019 at 1:18 pm #

      Are you using a Raspberry Pi camera module? If so, Make sure Line 18 is commented out and Line 19 is uncommented.

  59. Budi Rahardjo April 10, 2019 at 9:12 pm #

    Thank you for the code. Works perfectly. I ran in on my Macbook. Minor modification and I got it the way I like it.

    • Adrian Rosebrock April 12, 2019 at 11:30 am #

      Thanks Budi! And congrats on a successful project.

  60. KUMAR SHUBHAM April 17, 2019 at 12:02 pm #

    Which are the other Python barcode decoding library apart from zbar ?

  61. John Markhorst May 8, 2019 at 5:45 pm #

    Is it possible to recognize and decode multiple barcodes simultaneously? I an looking to quickly video 80-100 barcodes on boxes and pass them to an external api.

  62. Jack May 9, 2019 at 10:21 am #


    Thanks for great tutorial! works great, i ended up using a hd920 did not find the rpicam good enough when the distance got a bit longer.

    I am trying to build a delay or stop in the script that will wait on motion detect. can’t really get it right. Could you point me in the right direction? (i am not barcodedata to found since i want all barcodes to be logged, however i want the program to stop and wait untill a change has occured in the frame. )

    Thanks in advance!

    • Adrian Rosebrock May 15, 2019 at 3:19 pm #

      What do you mean by a delay/stop? What is the goal of using it?

  63. Ridhima Garg May 15, 2019 at 3:51 am #


    Thanks for the nice explanation.

    Will it work for pdf417 barcode?

    • Adrian Rosebrock May 15, 2019 at 2:31 pm #

      I’m not sure, you would need to refer to the ZBar documentation.

  64. Francisco May 21, 2019 at 6:41 pm #

    Hi Adrian,
    What can you say about performance on RPI?
    Which is de minimum or average time to detect and process a QR code?
    And in wich conditions: RPI version, image resolution, ….

  65. Samith June 16, 2019 at 9:31 am #

    Hi Adrian,

    Many thanks for the clear instructions. I had no previous experience, however managed to get it work with your step by step instructions.

    Going to use it practically to register the attendance (low cost system)

    Thanks again.

    • Adrian Rosebrock June 19, 2019 at 2:08 pm #

      Thanks Samith — and congrats on getting up and running with OpenCV and ZBar!

  66. krishnateja June 24, 2019 at 11:29 pm #

    Hi Adrian,
    I am doing a project using your tutorial, where the moving robot should detect QR codes on the ground and stop, but on motion, my robot is not detecting the qr code. Could you please provide me with a better approach in achieving this task. I am using a webcam and my laptop as a computer.


    • Adrian Rosebrock June 26, 2019 at 1:10 pm #

      Sorry, I cannot write custom code for your project. I would suggest debugging the QR code detection first before you even attempt controlling the robot. Make sure your code + camera can correctly recognize the QR code.

  67. Help July 17, 2019 at 12:12 pm #

    Hi Adrian,

    I am doing a project in which i have to detect QR Codes from bill images. But PyZBar is not detecting the QR Codes because they are not clear and are at some angle not flat images. What should i do?

  68. Patrick August 14, 2019 at 8:59 am #

    Hi Adrian,

    thanks for that tutorial it just works fine. But i’ve got a problem. I try to take a picture after detecting the qr-codes. I tried with subprocess and raspistill, but i get the mmal: Problem.

    Could you please tell me how to take a picture while the videostream is opened?

    Thanks a lot

    • Adrian Rosebrock August 16, 2019 at 5:34 am #

      You can’t. The Python script has access to the camera — two processes cannot access the camera at once. Instead, just use “cv2.imwrite” to save the frame to disk via the Python script.

  69. Richard Fuller October 3, 2019 at 10:39 am #

    Hi Adrian
    I love the simplicity of your tutorials, I’ve been able to get a static barcode reader code to work but I’ve been very hamstrung by having real trouble getting the PIP installs to work at all on my windows 10 desktop (running 64 bit Python 3.7). I managed to get somewhere by taking CV2 instead of opencv-python and I found a site that allowed me to download numpy and PIP install in a CLI ( I haven’t been able to download imutils at all so am stuck at this point.

    Also, I’ve installed the packages locally from the download but I want the software within a virtual environment within PYcharm and I’m not sure how that can be done.

    Any help would be gratefully received, the barcode read element is crucial to what I’m trying to do.

  70. Zaya October 3, 2019 at 5:16 pm #

    Hi Adrian,
    I attached my OpenMV USB cam to my raspberry pi. I commented out line 19 and uncommented line 18, however I get an error saying ‘NoneType’ object has no attribute ‘shape’. Ive tried going through your article here …but I couldn’t find a solution that works in my case..Am I missing something? any help would be appreciated!

  71. owen November 2, 2019 at 9:27 am #

    hi adrian,
    thx for your great work

    • Adrian Rosebrock November 7, 2019 at 10:25 am #

      Thanks Owen!

  72. Jeff December 4, 2019 at 5:43 am #

    Thanks for the tutorial! The pyzbar seems to not recognize UAC-A, UPC-E and other types of barcodes. Can’t really find good documentation on this. I don’t want a leading zero added to my UPC-A barcodes.

    Any suggestions? Another zbar library possibly?

  73. Anna December 9, 2019 at 1:21 pm #

    Amazing tutorial, I got it working but i would like it to close automatically after 15 seconds and not with the q key, I added a time.sleep(15) right after key = cv2.waitKey(1) & 0xFF and it works but the barcode scanner windows is kinda laggy; where should i put that sleep?

    Thanks in advance. 🙂

  74. Yuvraj December 10, 2019 at 9:10 am #

    I want to read barcodes in real time and then play videos corresponding to a certain barcode on the pi. Any suggestions?

Before you leave a comment...

Hey, Adrian here, author of the PyImageSearch blog. I'd love to hear from you, but before you submit a comment, please follow these guidelines:

  1. If you have a question, read the comments first. You should also search this page (i.e., ctrl + f) for keywords related to your question. It's likely that I have already addressed your question in the comments.
  2. If you are copying and pasting code/terminal output, please don't. Reviewing another programmers’ code is a very time consuming and tedious task, and due to the volume of emails and contact requests I receive, I simply cannot do it.
  3. Be respectful of the space. I put a lot of my own personal time into creating these free weekly tutorials. On average, each tutorial takes me 15-20 hours to put together. I love offering these guides to you and I take pride in the content I create. Therefore, I will not approve comments that include large code blocks/terminal output as it destroys the formatting of the page. Kindly be respectful of this space.
  4. Be patient. I receive 200+ comments and emails per day. Due to spam, and my desire to personally answer as many questions as I can, I hand moderate all new comments (typically once per week). I try to answer as many questions as I can, but I'm only one person. Please don't be offended if I cannot get to your question
  5. Do you need priority support? Consider purchasing one of my books and courses. I place customer questions and emails in a separate, special priority queue and answer them first. If you are a customer of mine you will receive a guaranteed response from me. If there's any time left over, I focus on the community at large and attempt to answer as many of those questions as I possibly can.

Thank you for keeping these guidelines in mind before submitting your comment.

Leave a Reply