Debugging OpenCV images into a Qt Application

Selection_001Getting right to the point: Qt has his own event loop control. So, if you want to use the OpenCV functions to show images you will discover that they do not change. The solution is to do the debugging inside the Qt loop. How?, creating a dialog and drawing the images inside. Lets see how to do it

CVDebugSystem

This class will take control of all debug windows (yes, we want to have more than one debugging window). When we want to debug the image we are processing, we only need to call to one method of this class passing the window name (like in OpenCV imshow function) and the image we want to show.

Probably, we want to debug images from different parts of our code, and create a debug object each time we want to debug could be a problem (after debug, maybe we forget to delete this objects and the code keeps “dirty”). To solve this, we will declare CVDebugSystem as a Singleton. Now, we do not need to create CVDebugSystem objects, the class take care of all the windows and debug a image is as simple as call the method:

CVDebugSystem::getInstance().showimg("Title of debug window", image_to_debug);

The different windows are stored into a QHash list, using the window title as key.

cvdebugsystem.h

#ifndef CVDEBUGSYSTEM_H
#define CVDEBUGSYSTEM_H

#include <QHash>
#include "cvdebugwindow.h"

class CVDebugSystem
{
public:
    static CVDebugSystem &getInstance()
    {
        if(pInstance_ == NULL)
        {
            pInstance_ = new CVDebugSystem();
            atexit(&DestroySingleton);    // At exit, destroy the singleton
        }
        return *pInstance_;
    }
    ~CVDebugSystem();

private:
    // Singleton
    static CVDebugSystem* pInstance_;

    // Delete the singleton instance
    static void DestroySingleton(){
        if(pInstance_ != NULL) delete pInstance_;
    }

    // Private to ensure single instance
    CVDebugSystem();
    QHash<QString, CVDebugWindow* > mWindows;

public:
    void showimg(QString window, cv::Mat *img);
    void showimg(QString window, cv::Mat img);
};

#endif // CVDEBUGSYSTEM_H

cvdebugsystem.cpp

#include "cvdebugsystem.h"
#include <QImage>

CVDebugSystem* CVDebugSystem::pInstance_ = NULL;

CVDebugSystem::CVDebugSystem()
{
    mWindows.clear();
}

CVDebugSystem::~CVDebugSystem()
{
    QHash<QString, CVDebugWindow* >::const_iterator i = mWindows.constBegin();
     while (i != mWindows.constEnd()) {
         delete i.value();
         ++i;
     }
}

void CVDebugSystem::showimg(QString window, cv::Mat *img)
{
    if (!mWindows.contains(window))
    {
        CVDebugWindow *win = new CVDebugWindow();
        mWindows.insert(window, win);
    }
    mWindows[window]->setImage(img);
    mWindows[window]->setWindowTitle(window);
    mWindows[window]->show();
}

void CVDebugSystem::showimg(QString window, cv::Mat img)
{
    this->showimg(window, &img);
}

CVDebugWindow

This is the class that inherits from QDialog. It only has a QLabel where we draw the image. In the code attached I have included some more widgets to help me, like a “Fit the image to the window” or scale the OpenCV image to make it more clear. Usually I use the UI files, if you prefer to code the widgets it is also possible

cvdebugwindow.h

#ifndef CVDEBUGWINDOW_H
#define CVDEBUGWINDOW_H

#include <QDialog>
#include <opencv2/core/core.hpp>

namespace Ui {
class CVDebugWindow;
}

class CVDebugWindow : public QDialog
{
Q_OBJECT

public:
explicit CVDebugWindow(QWidget *parent = 0);
void setImage(cv::Mat *image);
~CVDebugWindow();

private Q_SLOTS:
void on_fitButton_toggled(bool checked);

private:
Ui::CVDebugWindow *ui;
};

#endif // CVDEBUGWINDOW_H

cvdebugwindow.cpp

#include "cvdebugwindow.h"
#include "ui_cvdebugwindow.h"

CVDebugWindow::CVDebugWindow(QWidget *parent) :
QDialog(parent),
ui(new Ui::CVDebugWindow)
{
ui->setupUi(this);
ui->label->setAlignment(Qt::AlignCenter | Qt::AlignHCenter);
}

CVDebugWindow::~CVDebugWindow()
{
delete ui;
}

