Reading barcodes with Python and OpenMV

What if I said that there’s a camera that:

  • Is low cost at $65.
  • Runs MicroPython.
  • And can be expanded with shields just like an Arduino/RPi.

Meet OpenMV!

I met Kwabena Agyeman, the founder of OpenMV, during the PyImageSearch Gurus Kickstarter campaign in January 2015.  At that time, Kwabena and the OpenMV team were running a Kickstarter of their own. Kwabena’s Kickstarter raised a lot more funds than mine, which really demonstrates (1) the value of the OpenMV product and (2) the eagerness of the embedded community to work with such a tool.

Since the OpenMV Kickstarter, the OpenMV team has been on a mission to provide a low cost, Python-ready, and easy to use camera system for developers and engineers working on embedded computer vision projects.

Given the success of OpenMV so far, perhaps it’s no surprise that there is an active community of developers. You’ll definitely have the support needed to make your project a success. When I started building the barcode scanning system for this post I was incredibly impressed by the responsiveness of their users and forums.

In today’s blog post, you’ll be introduced to OpenMV, their fancy IDE, and we’ll even build your own barcode scanning system.

To get started with the OpenMV cam and barcode decoding with computer vision, just keep reading.

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

Reading barcodes with Python and OpenMV

Figure 1: The OpenMV can read QR codes among many types of codes — all with built in libraries!

There’s no way of getting around barcodes in today’s world.

Every grocery item or Amazon package you receive has them. Every time you board an airplane or rent a car, barcodes are used. And heaven forbid, the a barcode could be associated with your identity on a hospital wristband during an emergency visit!

But why?

Simply put, barcodes are an easy way for computers to associate an item with a database. It’s therefore important that barcodes are decoded properly so that databases can be updated.

Typical barcode readers use a photoelectric cell to “see” the code. Check out this post by Chris Woodford on Barcodes and barcode scanners.

Given the prominence of cameras in today’s age, we can actually use image processing to detect and decode barcodes.

In a previous post here on PyImageSearch, I demonstrated how to detect barcodes with Python and OpenCV.

Detecting is one piece of the puzzle.

The other piece is decoding the barcode into a useful string.

Unfortunately, OpenCV does not contain built-in barcode detection + reading functionality…

…but there are a few popular libraries for barcode detection, one of which is ZBar. Satya Mallick, a PyImageConf 2018 presenter, wrote a great post about ZBar last month on his blog.

Using ZBar and other similar barcode reading libraries is one method to accomplish the task.

The other option is to use embedded tools and libraries such as OpenMV.

In fact, OpenMV makes it so easy to detect and read barcodes that you could:

  • Build your own barcode scanning device
  • Create an automated part inspection system on an assembly line
  • Utilize OpenMV in a hobby project to help you scan and organize components and peripherals in your workshop
  • Use OpenMV to teach middle school or high schoolers about embedded programming

The OpenMV cam

Figure 2: The OpenMV camera is a powerful embedded camera board that runs MicroPython.

Aimed at being the “Arduino of Machine Vision”, the OpenMV cam is embedded (no OS) and is expandable via several available shields (just like an Arduino).

It is also dead-simple to use — you write code with MicroPython (unlike an Arduino).

Python users and readers of this blog will feel at home when building embedded computer vision projects with MicroPython for the OpenMV.

The OpenMV camera is quite capable and would fit well in a small robotics project with servo motors or even in a automated part inspection assembly line.

You can easily interface the OpenMV with other hardware, sensors, microcontrollers, and SBCs over communication protocols such as SPI, I2C, WiFi, and USB.

OpenMV will typically work best if it just has one or two tasks to perform as it does have limited memory (31KB is allocated for scripts). If you need to record stills or video you may plug in a microSD.

Image processing capabilities of the OpenMV include:

  • Haar cascades
  • Thresholding
  • Blob detection
  • Drawing lines, circles, and rectangles
  • Recording GIFs and MJPEGs
  • Reading barcodes (this post)
  • Template matching
  • …and more!

