README.md formatting tweaks
This commit is contained in:
parent
db4046f997
commit
b77da026c9
1 changed files with 121 additions and 120 deletions
241
README.md
241
README.md
|
@ -1,176 +1,177 @@
|
||||||
Quirc
|
Quirc
|
||||||
=====
|
=====
|
||||||
|
|
||||||
QR codes are a type of high-density matrix barcodes, and quirc is a
|
QR codes are a type of high-density matrix barcodes, and quirc is a library for
|
||||||
library for extracting and decoding them from images. It has several
|
extracting and decoding them from images. It has several features which make it
|
||||||
features which make it a good choice for this purpose:
|
a good choice for this purpose:
|
||||||
|
|
||||||
* It is fast enough to be used with realtime video: extracting and
|
* It is fast enough to be used with realtime video: extracting and decoding
|
||||||
decoding from VGA frame takes about 50 ms on a modern x86 core.
|
from VGA frame takes about 50 ms on a modern x86 core.
|
||||||
|
|
||||||
* It has a robust and tolerant recognition algorithm. It can
|
* It has a robust and tolerant recognition algorithm. It can correctly
|
||||||
correctly recognise and decode QR codes which are rotated and/or
|
recognise and decode QR codes which are rotated and/or oblique to the camera.
|
||||||
oblique to the camera. It can also distinguish and decode multiple
|
It can also distinguish and decode multiple codes within the same image.
|
||||||
codes within the same image.
|
|
||||||
|
|
||||||
* It is easy to use, with a simple API described in a single
|
* It is easy to use, with a simple API described in a single commented header
|
||||||
commented header file (see below for an overview).
|
file (see below for an overview).
|
||||||
|
|
||||||
* It is small and easily embeddable, with no dependencies other than
|
* It is small and easily embeddable, with no dependencies other than standard C
|
||||||
standard C functions.
|
functions.
|
||||||
|
|
||||||
* It has a very small memory footprint: one byte per image pixel,
|
* It has a very small memory footprint: one byte per image pixel, plus a few kB
|
||||||
plus a few kB per decoder object.
|
per decoder object.
|
||||||
|
|
||||||
* It uses no global mutable state, and is safe to use in a
|
* It uses no global mutable state, and is safe to use in a multithreaded
|
||||||
multithreaded application.
|
application.
|
||||||
|
|
||||||
* BSD-licensed, with almost no restrictions regarding use and/or
|
* BSD-licensed, with almost no restrictions regarding use and/or modification.
|
||||||
modification.
|
|
||||||
|
|
||||||
The distribution comes with, in addition to the library, several test
|
The distribution comes with, in addition to the library, several test programs.
|
||||||
programs. While the core library is very portable, these programs have
|
While the core library is very portable, these programs have some additional
|
||||||
some additional dependencies. All of them require libjpeg, and two
|
dependencies. All of them require libjpeg, and two (`quirc-demo` and `inspect`)
|
||||||
(``quirc-demo`` and ``inspect``) require SDL. The camera demos use
|
require SDL. The camera demos use Linux-specific APIs:
|
||||||
Linux-specific APIs:
|
|
||||||
|
|
||||||
``quirc-demo``
|
### quirc-demo
|
||||||
|
|
||||||
~ This is an real-time demo which requires a camera and a graphical
|
This is an real-time demo which requires a camera and a graphical display. The
|
||||||
display. The video stream is displayed on screen as it's received,
|
video stream is displayed on screen as it's received, and any QR codes
|
||||||
and any QR codes recognised are highlighted in the image, with the
|
recognised are highlighted in the image, with the decoded information both
|
||||||
decoded information both displayed on the image and printed on
|
displayed on the image and printed on stdout.
|
||||||
stdout.
|
|
||||||
|
|
||||||
``quirc-scanner``
|
### quirc-scanner
|
||||||
|
|
||||||
~ This program turns your camera into a barcode scanner. It's almost
|
This program turns your camera into a barcode scanner. It's almost the same as
|
||||||
the same as the ``demo`` application, but it doesn't display the
|
the `demo` application, but it doesn't display the video stream, and thus
|
||||||
video stream, and thus doesn't require a graphical display.
|
doesn't require a graphical display.
|
||||||
|
|
||||||
``qrtest``
|
### qrtest
|
||||||
|
|
||||||
~ This test is used to evaluate the performance of library. Given a
|
This test is used to evaluate the performance of library. Given a directory
|
||||||
directory tree containing a bunch of JPEG images, it will attempt
|
tree containing a bunch of JPEG images, it will attempt to locate and decode QR
|
||||||
to locate and decode QR codes in each image. Speed and success
|
codes in each image. Speed and success statistics are collected and printed on
|
||||||
statistics are collected and printed on stdout.
|
stdout.
|
||||||
|
|
||||||
``inspect``
|
### inspect
|
||||||
|
|
||||||
~ This test is used for debugging. Given a single JPEG image, it
|
This test is used for debugging. Given a single JPEG image, it will display a
|
||||||
will display a diagram showing the internal state of the decoder
|
diagram showing the internal state of the decoder as well as printing
|
||||||
as well as printing additional information on stdout.
|
additional information on stdout.
|
||||||
|
|
||||||
Installation
|
Installation
|
||||||
------------
|
------------
|
||||||
|
To build the library and associated demos/tests, type `make`. Type
|
||||||
|
`make install` to install the library, header file and camera demos.
|
||||||
|
|
||||||
To build the library and associated demos/tests, type ``make``. Type
|
You can specify one or several of the following targets if you don't want, or
|
||||||
``make install`` to install the library, header file and camera demos.
|
are unable to build everything:
|
||||||
|
|
||||||
You can specify one or several of the following targets if you don't
|
* libquirc.a
|
||||||
want, or are unable to build everything:
|
* libquirc.so
|
||||||
|
* qrtest
|
||||||
* libquirc.a
|
* inspect
|
||||||
* libquirc.so
|
* quirc-scanner
|
||||||
* qrtest
|
* quirc-demo
|
||||||
* inspect
|
|
||||||
* quirc-scanner
|
|
||||||
* quirc-demo
|
|
||||||
|
|
||||||
Library use
|
Library use
|
||||||
-----------
|
-----------
|
||||||
|
All of the library's functionality is exposed through a single header file,
|
||||||
|
which you should include:
|
||||||
|
|
||||||
All of the library's functionality is exposed through a single header
|
```C
|
||||||
file, which you should include:
|
#include <quirc.h>
|
||||||
|
```
|
||||||
|
|
||||||
#include <quirc.h>
|
To decode images, you'll need to instantiate a `struct quirc` object, which is
|
||||||
|
done with the `quirc_new` function. Later, when you no longer need to decode
|
||||||
|
anything, you should release the allocated memory with `quirc_destroy`:
|
||||||
|
|
||||||
To decode images, you'll need to instantiate a ``struct quirc``
|
```C
|
||||||
object, which is done with the ``quirc_new`` function. Later, when you
|
struct quirc *qr;
|
||||||
no longer need to decode anything, you should release the allocated
|
|
||||||
memory with ``quirc_destroy``:
|
|
||||||
|
|
||||||
struct quirc *qr;
|
qr = quirc_new();
|
||||||
|
if (!qr) {
|
||||||
|
perror("Failed to allocate memory");
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
qr = quirc_new();
|
/* ... */
|
||||||
if (!qr) {
|
|
||||||
perror("Failed to allocate memory");
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ... */
|
quirc_destroy(qr);
|
||||||
|
```
|
||||||
|
|
||||||
quirc_destroy(qr);
|
Having obtained a decoder object, you need to set the image size that you'll be
|
||||||
|
working with, which is done using `quirc_resize`:
|
||||||
|
|
||||||
Having obtained a decoder object, you need to set the image size that
|
```C
|
||||||
you'll be working with, which is done using ``quirc_resize``:
|
if (quirc_resize(qr, 640, 480) < 0) {
|
||||||
|
perror("Failed to allocate video memory");
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
if (quirc_resize(qr, 640, 480) < 0) {
|
`quirc_resize` and `quirc_new` are the only library functions which allocate
|
||||||
perror("Failed to allocate video memory");
|
memory. If you plan to process a series of frames (or a video stream), you
|
||||||
abort();
|
probably want to allocate and size a single decoder and hold onto it to process
|
||||||
}
|
each frame.
|
||||||
|
|
||||||
``quirc_resize`` and ``quirc_new`` are the only library functions
|
|
||||||
which allocate memory. If you plan to process a series of frames (or a
|
|
||||||
video stream), you probably want to allocate and size a single decoder
|
|
||||||
and hold onto it to process each frame.
|
|
||||||
|
|
||||||
Processing frames is done in two stages. The first stage is an
|
Processing frames is done in two stages. The first stage is an
|
||||||
image-recognition stage called identification, which takes a grayscale
|
image-recognition stage called identification, which takes a grayscale image
|
||||||
image and searches for QR codes. Using ``quirc_begin`` and
|
and searches for QR codes. Using `quirc_begin` and `quirc_end`, you can feed a
|
||||||
``quirc_end``, you can feed a grayscale image directly into the buffer
|
grayscale image directly into the buffer that `quirc` uses for image
|
||||||
that ``quirc`` uses for image processing:
|
processing:
|
||||||
|
|
||||||
uint8_t *image;
|
```C
|
||||||
int w, h;
|
uint8_t *image;
|
||||||
|
int w, h;
|
||||||
|
|
||||||
image = quirc_begin(qr, &w, &h);
|
image = quirc_begin(qr, &w, &h);
|
||||||
|
|
||||||
/* Fill out the image buffer here.
|
/* Fill out the image buffer here.
|
||||||
* image is a pointer to a w*h bytes.
|
* image is a pointer to a w*h bytes.
|
||||||
* One byte per pixel, w pixels per line, h lines in the buffer.
|
* One byte per pixel, w pixels per line, h lines in the buffer.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
quirc_end(qr);
|
quirc_end(qr);
|
||||||
|
```
|
||||||
|
|
||||||
Note that ``quirc_begin`` simply returns a pointer to a previously
|
Note that `quirc_begin` simply returns a pointer to a previously allocated
|
||||||
allocated buffer. The buffer will contain uninitialized data. After
|
buffer. The buffer will contain uninitialized data. After the call to
|
||||||
the call to ``quirc_end``, the decoder holds a list of detected QR
|
`quirc_end`, the decoder holds a list of detected QR codes which can be queried
|
||||||
codes which can be queried via ``quirc_count`` and ``quirc_extract``.
|
via `quirc_count` and `quirc_extract`.
|
||||||
|
|
||||||
At this point, the second stage of processing occurs -- decoding. This
|
At this point, the second stage of processing occurs -- decoding. This is done
|
||||||
is done via the call to ``quirc_decode``, which is not associated with
|
via the call to `quirc_decode`, which is not associated with a decoder object.
|
||||||
a decoder object.
|
|
||||||
|
|
||||||
int num_codes;
|
```C
|
||||||
int i;
|
int num_codes;
|
||||||
|
int i;
|
||||||
|
|
||||||
/* We've previously fed an image to the decoder via
|
/* We've previously fed an image to the decoder via
|
||||||
* quirc_begin/quirc_end.
|
* quirc_begin/quirc_end.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
num_codes = quirc_count(qr);
|
num_codes = quirc_count(qr);
|
||||||
for (i = 0; i < num_codes; i++) {
|
for (i = 0; i < num_codes; i++) {
|
||||||
struct quirc_code code;
|
struct quirc_code code;
|
||||||
struct quirc_data data;
|
struct quirc_data data;
|
||||||
quirc_decode_error_t err;
|
quirc_decode_error_t err;
|
||||||
|
|
||||||
quirc_extract(qr, i, &code);
|
quirc_extract(qr, i, &code);
|
||||||
|
|
||||||
/* Decoding stage */
|
/* Decoding stage */
|
||||||
err = quirc_decode(&code, &data);
|
err = quirc_decode(&code, &data);
|
||||||
if (err)
|
if (err)
|
||||||
printf("DECODE FAILED: %s\n", quirc_strerror(err));
|
printf("DECODE FAILED: %s\n", quirc_strerror(err));
|
||||||
else
|
else
|
||||||
printf("Data: %s\n", data.payload);
|
printf("Data: %s\n", data.payload);
|
||||||
}
|
}
|
||||||
|
```
|
||||||
|
|
||||||
``quirc_code`` and ``quirc_data`` are flat structures which don't need
|
`quirc_code` and `quirc_data` are flat structures which don't need to be
|
||||||
to be initialized or freed after use.
|
initialized or freed after use.
|
||||||
|
|
||||||
Copyright
|
Copyright
|
||||||
---------
|
---------
|
||||||
|
|
||||||
Copyright (C) 2010-2012 Daniel Beer <<dlbeer@gmail.com>>
|
Copyright (C) 2010-2012 Daniel Beer <<dlbeer@gmail.com>>
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for
|
Permission to use, copy, modify, and/or distribute this software for
|
||||||
|
|
Loading…
Reference in a new issue