NAME

Image::DecodeQR::WeChat - Decode QR code(s) from images using the OpenCV/WeChat library via XS

VERSION

Version 0.01

SYNOPSIS

# this ensures that both input params can contain utf8 strings
# but also results (somehow but beyond me)
use utf8;
use Image::DecodeQR::WeChat;

# this will be fixed, right now params are hardoded in XS code
my $payloads = Image::DecodeQR::WeChat::decode_xs(
    # the input image containing one or more QR-codes
    'an-input-image.png',

    # the dir with model parameters required by the library.
    # These come with this package and are curtesy of WeChat
    # which is part of OpenCV contrib packages
    # They are installed with this package and their default location
    # is given by Image::DecodeQR::WeChat::modelsdir()
    # Alternatively, specify your own model files:
    Image::DecodeQR::WeChat::modelsdir(),

    # outbase for all output files, optional
    # if more than one QR-codes were detected then an index will
    # be appended to the filename. And there will be png image files
    # containing the portion of the image which was detected
    # and there will be txt files with QR-code text (payload)
    # and its bounding box. And there will be an overall
    # text file with all payloads. This last one will be
    # printed to STDOUT if no outbase was specified:
    'output.detected',

    # verbosity level. 0:mute, 1:C code messages, 10:C+XS code
    10,

    # display results in a window with QR codes found highlighted
    # make sure you have an interactive shell and GUI
    1,

    # dump image and metadata to files for each QR code detected
    # only if outbase was specified
    1,
);
die "failed" unless $payloads;
print "Payload got: $_\n" for (@$payloads);

# The above decode_xs() expects all parameters to be present
# while decode() below takes a hash of params and fills the
# missing params with defaults. Then it calls decode_xs()
# So, it is still calling XS code but via a Perl sub
# The important bit is that the modelsdir is filled in automatically
# rather than the user looking for it
my $payloads = Image::DecodeQR::WeChat::decode({
    # these are required
    'input' => 'input.jpg',
    'outbase' => 'outs',
    # these are optional and have defaults
    #'modelsdir' => '...', # use it only if you have your own models
    #'verbosity' => 0,
    #'graphicaldisplayresult'' => 0,
    #'dumpqrimagestofile' => 0,
});
die "failed" unless $payloads;
print "Payload got: $_\n" for (@$payloads);

This code calls functions and methods from OpenCV/WeChat library (written in C++) for decoding one or more QR codes found embedded in images. It's just that: a very thin wrapper of a C++ library written in XS. It only interfaces the OpenCV/WeChat library for QR code decoding.

It can detect multiple QR codes embeded in a single image. And has been successfully tested with as small sizes as 55 x 55 px.

The payload(s) (the QR-code's text) are returned back as an ARRAYref.

Optionally, it can output the portion of the input image corresponding to each QR-code, its bounding box and the payload in separate files, useful for debugging and identification when multiple QR codes exist in a single input image.

Following this code as an example, it will be trivial to interface other parts of the OpenCV library:

Ιδού πεδίον δόξης λαμπρόν
   (behold a glorious field of glory)

EXPORT

SUBROUTINES/METHODS

Image::DecodeQR::WeChat::decode_xs(infile, modelsdir, outbase, verbosity, graphicaldisplayresult, dumpqrimagestofile)

It takes in the filename of an input image which may contain one or more QR codes and returns back an ARRAYref of strings containing all the payloads of the codes which have successfully been decoded (some QR codes may fail to be decoded because of resolution or quality etc.)

It returns undef on failure.

It returns an empty ARRAYref (i.e. a ref to an empty array) if no QR codes were found or decoded successfully.

These are the parameters it requires. They must all be present, with optinal parameters allowed to be undef:

Image::DecodeQR::WeChat::decode(\%params)

This is a Perl wrapper to the decode_xs() so that user can specify only a minimal set of parameters and the will be filled in by defaults.

Like decode_xs(), it returns undef on failure.

It returns an empty ARRAYref (i.e. a ref to an empty array) if no QR codes were found or decoded successfully.

The params hashref:

Image::DecodeQR::WeChat::modelsdir()

It returns the path where the models included in this package have been installed. This is useful when you want to use decode_xs() and need to specify the modelsdir. Just pass the output of this to decode_xs() as its modelsdir parameter.

IMPLEMENTATION DETAILS

This code demonstrates how to call OpenCV (modern OpenCV v4) C++ methods using the technique suggested by Botje @ #perl in order to avoid all the function, macro, data structures name clashes between Perl and OpenCV (for example seed(), do_open(), do_close() and most notably struct cv and namespace cv in Perl and OpenCV respectively).

The trick suggested is to put all the OpenCV-calling code in a separate C++ file and provide high-level functions to be called by XS. So that the XS code does not see any OpenCV header files.

Makefile.PL will happily compile any .c and/or .cpp files found in the dir it resides by placing OBJECT => '$(O_FILES)' in %WriteMakefileArgs. And will have no problems with specifying also these:

CC      => 'g++',
LD      => 'g++',
XSOPT   => '-C++',

With one caveat, g++ compiler will mangle the names of the functions when placing them in the object files. And that will cause XSLoader to report missing and undefined symbols.

The cure to this is to wrap any function you want to remain unmangled within

#ifdef __cplusplus
extern "C" {
#endif

and

#ifdef __cplusplus
} //extern "C" {
#endif

This only need happen in the header file: wechat_qr_decode_lib.hpp.

INSTALLING OpenCV

In my case downloading OpenCV using Linux's package manager was not successful.It required to add another repository which wanted to install its own versions of packages I already had.

AUTHOR

Andreas Hadjiprocopis, <bliako at cpan.org>

BUGS

Please report any bugs or feature requests to bug-image-decodeqr-wechat at rt.cpan.org, or through the web interface at https://rt.cpan.org/NoAuth/ReportBug.html?Queue=Image-DecodeQR-WeChat. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.

SUPPORT

You can find documentation for this module with the perldoc command.

perldoc Image::DecodeQR::WeChat

You can also look for information at:

ACKNOWLEDGEMENTS

LICENSE AND COPYRIGHT

This software is Copyright (c) 2022 by Andreas Hadjiprocopis.

This is free software, licensed under:

The Artistic License 2.0 (GPL Compatible)

HUGS

!Almaz!