Scanning QR Codes

These days, you can see QR codes almost everywhere. You see them at stores, on products, on screens. So one day, I was curious how the gears are put together to read QR codes. I ended up reading the ISO/IEC 18004 standard. It’s a very robust and detailed documentation on how QR codes are supposed to work. I’ve put up a link in the downloads section below if you’re interested.

This is a multipart series – we’ll be creating a QR code reader from scratch in OpenCV. Sure, there are a lot of libraries that do this – but making your own is so awesome. Don’t you agree?

Anatomy of a QR code

A QR code is made up of four main parts:

  1. Finder patterns: These are the big black/white/black squares on the three corners on the QR code. These help identify the presence of a QR code in an image and it’s orientation. These are made such that they can be detected really fast.
  2. Alignment patterns: These are smaller than finder patterns and help straighten out a QR codes drawn on a curved surface. The larger a code, the more alignment patterns it’ll have.
  3. Timing pattern: These are alternating black/white modules on the QR code. The idea is to help figure out the data grid accurately.
  4. The actual data: The blacks/whites form bits. Groups of 8 such modules makes one byte. You could combine 16 modules to get unicode data.

A ‘module’ is one square on the QR code. So an alignment pattern is 5 modules wide – one module is black, one is white, next is black, then white and finally black.

How to detect a QR code

Detecting a QR code revolves around identifying finder patterns. The key idea is that there’s a ratio in the number of black/white/black/white/black. And this ratio remains the same no matter what angle you look at it.

In the above picture, you’ll see that each of the red lines has roughly the same ratio. It does not depend on the angle. Once you’ve ‘identified’ such a ratio, you need to confirm what you see is a finder pattern or not. You do this by checking along the horizontal and vertical axes. If it’s the same ratio, you know you’ve found a finder pattern.

Once you have 3 finder patterns, everything is relatively simple. You extract the QR code and fix the perspective. Then you can extract each bit and figure out what the data means.

Error correction

QR codes can be really artistic. They can ‘sacrifice’ a few bits of data to make it look a lot better. They store redundant copies of bits to compensate for the sacrificed bits. Of course, this reduces the total capacity – but it makes the code look a nice and still be readable by all scanners.

QR uses the Reed-Solomon error correction code to do this. It supports multiple ‘levels’ of error correction (7%, 15%, 25%, 30%). If 30% of the bits are damaged (soiled, washed out, faded, replaced by art) you can still ‘read’ the QR.

What we’ll make

We’ll make a basic QR code reader. We won’t cover identifying curved QR codes (with the alignment markers). Nor would we really go into a lot of detail with the various formats/versions of QR. Once you have a code where you’ve recognized the orientation, the timing, you can make it work with all versions/formats really easily. So I’ll leave that part to you. We won’t cover error correction either. That wasn’t quite the point of this series.

Or as authors often write, “this is beyond the scope of this text book”. So get the latest version of OpenCV and make sure you’ve got everything setup just right!

Issues? Suggestions? Visit the Github issue tracker for AI Shack

Back to top


    No related downloads.


  • Detecting a QR code revolves around detecting finder patterns.
  • Alignment patterns help detect curved QR codes.


  1. afriend
    Posted February 4, 2012 at 4:18 am | Permalink

    Hey Utkarsh, thanks for the nice intro. Just so you know, the pdf file you posted has the licensee’s name burnt into it. I don’t know how serious is the license of the ISO document, but they may get in trouble for letting you see it, and post it.

    Please feel free to delete this comment. I am just posting it as a heads up.

    Looking forward to reading the rest of the series about QR-codes.

  2. yuzhao
    Posted February 10, 2012 at 8:30 am | Permalink

    haha, you are back. Very interesting topic~

  3. dino74
    Posted March 14, 2012 at 1:08 pm | Permalink

    Nice code! when can we expect the additional checks?

    • Posted March 16, 2012 at 10:53 pm | Permalink

      I have the code – but I haven’t had the chance to write the tutorial for it.

One Trackback

  • By QR Code | Uways Official on September 28, 2012 at 11:07 am

    [...] AI SHACK Share this:TwitterFacebookLike this:SukaBe the first to like this. By UwaysIsYoungWoon • [...]

Post a Comment

Your email is never published nor shared. Required fields are marked *


You may use these HTML tags and attributes <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>