For the full list, be sure to check out the docs.

Do you need a particular lens for your application? One differentiator is the Standard M12 Lens Mount. Now you can attach that telescopic zoom or fisheye lens for your project. I sure do wish that the Raspberry Pi PiCamera has a lens mount like the OpenMV does.

Barcode detection and decoding with OpenMV and Python

Once you’ve installed the OpenMV IDE, fire it up. We’ll be doing all of our coding in the OpenMV IDE.

Let’s begin by creating a file called :

On Lines 2-4 we import our required MicroPython/OpenMV packages.

Optionally, on Line 9, you can import the lcd  package which is required if you want to use the LCD shield.

Next, let’s set up the camera sensor:

The settings on Lines 12-29 are self explanatory, so please read the code and comments.

I do want to point out that the LCD requires a resolution that fits the screen ( sensor.QQVGA2 ).

Note: I tried and tried to figure out how to use the full resolution and then make a scaled image which would fit on the LCD, but was unable. Because of this, if you do elect to use the LCD, you’ll be trying to decode barcodes at a lower resolution (which isn’t optimal for traditional 1D barcodes). Needless to say, the LCD is still a good debugging tool, and I wanted to include it so that you can see that it’s very easy to use. As always, if you are able to solve this problem, then I encourage you to leave me a comment below the post to share with me and the community.

I’d also like to point out Line 27. In the “hello world” example you’ll see a keyword argument time=2000  to sensor.skip_frames . Keyword arguments aren’t supported in this context, so be sure to use this syntax shown on Line 27 (especially if you are working through the “hello world”).

Next, let’s perform initializations:

You’ll want to uncomment Line 33 if you are using the LCD (see the previous code block).

Line 36 initialize our clock for FPS calculations

From there we’ll create (1) a lookup table and (2) a convenience function for determining the type of barcode:

As you can see on Lines 39, where I defined a barcode_type  dictionary, the OpenMV can detect and decode quite a few different barcode styles.

That being said, I didn’t have luck with all of them, so the PDF included with the “Downloads” section of this blog post doesn’t include every type of barcode.

Lines 57-63 define a convenience function for grabbing the barcode type without risk of throwing a Python key exception (the OpenMV does not handle exceptions well).

From there, let’s get down to business and start capturing and processing frames! We’ll begin by starting a while  loop:

The first step is to tick the clock for our FPS counter (Line 68).

From there you should grab a frame with sensor.snapshot  (Line 71).

Now, let the fun begin!

We’ve got an image, so let’s see what we can do with it:

Here we’re finding standard, non-QR codes. All we need to do is call img.find_barcodes (which encapsulates all barcode detection + reading functionality) and loop over the results (Line 74).

Given the detected barcodes we can:

  • Draw a bounding box rectangle around the detected barcode (Line 76).
  • Print the type, quality, and payload (Lines 79-82).
  • Draw the string on the screen (Line 85). Unfortunately (according to the docs) there is no current way to draw the string in a larger font.

That’s really all there is to it!

QR code decoding is done in a similar fashion:

This loop mimics the standard barcode loop, so be sure to review it for details.

Outside of the loop, if you’re using the LCD, you’ll want to display on it (Line 100).

Lastly, we can easily print the FPS (frames per second) in the terminal on Line 103.

OpenMV Barcode Decoding Results.

Figure 3: The OpenMV team has put together an awesome IDE for computer vision development. This is what you see when you first open the IDE and load a program.

First, connect your OpenMV cam via USB to your computer.

Then Fire up the IDE as shown in Figure 3.

From there, click the connect button in the lower left.

The IDE may prompt you to update your firmware (which I did without a hitch by clicking the button and waiting about 3-5 minutes).

When you’re ready with your program loaded in the editor, click the green play/program button also in the lower left. This button will set up the OpenMV with your code.

Be patient. It takes about 45-90 seconds for the MicroPython code to compile to machine code and get flashed on the processor. There isn’t a status indicator, so you just need to be patient.