void CVDebugWindow::setImage(cv::Mat *image)
{
QImage::Format format;
if (image->channels() == 1) format = QImage::Format_Mono;
else                        format = QImage::Format_RGB888;

QImage  img = QImage((const unsigned char*)(image->data),
image->cols,
image->rows,
image->step,
format).rgbSwapped();

QImage aux;
if (ui->fitButton->isChecked())
{
aux = img.scaled(ui->label->size());
}
else
{
if (ui->scaleFactor->value() != 1)
{
aux = img.scaled(img.size()*ui->scaleFactor->value());
}
else
aux = img;
}

ui->label->setPixmap(QPixmap::fromImage(aux));
}

void CVDebugWindow::on_fitButton_toggled(bool checked)
{
if (checked) ui->scaleFactor->setEnabled(false);
else ui->scaleFactor->setEnabled(true);
}

In GitHub you can find the repository with the code. Improvements are welcome.

Nao Robot: Visual debugging of the vision variables

One of the more interesting things of the Nao Robot SDK is, probably,  the Vision Module and all the work it can do for you. For example, Nao can detect faces and provide you the coordinates of the different faces with a lot of face features. However, I have found  few information about how to use the variables provided by Nao, so I have needed to use the old method of try/error to understand the variables.

Accessing the variables

Thanks to the ALMemoryProxy accessing to the FaceDetected variable is very easy:

mMemoryProxy = new AL::ALMemoryProxy("NaoRobotsIP", 9559);
AL::ALValue face = mMemoryProxy->getData("FaceDetected");

Understanding the variables

(Disclaimer) I have not found official documentation about what the information inside FaceDetected means and this explanation is based in my experiments and maybe I have get some mistakes.

All parameters have the centre of the image as origin and they have not units. We will pay attention only to the ShapeInfo variable:

  • alpha: Vertical offset in relation to the image height with origin in the centre of the image
  • beta: Horizontal offset in relation to the image width with origin in the centre of the image
  • sizeX: The face size in relation to the image height. It should be the width (as we are talking about the X axis), but in this case the rectangle around the face is wider than tall
  • sizeY: The face size in relation with the width
Reference system for the Vision Module variables

Reference system for the Vision Module variables

Results

Once we have transformed the variables provided by Nao, we can draw a simple rectangle around the faces detected using OpenCV.

// Face Detected [1]/ First face [0]/ Shape Info [0]/ Alpha [1]
float alpha = face[1][0][0][1];
float beta = face[1][0][0][2];
float sx = face[1][0][0][3];
float sy = face[1][0][0][4];

// sizeX / sizeY are the face size in relation to the image
float sizeX = mImageHeight * sx;
float sizeY = mImageWidth * sy;

// Centre of face into the image
float x = mImageWidth / 2 - mImageWidth * alpha;
float y = mImageHeight / 2 - mImageHeight * beta;

cv::Point p1(x - (sizeX / 2), y - (sizeY / 2));
cv::Point p2(x + (sizeX / 2), y + (sizeY / 2));

cv::rectangle(mImage, p1, p2, cv::Scalar(255,255,255));

Nao camera debugging 1

Conclusions

The docs explain that the face detection algorithm is provided by OKI. It can save you a lot of work (computational work) if you want to avoid to transfer images over the network and use the OpenCV classic face detection algorithm to know how many faces are or where are they.

However, the values related with others features, like eyes, are no so useful:

Eye Centre (X) Eye Centre (Y) Eye Top Limit (X) Eye Top Limit (Y) Eye Bottom Limit (X) Eye Bottom Limit (Y)
0.112876 -0.121094 0.126156 -0.128013 0.126156 -0.114174

As can be appreciated, the values for the TopLimit and TopBottom coordinates are almost the same. The debugging result is a point over the eye and not a rectangle as it could be expected.

After several test with different faces I am not very satisfied with the results obtained. The Nao’s algorithm provide a good approximation of the faces coordinates but the faces features are inaccurate. This implies you will need OpenCV (or any other library) to search for features.

Eye tracking and Nao robot

Some days ago, my colleague Min-Gyu asked me if know of any eye-tracking system. For his project, he needs a way to know where the people look, making effective the experiments (I am sorry, but this is all I can say). I had not any in my pockets, so, I toke a look through the Internet to know how the state of the art was. I have discovered that some companies are applying eye-tracking to advertisements: they are want to know where the people look to know if the money they are spending in publicity has any sense.

