Thursday, 17 December 2015

Scanning Barcodes / QR Codes with OpenCV using ZBar

This Opencv Tutorial is about Scanning or Reading Barcode with Opencv by using ZBar Libraries

A bar code can best be described as an "optical Morse code." Or in other words it could be said as the machine readable representation of the human-readable characters. The mapping between messages and barcodes is called a symbology.

Links where we could create barcodes:
Bar-codes can be subdivided into two types, 1-Dimensional and 2-Dimensional .

1-Dimensional (1D)bar codes
It comprises of parallel lines(bars) of varying widths(thickness) and spaces used to encode information about the object it labels. The various types of 1-Dimensional bar codes are:
  • UPC Code(Universal Product Code)
  • Variations:UPC-A and UPC-E 
    1 UPC-A:It uses 12 digits codes and no other digits other than the numbers
    2. UPC-E:It uses only 6 digit codes and other digits other than the numbers
  •  EAN Code(European Article Number now renamed as International Article Number)
  • Variations: EAN-13, EAN-8, JAN-13, ISBN, ISSN
    EAN-13 barcode: It is similar to UPC-A barcode with the only visual difference lying in the position of the last digit.In EAN-13 barcode system the checksum digits lies below the barcode rather than to the right to it.EAN-13 barcode system consists of 2 groups of 6 digits each. 
    EAN-8 barcode: It is simliar to that of EAN-13 barcode system except the fact that it was introduced for the small packages where EAN-13 barcode system is not that useful.
  • Code 39:
  • Also known as code 3 of 9, initial version could encode only 39 characters,now could encode upto 43 characters.A to Z,0 to 9, and some special symbols like "$" , "/" , "," , "%" and space.Each character is encoded with five bars and four spaces.
  • Code 128:
  • It can encode all 128 ASCII characters.
  • ITF-14:
  • Also known as "Interleaved 2 of 5" is a high density bar-code symbology used for encoding only numeric digits from  0 to 9.It always codes digit pairs for e.g 01 is regarded as one pair and coded by 1 set of bars similarly for 02 and so on.Thus it should always consist of even number of digits.Whenever the data to be encoded is of odd numbers a leading 0 is added to data.
  • Codabar
  • Variations: Codeabar, Ames Code, NW-7, Monarch, Code 2 of 7, Rationalized Codabar, ANSI/AIM BC3-1995, USD-4
    It is a self checking bar-code symbology which can encode 16 different characters (consists of numbers from 0 to 9 , "$" ,"+" , "-" , ":" , ".","/" and an additional 4 start or stop characters (A,B,C,D).
  • GS1 Databar
  • Variations: GS1 DataBar Omnidirectional, Truncated, Stacked, Stacked Omnidirectional, Expanded, Expanded Stacked.
  • MSI Plessey: Also known as modified Plessey is not slf checking symbology and can encode only digits from 0 to 9.
2-Dimensional (2D) Barcode:
The  2D bar codes are similar to 1-D except  the fact that it can store more data per unit area(since it can not only store images horizontally as 1-D barcodes do but also vertically)
  • QR code:
  • DATAMATRIX Code:
  • PDF 417:
  • AZTEC:
Now,

How to scan/read these Barcodes using OPENCV?

Scanning the barcdoes with Zbar libraries are quite simple. So, What is ZBar and how to use ZBAR with OPENCV? ZBar is an open source library for reading bar codes from various sources, such as video streams, image files and raw intensity sensors. It supports many popular symbologies (types of bar codes) including EAN-13/UPC-A, UPC-E, EAN-8, Code 128, Code 39, Interleaved 2 of 5 and QR Code.So to read these barcodes we use ZBar along with OPENCV. The Steps to configure ZBar with OPENCV is as mentioned below:

1. Install Z-bar(Windows installer) from the link below:
http://sourceforge.net/projects/zbar/files/zbar/0.10/zbar-0.10-setup.exe/download
 zbar-installation-link





2. Now Open your Visual Studio : Go to File >> New>>Project.
 i. In Installed Templates Select Visual C++  
ii. Win32 Console Application
iii. Name of Project as BarcodeScanner.


Click on Next
In Additional Options : Tick Empty Project 
Finish

3. Right Click on File BarcodeScanner in Solution Explorer.

Click on Properties: The Property Pages Dialog Box would pop-up.

In "Configuration Properties" goto "VC++ Directories" then to "Include Directories"

Double click the empty box
4. Browse and Add the Path of OpenCV Include folder and ZBar Include folder

Here it is==> D:\opencv2410\build\include


Here it is ==> D:\opencv2410\build\include
Click OK and then  Apply.

5. Goto Library Directories.Add the path of the ZBar lib folder.

Here it is==> C:\Program Files\ZBar\lib

6. Goto Linker ==> Input
Then to Additional Dependencies
Add:
libzbar-0.lib
opencv_calib3d2410d.lib
opencv_contrib2410d.lib
opencv_core2410d.lib
opencv_features2d2410d.lib
opencv_flann2410d.lib
opencv_gpu2410d.lib
opencv_highgui2410d.lib
opencv_imgproc2410d.lib
opencv_legacy2410d.lib
opencv_ml2410d.lib
opencv_nonfree2410d.lib
opencv_objdetect2410d.lib
opencv_photo2410d.lib
opencv_stitching2410d.lib
opencv_superres2410d.lib
opencv_ts2410d.lib
opencv_video2410d.lib
opencv_videostab2410d.lib

Click OK

Click OK and APPLY on Property Page Dialog Box
(Note: If it doesn't work also copy all the library files under the debug folder of the current project)

7. Right Click Source Files in BarcodeScanner, goto Add , goto New Item.

Goto Visual C++ , Select C++ File(.cpp).Name it as "main" (without double inverted commas)


8. Copy the Opencv Code for Barcode Scanning as shown below:
// OpenCV Barcode Scanner  Tutorial 
// Opencv   Barcode Reader Tutorial
#include <opencv2/core/core.hpp> 
#include <opencv2/highgui/highgui.hpp> 
#include "opencv2/opencv.hpp"  
#include <iostream>
 #include "zbar.h"  
using namespace cv;
using namespace std;
 using namespace zbar;  

 int main(void){  
      ImageScanner scanner;  
      scanner.set_config(ZBAR_NONE, ZBAR_CFG_ENABLE, 1);  
       // obtain image data  
      char file[256];  
      cin>>file;  
      Mat img = imread(file,0);  
      Mat imgout;  
      cvtColor(img,imgout,CV_GRAY2RGB);  
      int width = img.cols;  
      int height = img.rows;  
   uchar *raw = (uchar *)img.data;  
   // wrap image data  
   Image image(width, height, "Y800", raw, width * height);  
   // scan the image for barcodes  
   int n = scanner.scan(image);  
   // extract results  
   for(Image::SymbolIterator symbol = image.symbol_begin();  
     symbol != image.symbol_end();  
     ++symbol) {  
                vector<Point> vp;  
     // do something useful with results  
     cout << "decoded " << symbol->get_type_name()  
        << " symbol \"" << symbol->get_data() << '"' <<" "<< endl;  
           int n = symbol->get_location_size();  
           for(int i=0;i<n;i++){  
                vp.push_back(Point(symbol->get_location_x(i),symbol->get_location_y(i))); 
           }  
           RotatedRect r = minAreaRect(vp);  
           Point2f pts[4];  
           r.points(pts);  
           for(int i=0;i<4;i++){  
                line(imgout,pts[i],pts[(i+1)%4],Scalar(255,0,0),3);  
           }  
           cout<<"Angle: "<<r.angle<<endl;  
   }  
      imshow("imgout.jpg",imgout);  
   // clean up  
   image.set_data(NULL, 0);  
       waitKey();  
 }  

2 comments:

  1. I am using visual C++ 14 and OpenCV 4.0 so How to configure my project? Thank you. Because I did the steps above replacing "2410" with "400" for the libraries files but I don't have many of these lib files in my openCV 4.0 lib folder. like "opencv_contrib400d.lib" and "opencv_gpu400d.lib")...

    Also for including paths I did as you mentioned above but still get:

    "CV_GRAY2RGB is undeclared identifier". thank you.

    ReplyDelete