Before long, if you’re printing to the terminal, you’ll see the data such as FPS or barcode information — that’s your queue that everything is working. You’ll also see a live view from the camera sensor in the top right viewfinder.

Now let’s try some barcodes!

In the “Downloads” section, I’ve included a PDF of barcodes for you to print and scan. Here’s what we’re working with:

Figure 4: Sample barcodes for testing with the OpenMV camera. Included are QR, CODE128, CODE93, CODE39, and DATABAR barcode images. You may print a PDF from the “Downloads” section of this blog post.

You can see the results here from the IDE’s built in terminal:

Screenshots of each code and the terminal are below:

Figure 5: Scanning a QR code with a link to the PyImageSearch homepage.

Figure 6: Scanning a QR code that contains a payload of “” — the OpenMV homepage.

Figure 7: This QR code contains a payload directing you to the Deep Learning for Computer Vision with Python book information page.

Figure 8: A CODE128 barcode that says “guru” is decoded by the OpenMV.

Figure 9: The OpenMV can decode CODE93 barcodes such as this one that has a payload of “OpenMV”.

Figure 10: CODE39 barcodes are easy with the OpenMV. The Payload here is “DL4CV”.

Figure 11: The OpenMV can decode DATABAR codes which are fixed-width and only contain digits. I coded “2018” into this barcode, but as you can see, the OpenMV camera actually reads 16 characters.

And finally, here’s a picture of the IDE in action. Notice how it is reading multiple codes, drawing boxes around the barcodes, and also contains a nice color histogram.

Figure 12: The OpenMV in action detecting barcodes and printing results to the IDE. As you can see, there’s a terminal in the bottom left which is scrolling data. There’s also a live view of the camera feed in the top right of the IDE and color histograms in the bottom right.

Here’s a video of the system in action using the IDE:

The IDE is great for debugging. For a deployable project however, you wouldn’t use the IDE. Instead you’d send the barcode payloads out to an actuator via I2C, SPI, or maybe WiFi to be processed in a database.

The LCD tool is also great for debugging although I found that the required resolution didn’t work for all the barcodes on the barcodes.pdf  file included in the “Downloads”.

Nevertheless, here’s the LCD in action:

Figure 13: The OpenMV color LCD shield provides a nice viewfinder for the OpenMV. Pictured are a few barcodes for today’s blog post on decoding barcodes with the openMV.

Does the OpenMV run OpenCV?

In short, no — the OpenMV does not run OpenCV. The processor wouldn’t be able to handle it.

There are a number of capabilities of the OpenMV, but don’t think of it as a replacement for a Raspberry Pi which can run an OS and OpenCV.

But don’t let that deter you from considering the OpenMV for your project!

There’s plenty of OpenCV-like functionality built in.

You’ll feel at home working with the OpenMV examples and turning one into a solution that works in your project, but don’t expect to paste some OpenCV code into the OpenMV IDE and expect it to work.

Oh, and the best part?

You don’t need to worry about a complex install! If the OpenMV firmware needs to be updated, just click the button in the IDE and it will update over USB in a matter of minutes.

The easy install, and basic image processing capabilities make it a great teaching tool to get someone interested in CV.

It also would do well in specific projects, provided the project aligns with one of the image processing capabilities of OpenMV — just be sure that you don’t need something more powerful before you go down this path.

Can I connect the OpenMV to my Raspberry Pi?

Of course you can but there are more reasons against doing so.

The first reason is: the Raspberry Pi can do (mostly) everything the OpenMV can do, and then some. I2C? Check. SPI? Check. PWM? Check. WiFi? Check.

That said, the Raspberry Pi doesn’t have a high powered RGB LED and two high power IR LEDs like the OpenMV does.

But back to the point: Why would you need duplicate capabilities?

You most-likely don’t.

Instead, you should not think of the OpenMV as a general purpose SBC — it’s not.

The OpenMV is particularly great for specific embedded use cases. Another great use case for the OpenMV might be one where you’re concerned about power draw such as on a battery powered drone.