In other part of the world, there are people that work on eye-tracking techniques to help people with disabilities (helping them to use a computer, just looking at it) and other just for fun. Searching between these people, I found the work of Tristan Hume, that based in the scientific work of this paper, is implementing an algorithm to make a robust a feasible eye-tracking with a webcam.

I tried the code in worked smooth, as Tristan promised. As I had one free hour and a Nao robot bored, I put some code over code and I have implemented the same eye-tracking system for the Nao robot. Now, when you look to the robot, he can know where are you looking, be careful!

I have uploaded the code to gitHub, maybe someone can find it interesting.

When the ideas have a value

Adrian, Nao, and the Next Nature

Adrian, Nao, and the Next Nature

Some months ago I spoke about the value of ideas. I would like to retake this issue and give a new approach to it. Some days ago, I had the opportunity to assist to an exposition (or showroom) celebrated into the TU/e University (EIndhoven). The idea of the exposition is very simple: students from the University have to work along some months into an idea and present their work and conclusions to professors, colleagues and visitors (like me).

It was a very interesting experience, and I would like to remark two aspects:

1.- The University supports the students ideas. Maybe you do not know or you do not remember, but the University where I come from, you can work in your ideas in your spare time (if you have) and the University, usually, is not interested in that work. Moreover, find a professor to support your ideas with time or resources… is quite difficult (but these professors exists, I assure you). Here, is mandatory (if you want to pass the course) to work in these ideas you have, or maybe others had before you (Is not crazy make the people work in innovative and stupid ideas, making research and spending public money?)

2.- The opportunity the students have to talk about their ideas and how hungry they are to know your opinion. I think, this is the first step to start a project (your own project): believe in it. I saw hungry in their eyes, expectation, appetite for continue, for know your feedback. That is great. These feelings are the foundations of the science.

At the University entrance, I saw a “slogan” I found a bit presumptuous: “Where the innovation starts“. I am starting to think I am wrong. I hope to be wrong. Till now, I have see what Spanish Universities and the central government do not give you: an opportunity

I can not explain how impressed I felt: good ideas, crazy ideas, stupid ideas, mad ideas… all kind of them, all kind of students, all of them brilliants, all of them in the first steps to get something very difficult: work in something you love exploring your own ideas, your own path, your own way.

I would like to talk about all projects presented, but it will take more time I have. I invite you to read about the projects from their owners: the students.

Spotbros: Mis impresiones

Spotbros, mensajería Made In Spain

Spotbros, mensajería Made In Spain

Últimamente ando un poco inquieto con el tema de las aplicaciones de mensajería para móviles. No, no es que no quiera pagar los 70 Céntimos de WhatsApp, es que si tengo que pagar, prefiero hacerlo por un producto que me convenza plenamente. ¿Y que tiene de malo WhatsApp?, bueno… prefiero preguntar ¿Qué hace WhatsApp con la información que vuelco?. Como no lo tengo claro, busco alternativas.

Y encontré Spotbros, una aplicación Made in Spain, si señor, ¡qué aquí hacemos más cosas además de ir de procesiones y a los toros!. Debo confesar que yo quiero que me guste Spotbros, y no sólo por lo que dicen acerca de la privacidad, sino porque siento debilidad profesional por el software diseñado en mi país, que carajo (aunque a veces me avergüence).

Partiendo de ese sentimiento que hace que mi pecho se hinche hasta el límite de la explosión patriótica, practicaré el castizo deporte de criticar. Y es que Spotbros tiene una interfaz limpia, elegante, es rápido y además ligero. Pero esto no aporta nada a sus desarrolladores, sólo les regalo los oídos, y a los Españoles nos gusta criticar 🙂

Spotbros mola, pero quiere molar demasiado. ¿Para que sirve Spotbros?, para muchas cosas… puedes mandar mensajes a tus colegas (que es, creo, lo que todo el mundo que lo instala quiere hacer) y además puedes instalar aplicaciones propias de Spotbros para bajar música, para saber cuanto queda hasta que llegue el bus, lo que te deparan los astros ese día, ligar en la discoteca con los “Shouts”… Cuantas cosas, ¿verdad?

