QR Code is kind of matrix barcode, it is recently very popular because of its fast read speed and big storage capacity, we can see it everywhere, Jeky even wanted to tattoo one on his body.
A QR code makes up by black square dots and white square grid, black dots arrange in white background, any kind of imaging device (in most situations, we use our smart phones) can read it, after processed by software, we can easily get information carried in the QR code.
Since half year ago, I wanted to make a QR code scanner using c++ and OpenCV, but I rarely had time, so before the new semester’s beginning, I must try to finish it, at least part of it.
First thing a QR code reader need to do is to find the position of QR code in image. It is convenient because QR code provide three finder patterns in the top-left, top-right, and bottom left corner, so our aim became simply finding these three finder patterns. When finder patterns found, the orientation of QR code is also known.
A QR code is something like above, we can see the 3 finder patterns, each of them can be decomposed into 3 parts: a 3 * 3 black square, a 5 * 5 white square frame, and a 7 * 7 square frame.
People use a lot of ways to finding these funky things, For instance, Viola-Jones framework, Boosting, Blob analysis, cluster analysis and so on, here I’ll try to use binary image contour analysis, the most simple way to do it.
Given this image, the back surface of a book with a QR code on it, we want to find the QR code. First let’s convert this image into gray scale, and change it to binary image. (Here I simply use Otsu-Method to get gray image binarized, about how to make the binary process self-adapted, that’s another story)
Using findContours() to find contours in this image, we can find plenty of contours.
And next step is eliminate all trash contours. Because the specific formation of finder pattern, we can find which of the contours are inside other contours, and the ratio of these inner pattern and outer pattern is in specific range.
Now we’ve found the three finder patterns, and we can do some judge and find the orientation of this QR code. In regular camera orientation, distance between top-right pattern and bottom-left pattern should be longer than their distance between top-left pattern, so by finding the longest distance among the three patterns, we can easily get the orientation of this QR code.
With the three patterns’ position, we can get an affine transform matrix by using OpenCV’s “getAffineTransform()” function, and using “warpAffine()” function get the final QR code image.
Next step is about read and decode QR code, I will go forward doing it when I have time these days.