The second reason is that compiling the QT GUI for the Raspberry Pi would take 2-3 days. This isn’t practical. Sure you could do it once, and keep a handy .img lying around so you don’t have to do it again, but it just doesn’t seem practical to me.

So yes — you can definitely plug in the OpenMV via USB or via a custom header/wires to a Raspberry Pi. I just don’t think it is the wise thing to do.

If I’m wrong, let’s discuss in the comments section.

Where can I get an OpenMV camera as well as accessories?

Figure 7: The OpenMV is available at distributors as well as direct at Bulk discounts and kits are available!

The OpenMV is very affordable at $65. Think of it as getting a powerful Arduino and a camera all on one board (that runs MicroPython).

You can pick up an OpenMV Cam at the retailers listed on the sales page, and many of the retailers offer free shipping.

Notable retailers include

There are a few Chinese retailers serving Asia as well as a number of European and UK retailers.

Looking to buy in bulk for your classroom or for a deployment?

If that’s the case, then you can take advantage of the bulk discounts by ordering direct from There’s a piecewise function where you can get 10%, 20%, or even 30% off by buying in bulk.

Shields, shields, shields!

Figure 8: The OpenMV has an assortment of shields available to expand capabilities. Do you want to make your own shield? The hardware is open source, so get started with Eagle CAD or your favorite tool.

There are a number of expansion shields available, so be sure to check the retailers as well as OpenMV direct for purchasing options.

The official shields include:

You’ll need to use your soldering skills in order to attach shields — the headers do not come pre-populated. This is a minor inconvenience, but if you have a soldering iron, you can be up and running in 10 minutes.

It’s also worth noting that all hardware is open source. So if you have electronics skills and need a custom shield and are proficient in Eagle CAD, then you can visit the OpenMV Shield GitHub Repo to select a shield as a starting point to customize for your application.

Do you want a value kit that includes most accessories so you can get started tinkering?

If you order the “Full Set” kit direct from, you get about 10% off the combined price.

The “Full Set” kit includes 7 pieces:

  • 1 – OpenMV Cam M7
  • 3 – Shields (Proto Shield, LCD Shield, WiFi Shield)
  • 3 – Lenses (IR Lens, Telephoto Lens, Ultra Wide Angle Lens)

Figure 9: The OpenMV Full Set bundle is a good kit to get started with. It is 10% off versus buying the items individually.


In today’s blog post we used the OpenMV to perform barcode decoding.

Aimed at being the “Arduino of Machine Vision”, the OpenMV cam is embedded (no OS) and is expandable via several available shields. It’s also extremely easy to use. You can write code on the OpenMV using MicroPython.

However, it’s important to understand that the OpenMV does not run OpenCV — the processor simply would not be able to handle it. That said, there’s plenty of OpenCV-like functionality built in. Using the OpenMV IDE you can put together your own computer vision applications.

Next week I’ll be interviewing Kwabena Agyeman, the creator of OpenMV.

To be notified when next week’s interview with Kwabena goes live, just 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!

, , , , ,