Ahí está su valor añadido, todas esas cosas, y así es como quieren ganar dinero (recordad niños, en Internet no hay NADA gratis, todo el mundo busca un beneficio con sus aplicaciones, lo malo es cuando no sabes como lo sacan… desconfiad). Ese, su valor añadido, creo que es precisamente su talón de Aquiles.

Spotbros se pierde dentro de sus virtudes. Quiere abarcar tanto que aspectos sencillos se le escapan. Yo personalmente, cada vez valoro más las aplicaciones que hacen una cosa y la hacen bien. Y es en este aspecto creo que Spotbros tiene más potencial que sus competidores (salvo el imbatible WhatsApp).

Y aquí mi primera crítica: el SB Mail. Un concepto que no sé para que sirve si no es para desquiciar al usuario. Si le quieres enviar a un amigo una imagen, vídeo, canción, etc… entonces al adjuntarla se crea el SB Mail (¿pa qué?) y lo adjuntas, debes poner un asunto (¿pa qué?) y luego mandarlo. A tu colega le llega la foto, la abre (abre el SB Mail) y la ve, le hace gracia y deja un comentario, ¡pero lo deja en el SB Mail!, y claro, eso no aparece en la conversación que tenías… así que al traste con la conversación original.

Eso perjudica enormemente lo que llaman la experiencia de usuario. WhatsApp hace cosas bien, muchas, ¡copiadlas!, envías una foto y llega encogida, para ahorrar ancho de banda, para que se abra de forma rápida, dentro de la conversación. Eso facilita la experiencia de usuario. No el SB Mail.

Mi segunda crítica viene del aspecto por el que más presume Spotbros: la privacidad. Resulta que toqueteando por los perfiles de mis amigos, descubro que puedo ver a quienes tienen de contacto. Algo así como ver los amigos de mis amigos en Facebook. Hombre, muchachos de Spotbros, no me digáis que cifráis las comunicaciones, que no guardáis nuestros datos, y luego resulta que mis contactos (de los cuales sólo el 20% son amigos) pueden ver a mis otros contactos… Si, que lo puedo quitar, pero no me pongas eso por defecto. Mis contactos, son míos, y ya si eso dejaré yo que se vean para presumir de gente, como en LinkedIn (que cuantos más contactos, más molas)

Y para terminar mis críticas “constructivas” quiero hacer una reflexión. ¿habéis probado Line (el de los japoneses)?, ¿qué es lo que mola de Line?, ¿unas llamadas VoIP que se cortan?, ¿la enorme cantidad de batería y memoria que requiere?, ¿la ingente cantidad de tiempo que requiere para abrir una foto?. No, no y no y no. Lo que mola de Line son los Stickers. Esos emoticonos grandes y grotescos que nos permiten alegrar nuestras conversaciones (y que además a la gente de Line le dan dinero).

En resumen. Me gusta Spotbros por muchas cosas: velocidad, limpieza de la interfaz, presentación, consumo de recursos… pero sigue sin ser el producto que busco: Una aplicación para chatear con amigos, mandarles fotos, vídeos y enlaces de la red, hacer todo eso en un tono desenfadado y cuya curva de aprendizaje sea ridícula. ¿Se puede hacer?, creo que Spotbros lo puede hacer, pero debe simplificar muchas de las cosas que tiene.

Personalmente, seguiré usando Spotbros hasta que mis amigos dejen de hacerme caso, encuentre una mejor alternativa o la aplicación se convierta en un monstruo inmanejable. No creo que copiar los aciertos de tus competidores sea malo. Lo que es malo es copiar sus errores.

Y para los que habéis llegado hasta aquí, una pequeña comparación de consumo de memoria de WhatsApp, Line y Spotbros en mi terminal, para que veáis que Spotbros mola 😉 (aunque, o a causa de que, sea Español)

Aplicación Memoria (Mb)
Spotbros 8,6 Mb
WhatsApp 13 Mb
Line 49 Mb (2 procesos)

Futuroscopias: Ciencia ficción en castellano

Portada del número 3 de Futuroscopias

Hace pocos días tuve la suerte de descubrir un proyecto nacional que aboga por publicar de forma gratuita relatos de ciencia ficción: Futuroscopias

Los que me conocéis sabéis de mi predilección por este género. Y es que siempre me ha gustado la originalidad de muchos autores a la hora de crear una excusa para hablar de temas muy serios.

