Creating a Livekeys based Plugin

In order to use Open CV types within QtQuick, Livekeys provides a set of wrapper libraries. We will be using lcvcore for this scenario since we will need the QMat type, so we will link to lcvcore and Open CV from our plugin. In qmake, linking to the 2 libraries requires a lot of boiler plate code:


# Link to Open CV

win32{ OPENCV_DIR_INCLUDE = $$(OPENCV_DIR)/../../include OPENCV_DIR_LIBRARIES = $$(OPENCV_DIR)/lib

INCLUDEPATH += $${OPENCV_DIR_INCLUDE}
LIBS += -L$${OPENCV_DIR_LIBRARIES} -lopencv_world310

} unix{ CONFIG += link_pkgconfig PKGCONFIG += opencv }

Link to lcvcore

PATH_TO_LIVEKEYS = '<path_to_livekeys>'

INCLUDEPATH += $$PATH_TO_LIVEKEYS/dev/include/plugins/lcvcore LIBS += -L$$PATH_TO_LIVEKEYS/dev/plugins/lcvcore -llcvcore

so to simplify this, Livekeys already provides a set of qmake files that simplify these types of operations. The files are located in the project folder of our Livekeys installation directory. We will need the functions.pri file, together with the 3rdparty/opencv.pri file included in our tutorial.pro:

LIVEKEYS_BIN_PATH = <path_to_livekeys>
LIVEKEYS_DEV_PATH = $$LIVEKEYS_BIN_PATH/dev

include($$LIVEKEYS_DEV_PATH/project/functions.pri)
include($$LIVEKEYS_DEV_PATH/project/3rdparty/opencv.pri)

functions.pri expects us to define LIVEKEYS_BIN_PATH and LIVEKEYS_DEV_PATH, which are used as locations to

find the plugins we will be linking to. Note that on windows, in order to link to Open CV, you will also need to have OPENCV_DIR environment variable set up. After we have the functionality available, we can link to the lcvcore library:

linkPlugin(lcvcore, lcvcore)

The linkPlugin function takes 2 parameters, a location where the plugin resides, and a plugin name to be used.

Open CV is linked to automatically by just having the opencv.pri file included. After the appended lines , the top part of tutorial.pro file should look something similar to:

TEMPLATE = lib
TARGET = tutorial
QT += qml quick
CONFIG += qt plugin c++11

TARGET = $$qtLibraryTarget($$TARGET)
uri = tutorial

LIVEKEYS_BIN_PATH = <path_to_livekeys>
LIVEKEYS_DEV_PATH = $$LIVEKEYS_BIN_PATH/dev

include($$LIVEKEYS_DEV_PATH/project/functions.pri)
include($$LIVEKEYS_DEV_PATH/project/3rdparty/opencv.pri)

linkPlugin(lcvcore,  lcvcore)

# ...

After solving our dependencies, we can now go back to our CountNonZeroPixels item. We're going to need

an input matrix, and an output value for the number of pixels:

Q_PROPERTY(QMat* input         READ input         WRITE setInput         NOTIFY inputChanged)
Q_PROPERTY(int   nonZeroPixels READ nonZeroPixels NOTIFY nonZeroPixelsChanged)

The QMat element requires us to include the qmat.h file at the beginning:

#include "qmat.h"

Last, we need to add the 2 fields, setters, getters and notifiers, and we have the final version looking like this:

#include <QQuickItem>
#include "qmat.h"

class CountNonZeroPixels : public QQuickItem
{
    Q_OBJECT
    Q_DISABLE_COPY(CountNonZeroPixels)
    Q_PROPERTY(QMat* input         READ input         WRITE setInput         NOTIFY inputChanged)
    Q_PROPERTY(int   nonZeroPixels READ nonZeroPixels NOTIFY nonZeroPixelsChanged)

public:
    CountNonZeroPixels(QQuickItem *parent = 0);
    ~CountNonZeroPixels();

    QMat* input();
    void setInput(QMat* input);

    int nonZeroPixels() const;

signals:
    void inputChanged();
    void nonZeroPixelsChanged();

private:
    QMat* m_input;
    int   m_nonZeroPixels;
};

inline int CountNonZeroPixels::nonZeroPixels() const{
    return m_nonZeroPixels;
}

inline QMat*CountNonZeroPixels::input(){
    return m_input;
}

inline void CountNonZeroPixels::setInput(QMat* input){
    m_input = input;
    emit inputChanged();
    m_nonZeroPixels = cv::countNonZero(*m_input->cvMat());
    emit nonZeroPixelsChanged();
}

In the setInput method, we calculate the non zero pixels using the cv::CountNonZero method from Open CV. To

retrieve the actual cv::Mat contents of a QMat, we use the cvMat() getter, which retrieves a pointer to a cv::Mat object.

We can now build the library and test it. Just like the steps in the previous part, go to the plugins directory in Livekeys's installation path, and override the qmldir and the so or dll files with the newly build ones. Run livekeys, and you can use the following code to test your plugin:

import QtQuick 2.3
import lcvcore 1.0
import lcvimgproc 1.0
import tutorial 1.0

Grid{

columns : 2

property string imagePath : &#39;path/to/image.jpg&#39;

ImRead{
    id : imgSource
    file : parent.imagePath
}

Canny{ // get the edges
    id : canny
    input: imgSource.output
    threshold1 : 70
    threshold2 : 210
}

CountNonZeroPixels{ // count the number of edge pixels
    id : count
    input : canny.output
}

Text{
    color : &quot;#fff&quot;
    text : count.nonZeroPixels
}

}

Configure the imagePath property to open an image on your hard drive. If you see a text just below your image with a large number, then you have succesfully created a Livekeys plugin that counts the number of non zero pixels in an image.