Updating itk image in Qt user interface - c++

I have a problem that I would like to tell you because is about some days that I don’t have new ideas.
I have an image pointed with a double* pointer, and I want to translate it into itk::smartpointer for updating the user graphic interface, for this purpose I made this method :
void prueba_r01::double2itk( double *im_proc, ImageType::Pointer *salida, int alto, int ancho)
// This method translate the double* image into itk:smartpointer image
ImageType::IndexType pixelIndex; // pixelIndex[0]= index x-axis; pixelIndex[1] = index y-axisy
ImageType::PixelType pixelValue;
ImageType::PixelType aux; //auxiliar variable for checking the behaviour of the programm
// Doing a sweep of all the image (is in double *im_proc) translating the values into itk pointer format
for (int x=0; x<ancho; x++){ // ancho: widht of the image
pixelIndex[0]=x;//x position
for (int y=0; y<alto; y++){ // alto: height of the image
pixelIndex[1]=y;//y position
pixelValue= *(im_proc+x+ancho*y);
(*salida)->SetPixel(pixelIndex,pixelValue);
aux = (*salida)->GetPixel(pixelIndex); // checking that the image has been correctly transtaled from im_proc to salida-- > CHECKED
}
}
}
And then is called here:
//Translation of the double* image into itk:smartpointer image
double2itk(out_inv, &(ui.imageframe->imagereader), alto, ancho);
And after that, the user interface is updated:
// Update of the image shonw in the user interface
ui.imageframe->update();
The problem is that it seems that everything is working correctly, but the image in the interface is not updated.
Another option also valid for my project could be to stored the image in a ‘.bmp’ or ‘.jpeg’ file.
Could someone help me? Any ideas of what is not working properly? Is there any function for creating this image files?

ITK has built-in mechanisms for this, with some considerable safety advantages. Also: they can be used in a pipeline like any image source, and because they use your existing array they will be considerably faster (I think) than looping over the indices.
http://www.itk.org/Doxygen/html/classitk_1_1ImportImageFilter.html
http://www.itk.org/Doxygen/html/classitk_1_1ImportImageContainer.html
http://www.itk.org/Wiki/ITK/Examples/IO/ImportImageFilter

You must use the ImportImageContainer, and be very careful how you set the memory management options.
By default ITK will clean up after itself, and will expect to be able to delete the memory pointed to by your external pointer.
There are examples of this in the Users Guide.
There is also a very nice wiki example at: http://www.vtk.org/Wiki/ITK/Examples/IO/ImportImageFilter

Related

Convert Mat to PvBuffer (from Pleora eBUS SDK lib.)

thank you in advance for reading this.
For better readability I'll list pieces of info. necessary in point form.
building an app based on eBUS player sample provided by Pleora.
Grabbing images in 16 bit gray in 50 fps.
my app is processing image data using openCV within the OnBufferDisplay function in DisplayThread
so far, I have successfully processed images suiting my needs and am trying to convert my Mat(processed already) data back to PvImage or PvBuffer s.t. the image can be displayed in the eBUS Player using the already existing display function(this way I can still use other features in the Player app without having to make too many modifications to the original app).
The difficulty arises from the fact that display functions and other important functions are hidden in dlls. I can only make modifications to what's exposed.
The processing procedure is basically:
void Display Thread::OnBufferDisplay(PvBuffer *aBuffer){
aBuffer->Attach(imageMat.data, 614400);
//where imageMat is init'd as
//imageMat = cv::Mat(cv::Size(imgWidth, imgHeight), CV_16U);
//process.. the data....
//at this point, I Have my Mat object ready to go.
//supposed to create or have another PvImage or PvBuffer with the processed datahere for displaying.
//Display
mDisplay->Display(*aBuffer);
}
What I have tried so far is:
memcpy(aBuffer->GetDataPointer(), imageMat.data 614400);
//and
aBuffer->free();
//and/or
aBuffer->Detach();
//then
aBuffer->Alloc(614400); //since 640 * 480 in 16 bit gray
memcpy( Mat.data to buffer->datapointer);
Please help me clarify the following:
I have discovered after using Attach(), the passed aBuffer does no longer properly display image. Does that mean this function not just copies the data from aBuffer to imageMat.data but erases the data in aBuffer and then copies it to imageMat.data?
I went for Attach() because memcpy(imageMat.data, aBuffer->GetDataPinter(), size); didn't work. It didn't copy the data properly like the way Attach() does. Anybody know why?
The description for Attach() provided by Pleora is "Attach this PvBuffer to an external memory buffer. To use an internal memory buffer, use Alloc.".
In summary,
How do you properly create a PvImage or a PvBuffer object that contains the data from my Mat object in order to pass to the Display() function?
Are there any detours to make this work without having to create such objects?

How to create std::map of Gdk::Pixbuf instances and use it in Gdk::Cairo