19 Responses to Reading barcodes with Python and OpenMV

  1. Muhammad Umraiz March 19, 2018 at 11:55 am #

    Hi Adrian!
    Thanks for sharing all the valuable asset with us.
    After bar code scanner, can you please guide me how I can build a 2D scanner that can measure objects’ dimensions(height, width, curves) through computer vision.
    remember I am talking about objects that have virtually no depth. For example measuring dimensions of a paper with the help of computer vision. It will be a great service for the industrial cluster in my city that are struggling with this problem. I will really appreciate any help from your side.
    With best regards
    Muhammad Umraiz

    • Adrian Rosebrock March 19, 2018 at 4:52 pm #

      Hey Muhammad — a simple calibration would allow you to measure object dimensions. But keep in mind that you wouldn’t be able to do this with OpenMV as the OpenMV does not run OpenCV.

  2. Monica March 19, 2018 at 12:28 pm #

    Why is the keyword FPGA tagged here?

    • Adrian Rosebrock March 19, 2018 at 4:50 pm #

      FPGA stands for “Field-programmable gate array”. The OpenMV is a type of embedded FPGA device. I mainly wanted to highlight out OpenMV is an embedded device and is not used how we may hook up a camera to our laptop/desktop.

  3. david March 19, 2018 at 3:18 pm #

    can we use openmv lib or code or IDE embedded into other chip or my personal DIY board? Sorry, I am very new to embedded system. Do you have any recommend chips which can use opencv? Thanks!

    • Adrian Rosebrock March 19, 2018 at 4:49 pm #

      Great question, David. I would be sure to ask Kwabena and the OpenMV team. I’ll also ping them and ensure they check on this post and reply to questions.

      • david March 19, 2018 at 11:43 pm #

        Thank you! Adrian!

        • Adrian Rosebrock March 20, 2018 at 5:46 am #

          Hey David — I just wanted to let you know that Kwabena replied and addressed your question. Please see his answer in the comments section.

  4. Simon Fung March 19, 2018 at 11:14 pm #

    Hi Mr Adrian, it is good device to learn the imaging programming. May I know if it can do the OCR inspection like open CV in raspberry Pi3 with Camina module?

    • Adrian Rosebrock March 20, 2018 at 5:45 am #

      Hey Simon — what is the “Camina” module? Can you clarify?

  5. Kwabena W. Agyeman March 19, 2018 at 11:57 pm #

    @Muhammad – Technically we can measure object size using our find_rect() method. This basically does all the steps in the simple calibration demo in one step for finding edges of an object. That said, Adrian has built-out this feature with a lot more detail in his tutorial with OpenCV.

    @David – Our source code is here: It’s not really possible to run OpenCV on chips that don’t run Linux/Windows/OSX. OpenMV was started to make it possible to do computer vision on them.

  6. RedSea March 20, 2018 at 6:15 am #

    Thank you.
    I hope that you write subject of entry ball in the goal.
    And subject for used the camera to know decay teeth. And Directing a laser to decay teeth.

    • Adrian Rosebrock March 20, 2018 at 6:28 am #

      Thank you for the suggestions. I do not know if I will cover the requested topics but I will certainly consider them.

  7. Dennis March 24, 2018 at 9:07 pm #

    I bought one of these two weeks ago to test. I have to admit that the OpenMV is fun to play with but it is pretty slow compared to the Pi. Everything has to run at a lower resolution and often times in grayscale.

    That said, the IDE and setup are really well thought out. The IDE loads up a good number of samples and the code is not terribly different than OpenCV.

    This could be used to control your own robot or could talk to an Arduino controlled robot to give it ‘vision’.

    It’s a great product we plan to buy more.

    • Adrian Rosebrock March 27, 2018 at 6:25 am #

      Thank you for sharing your experience with OpenMV, Dennis! 🙂

    • Kwabena W. Agyeman April 1, 2018 at 3:59 pm #

      Hi Dennis,

      >> I bought one of these two weeks ago to test. I have to admit that the OpenMV is fun to play with but it is pretty slow compared to the Pi. Everything has to run at a lower resolution and often times in grayscale.

      Yeah, the current hardware is 2X slower that the Pi zero and 3X slower than the Pi 3. It’s actually on par with the original raspberry Pi one though if you have one of those lying around.

      The next gen will get us up to faster than the Pi 2. Afterwards, we hope to go even faster. The point of the project isn’t really to be on low end hardware but to make computer vision more embedded-able.

  8. Tony June 30, 2018 at 9:13 am #

    Hi, could I use the openMV set simple for normal .tif images for scanning tilted barcodes. I just have the problem that pyzbar is not capable of detecting them. Thanks.


  1. An interview with Kwabena Agyeman, co-creator of OpenMV and microcontroller expert - PyImageSearch - March 28, 2018

    […] publishing last week’s blog post on reading barcodes with Python and OpenMV, I received a lot of emails from readers asking questions about embedded computer vision and how […]

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