No me quiero dispersar en cosas mías ya que prefiero ceñirme al motivo original de la entrada: convenceros de que le echéis un vistazo.

La revista incluye varios relatos, algunos más largos que otros pero todos de gran calidad. Personalmente destaco los dos siguientes:

Pensando a la fuerza

Más que un relato, lo calificaría como “un programa radiofónico”, y es que este texto pone en la voz de un tal Federico la crónica diaria de un día cualquiera de un año cualquiera. Bueno, cualquiera no, y es que esa mañana un individuo había sido detenido por entrar en una iglesia con la firme intención de obligar a los asistentes a… ¿pensar?.

Divertido y cruelmente real este relato no os dejará indiferentes. Y es que en ocasiones si añades a la realidad un tono fantástico, sigue siendo la dura y cruel realidad, pero más entretenida. Antonio Morera ha sabido sacar punta de algo que ha todos nos ha indignado o divertido a partes iguales.

Walden III

Ese es el nombre de una comuna establecida en las salvajes y primitivas tierras de una Galicia proyectada unas cuantas décadas en el futuro. Allí, Amador Casares se erige como líder, revolucionario y pensador, comandando un movimiento rebelde que pretende ser independiente dentro de la autoridad ejercida por el gobierno central de Moscú.

Y es que nuestra Europa ya no es lo que era. Usando una invasión extraterrestre como excusa, el autor (Antonio Morera) nos deleita con las conversaciones que mantienen Amador Casares con un periodista llegado de América que pretende reflejar la barbarie de aquellos que se oponen al sistema.

A través de sus conversación conoceremos que llevó a este revolucionario a desafiar con una impresora 3D a lo que quedaba del mundo civilizado.

Today: A weekend project

Today main window. Very simple, right?

Today main window. Very simple, right?

Two weeks ago I started what I call a Weekend project: a project I start a weekend because I am boring and I finish two weeks later, after test the code and include files like license, readme, etc.

In this occasion, I have write a small application to help me to improve my writing in English. How?, well, I just  need to write a lot to improve my informal English, and the blog require more worked text. With this application I can write in a few minutes what I have done along the day, like in a diary.

Today (that is the name of the application) keeps a registry of the entries, stored by date. So, the user only need to select the date, write and save. Also, the application includes a spell checking feature to help to write words correctly.

I encourage you to download de code and test the program. Let me know your impressions 😉

The big deal

Sunset through a crystal ball, by twombold

Sunset through a crystal ball, by twombold

Along my life I have observed how easy is to detect big opportunities years after the best moment. I mean, in 90s it was obvious that the best investment in the 80s were computers, in first years of 21th century it was clear that the best investment in 90s were mobile phones, and you can find hundreds of examples like these.

How to find a good opportunity is probably (with the eternal beauty) one of the most wanted things of this era. Everyone wants to find its “El Dorado”, the philosopher stone that allow them to live a comfortable life. Of course, I am one of them, everyone has its own idea about a “comfortable life”.

You can be sure that within ten years, everyone you ask will know what was the best opportunity to invert ten years ago, i.e. now. So, I think we only can observe our environment and smell the wind, letting our instincts act.

What is the value of an idea?

zen_idea_by_caen_n-d5flbsh

ZenIdea, by Caen-N

Probably, you have listen a hundred of times expressions like “the success of this project is its idea” or “the core of this business is its invaluable idea“. Of course, we can swore that they are correct, everyone agree about the importance of a good idea, how important is to get a simple and pure good idea.

But, really we pay for good ideas?, how much we pay?, a good idea compensates the economic effort of bad (or at least, as not good) ideas?. I have look intensively for answers these lasts weeks, and my conclusion (I hope and desire to be wrong) is that all people want good ideas, they hope you will find them like mushrooms after the rain, but what finally decides your value is not your ideas but your the economic results you produce.

So, your value are not your ideas but your capacity to make money with these ideas, do not hope to live selling ideas

¡Abrazos gratis!

Hagamos un experimento, coge un trozo de papel y escribe en él “Abrazos gratis“. Ahora ponlo en un lugar visible: la mesa del despacho, la puerta, colgado en el pecho… donde sea, y regala tantos abrazos como puedas 🙂

Al final del día me dices como te sientes

Hug, por WhiteWeasel

Hug, por WhiteWeasel