I guess one may found it trivial, but I ask it here since I could not find a straightforward answer.
Let's dive into the problem:
Having a resource of multiple images along with cairo context that is using these images incessantly. Naturally, I can do so as below:
Glib::RefPtr<Gdk::Pixbuf> image;
image = Gdk::Pixbuf::create_from_resource("/image/icon1"); //there are numerous icons out there
Then I can use it with Cairo context pointer like this:
bool MyClass::on_draw(const Cairo::RefPtr<Cairo::Context> &cr)
{
// ... some code
Gdk::Cairo::set_source_pixbuf(cr, image, x0 , y0); //x0 , y0 : somewhere in the context
cr->paint();
return true;
}
Images are not changing but it creates Pixbuf instance everytime. I want to use c++ map and put my icons in it. Then, I want to get the image pointer from the map. I did something like this:
std::map<Glib::ustring , GdkPixbuf*> map_Images;
// ..
map_images.insert(pair<Glib::ustring , GdkPixbuf* >("icon1" , image->gobj() )); // I do the same with all of my frequently referred icons
Now, I don't know how should I call this map to use with Cairo context. In other words, how should I make a Glib::RefPtr from the base object, say GdkPixbuf*
I would recommend you to make map_Images a map of type std::map<Glib::ustring , Glib::RefPtr<Gdk::Pixbuf> > and make it data member of MyClass. Because Glib::RefPtr will deallocate the owning object once all references are lost to that pointer.
What I want to say is that if you have code similar to this:
... some function, say fun1
{
Glib::RefPtr<Gdk::Pixbuf> image;
image = Gdk::Pixbuf::create_from_resource("/image/icon1");
map_images.insert(pair<Glib::ustring , GdkPixbuf* >("icon1" , image->gobj() ));
} // image object will die here. So, Gdk::Pixbuf held by Glib::RefPtr will be deallocated
Now, If you will try to access Gdk::Pixbuf * from the map, you will get dangling pointer.
If that is the case, skip the part that follows. Otherwise, continue reading.
Creating Glib::RefPtr of type Gdk::Pixbuf seems to be simple. As per source code that I found on GitHub: https://github.com/GNOME/glibmm/blob/master/glib/glibmm/refptr.h, make_refptr_for_instance(T_CppObject* object) API should do the job for you.
If you really want to create Glib::RefPtr of type Gdk::Pixbuf, you may get it by calling:
Glib::RefPtr<Gdk::Pixbuf> imageForIcon1 = make_refptr_for_instance<Gdk::Pixbuf>(map_images["icon1"]); // assumption: map_images already has an element with key "icon1"
Hope it helps.

Image weirdly changed after cv::resize()

The related code is here(C++, opencv):
Rect rec = boundingRect(...);
image_grey.copyTo(gesture_grey, mask);
imshow("image_grey", gesture_grey(rec));
resize(gesture_grey(rec), gesture_grey, Size(256, 256));
imshow("gesture_grey", gesture_grey);
The result of imshow():
Why are the two images so different before and after resizing? How to fix it?
The problem is in copyTo method. It doesn't clear the content of 'gesture_grey' image container.
When you use gesture_grey(rec) you are effectively executing copy constructor, which gives you a new image container, so it's all cool. But when you call copyTo you are copying over to an existing target 'gesture_grey'.
To fix it, you need to re-initialize 'gesture_grey' in order to clear it, before calling copyTo. Otherwise, what you see is a combination of the previous content of 'gesture_grey' + new content you copy from image_grey.

Show points in QCustomPlot with QCPItemTracer

I am trying for a longer while now to create a mechanism that would create text labels next to my points on a plot with the coordinates. From the documentation, I have read that I need to use QCPItemTracer for that. No matter how i try, I cannot display any additional items on my plot using this object. In the QCustomPlot examples, there is one program that user QCPItemTracer, but when i run it, I also dont see any additional objects. I am trying to run the example code from bellow:
QCPItemTracer *phaseTracer = new QCPItemTracer(customPlot);
customPlot->addItem(phaseTracer);
phaseTracer->setGraph(customPlot->graph(DATA_PLOT));
phaseTracer->setGraphKey(7);
phaseTracer->setInterpolating(true);
phaseTracer->setStyle(QCPItemTracer::tsCircle);
phaseTracer->setPen(QPen(Qt::red));
phaseTracer->setBrush(Qt::red);
phaseTracer->setSize(7);
From my understanding this was supposed to add red circles on my plot points. It does not. I Would really aprichiate any help in this matter, some example code maybe. I am struggling with this for a really long time.
I have managed to get the labels working:
returnCodes_t PlotData::insertPointLabel(const int& index, const double& x, const double& y)
{
QCPItemText *textLabel = new QCPItemText(m_parentPlot);
m_parentPlot->addItem(textLabel);
textLabel->setPositionAlignment(Qt::AlignBottom|Qt::AlignHCenter);
textLabel->position->setType(QCPItemPosition::ptPlotCoords);
textLabel->position->setCoords(x, y); // place position at center/top of axis rect
textLabel->setText(QString("x%1 y%2").arg(x).arg(y));
textLabel->setVisible(labelsVisible);
m_pointLabels.insert(index, textLabel);
return return_success;
}

QT - Pointer to global memory

First: sorry for my English from Google
The question:
I'm changing the IDE, I'm migrating from Borland to QT with QT Creator.
In Borland I used a class contained in a type library (APuma.dll). The prototype was:
BOOL XOpen (long hDIB, LPCTSTR FileName) / / OpenOCR - Cuneiform
hDIB is a pointer to global memory of an image.This version Not Work with files.
To pass a pointer to global memory of an image, I used GDI+, but in QT can not find anything similar, and the inclusion of Gdiplus.h and GdiPlusInit.h generates too many errors.
How do I give access to global memory where I host the image to XOpen?
Thank you very much.
OK, I think i understand what you need. You need a pointer to the pixels of the image so you can pass it. Your simplest option in Qt is using a QImage object and using its bits() member.
Something like this:
QImage image(filename);
uchar* p = image.bits();
XOpen(reinterpret_cast<long>(p), whatever);
just be sure that XOpen somehow knows the dimmensions of the image. And that you have it in the right format (See QImage::convertToFormat). For more overall information check the Qt documentation at http://doc.qt.io/qt-4.8/qimage.html