[Code] NotifyPropertyChanged Equivalence on Qt

Whazzaaaapp? So, let’s turn our geek mode on now. For today’s post, the theme is about Qt. So, lately I’ve been in a huge need for a feature like NotifyPropertyChanged in .NET (C#). For you who don’t know what it is, it’s some kind of mechanism for a variable to notify other components that its value has been changed, and the other components will behave accordingly. This is a huge advantage if you have a lot of GUI components that are dependent on some certain variables (like visibility, enability, and stuff).

However, I couldn’t find any equivalence of this thing on Qt and I need to have this feature for primitive types (integer, boolean, string, etc). Since Qt is kinda big on SIGNAL and SLOT, so this was the first solution that came up to my mind, making a new class for each primitive type. I know, maybe it would be better if I made template classes instead, but the template class is not working with QObject, which is necessary for SIGNAL and SLOT. I’ve found some workarounds here, but I think the solution with observer is a huge amount of work, since I can’t connect it to the slot the the GUI components already have. So, I did it the brute force way, for every primitive class that I might need, I made a corresponding class.

I tested them, and they’re working just fine and it’s easy to use as well. All you need to do in your code is to connect the variable with whatever component you want to connect it with. Let’s say I want to connect a string with a label. It will go like this:

MString mstr;
connect(&mstr, SIGNAL(valueChanged(QString)), ui->label, SLOT(setText(QString)));

If there’s somewhere in your code that the mstr value is changed, the text on ui->label will be changed as well. You might think that “Oh Andru come oon, it’s only one extra line to change the text. What’s the huge deal of this feature?” Well imagine if you’re changing the variable in various places, it means that you have to add that one extra line every single time the string is changed and it’s just pain in the ass.

And of course, I have made for other types as well: double, float, boolean, and integer. For my current use, the signals give the original type as well as the QString representation. For example:

MInteger mint;
connect(&mint, SIGNAL(valueChanged(QString)), ui->label, SLOT(setText(QString)));
connect(&mint, SIGNAL(valueChanged(int)), ui->label, SLOT(setNum(int)));

The implementation is very easy, it would take you no time to implement it yourself, but I thought it would be unnecessary time being wasted if I already implemented it, right? So, it’s just one header file (mmodel.h), all implementations are inline. And it can be downloaded here. And as a bonus, I included a little widget project to show you how it works. Even though it’s an easy peasy work, but please credit me if you’re using it in your application. All questions are welcome. I hope this helps.

And if you happen to know better solution than this, please inform me. I would love to know it. :D

[Code Journal] Blackmagic Intensity Pro Stream to OpenCV

Hey hey been a while. My internship project is progressing very slowly now, since I’m facing a problem with calibration. In order to help me doing the calibration, my supervisor gave me a blackmagicdesign product: Intensity Pro. This is an editing card that takes HDMI input. Complete spec of the thing can be seen here. They also provide the SDK to do a bunch of stuff. As for me, I only need to do a simple reading and process it with OpenCV, so what I need is DeckLink SDK that can be found here. In the SDK, it includes some samples and stuff. So go crazy!

Now one of the samples is Capture which allows us to capture the stream from our device and replay it. In my case, my stream format is UYVY. So basically I need a function that converts the stream from my device to an OpenCV. The code is right here:

void convertFrameToOpenCV(void* frameBytes, IplImage * m_RGB){

int height = 1080; int width = 1920;
if(!m_RGB) m_RGB = cvCreateImage(cvSize(width, height), IPL_DEPTH_8U, 3);

unsigned char* pData = (unsigned char *) frameBytes;

for(int i = 0, j=0; i < width * height * 3; i+=6, j+=4)
{
unsigned char u = pData[j];
unsigned char y = pData[j+1];
unsigned char v = pData[j+2];

m_RGB->imageData[i+2] = 1.0*y + 8 + 1.402*(v-128);
m_RGB->imageData[i+1] = 1.0*y - 0.34413*(u-128) - 0.71414*(v-128);
m_RGB->imageData[i] = 1.0*y + 1.772*(u-128) + 0;

y = pData[j+3];
m_RGB->imageData[i+5] = 1.0*y + 8 + 1.402*(v-128);
m_RGB->imageData[i+4] = 1.0*y - 0.34413*(u-128) - 0.71414*(v-128);
m_RGB->imageData[i+3] = 1.0*y + 1.772*(u-128) + 0;
}
}

The code works just fine for me. I hope it helps. Please note that my stream is UYVY. I’m not sure whether all stream format will be in UYVY.

Happy coding!

[Code Journal] Stereo Calibration on OpenCV

Well, this is just a little reminder for myself really. When you’re doing stereo calibration on OpenCV, it is better if you get calibration result from each camera first and then force the stereoCalibrate function to take the intrinsic parameter and distortion coefficient from previous calibration. So, the stereo calibrate will only compute the rotation and translation from camera 1 to camera 2. As beautifully written here.

Ciao!

[Code Journal] Number Formatting with Zeros Padding on Qstring

Oh my God, when I used Java, it was like a breeze to do number formatting and stuff. When I tried to do the same thing on Qt, I needed to spend like 30 minutes or so. Well, I might be just stupid, but still for such an easy task, it shouldn’t take too long.

So, what I need is a 4 digits string representation for an integer, with 0 padding on the left. So:

1 -> “0001”
199 -> “0199”

.. and such. So, I finally got my answer here. It’s this one:

QString("%1%2").arg(x < 0 ? '-' : '+').arg(qFabs(x),5,'f',2,'0');

So, what I need is just the second arg, since the first arg is for the sign of the value. So, here is what I did:

QString("%1").arg(x,4,'d',0,'0');

The first argument is the number that’s going to be converted. The second one is the width of the field I want to fill. Third is the format of your number (‘f’->float, ‘d’->integer, etc). Fourth is how many digits after decimal point (fraction precision). and the fifth is the padding character.

And voila, it’s working now. :D

To Tumblr, Love Pixel Union