I wrote this method (it displays an image):
void ImageLoader::displayMyImage()
{
namedWindow("new_Window1");
imshow("new_window1", m_image);
waitKey(2);
}
m_image is of Mat type.
I also use this destructor:
ImageLoader::~ImageLoader()
{
m_image.release();
}
However, Valgrind found tons of memory leaks. It's caused by these two cv functions:
namedWindow and imshow (because without calling the displayMyImage() there is no any leak).
Is there a way to fix it?
Thanks!
Your first problem is that you name the named window differently:
"new_Window1" is different from "new_window1". Second, I tell you I have never used namedWindow, you only need to use imshow to display an image in an image window called "new_window1".
Remark1: you don't need to worry about explicitly releasing m_image, that is what Mat is for in the first place.
Remark2: waitKey(0) holds the window forever.
I have seen this question here before, so I think you could search here too for answers.
Related
I have a simple problem however I'm not sure how it could be solved. I have the following code (c++):
Mat myImage;
for(;;){
imshow("Name", myImage);
}
Lets make the assumption that myImage is already populated with an image here. For some reason this very simple code is causing a memory leak. I read somewhere online that supplying imshow with the same image results in imshow adding it as a seperate axis, increase the memory comsumption.
Basically I dont know how to stop this memory leak. Any ideas?
Thanks.
Edit 1
Here is a screen shot of what I'm seeing when analysing memory usage.
Edit 2
Here is an example xcode project, made from scratch to display this issue. If you cannot run xcode, I've also provided a copy of the code on pastebin here. The project files can be downloaded from here.
In MFC I'm loading a .PNG image and thereafter, I'm displaying it with a static control as below:
CImage Img;
Img.Load(_T(abc.png"));
CBitMap Bmp;
Bmp.Attach(Img.Detach());
CStatic dispImg;
dispImg.SetBitmap(Bmp);
In this way I've several images which I'm displaying with the static control repetitively
which is causing significant memory leak within my application. I found several clues by googling, but I couldn't decide the best option for releasing memory. Could anybody please guide me with the best approach.
This code is incomplete. Using a CStatic in this way will never work. It isn't created.
If you realy want help that macthes your question give a more detailed description.
When you use CStatic::SetBitmap ypu must free the HBITMAP handle that is returned by the function. Just read the docs. So if you use this samne CStatic in a Loop and always assign a new Bitmap to the CStatic this may cause a leak.
As xMRi suggested I'm freeing HBITMAP handle returned by CStatic::SetBitmap. In my test app there is a CStatic control member m_pic, a method ChangePic which sets a Bitmap and a button control for changing the image based on a value of a boolean variable SetBlueImg. Defination of ChangePic as below:
void CPNGTestDlg::ChangePic(Cstring img)
{
CImage Img;
Img.Load(img);
CBitmap Bmp;
Bmp.Attach(Img.Detach());
HBITMAP hBmp=m_pic.SEtBitmap(Bmp);
if(hBmp!=NULL) DeleteObject(hBmp);
}
Click event of the button is defined as below:
void CPNGTest::OnBnClickedChngPic()
{
if(SetBlueImg)
{
ChangePic(_T("Blue.png"));
SetBlueImg=false;
}
else
{
ChangePic(_T("Red.png"));
SetBlueImg=true;
}
}
Initial value of SetBlueImg=true and in OnInitDialog() I called ChangePic(_T("Red.png"));
I ran the application and continuously clicking the button to change current image but still I can see memory leaks through windows task manager. Hike of memory is by 4KB after clicking button 40/50 times or sometimes unpredictably. Please, point out where I'm missing something which is causing the leaks.
To get rid of overlapped images when replacing one image on a Static Control with another one, I initially followed the steps below:
ShowWindow(SW_HIDE)
SetBitmap()
ShowWindow(SW_SHOW)
but I didn't know whether this is a correct way to solve the image overlapping. I searched a bit by googling and found the following way:
Copying area on the parent window behind the static control before it is drawn for the first time.
Copying the image back to the parent every time the static control needs to be redrawn.
The HBITMAP object has to be deleted when the dialog is destroyed.
void CMFCAppDlg::OnDestroy()
{
CDialogEx::OnDestroy();
DeleteObject(m_pic.GetBitmap());
}
I am writing a GUI program using Qt and doing some video processing with OpenCV. I am displaying the result of the OpenCV process (which is in a separate thread) in a label in the main GUI thread.
The problem I am having is cv::waitKey doesn't work unless I open a native OpenCV window opened using cv::namedWindow or cv::imshow. Does anybody know how to solve this?
Short example:
void Thread::run()
{
//needed variables
cv::VideoCapture capture(0);
cv::Mat image;
//main loop
//cv::namedWindow("test");
forever
{
capture>> image;
if(!image.data)
break;
emit paintToDisplay(convertToQImage(image));
cv::waitKey(40);
}
}
With //cv::namedWindow("test"); i.e. commented, the program crashes with access violation error.
With cv::namedWindow("test"); i.e. uncommented, the program displays perfect but there's a window (named test) I don't want or need. Anybody?
cv::waitKey() only works with OpenCV windows, which is not what you are using right now.
I suggest you investigate a QT alternative, most probably qSleep(), which is provided by the QTest module:
QTest::qSleep(40);
cv::waitkey is part of opencv's gui loop for show window
If you simply want to wait for a key press see QWaitcondition.
OR you could display another named window with no image in it, or a small 1,1 pixel image and just ignore the window
I found a solution to use msleep(). It's easy to use since it's a member of the class QThread.
Just thought i'd update this in case someone with a similar problem finds this thread.
You can call
qApp->processEvents();
instead of
cv::waitKey(40);
in the loop to make your application responsive and let the rest of the loop do their job.
I'm trying to display video from a webcam. I capture the images from the webcam using opencv and then I try to display them on a GtkImage.
This is my code, which runs in a seperate thread.
gpointer View::updateView(gpointer v)
{
IplImage *image;
CvCapture *camera;
GMutex *mutex;
View *view;
view=(View*)v;
camera=view->camera;
mutex=view->cameraMutex;
while(1)
{
g_mutex_lock(view->cameraMutex);
image=cvQueryFrame(camera);
g_mutex_unlock(view->cameraMutex);
if(image==NULL) continue;
cvCvtColor(image,image,CV_BGR2RGB);
GDK_THREADS_ENTER();
g_object_unref(view->pixbuf);
view->pixbuf=gdk_pixbuf_new_from_data((guchar*)image->imageData,GDK_COLORSPACE_RGB,FALSE,image->depth,image->width,image->height,image->widthStep,NULL,NULL);
gtk_image_set_from_pixbuf(GTK_IMAGE(view->image),view->pixbuf);
gtk_widget_queue_draw(view->image);
GDK_THREADS_LEAVE();
usleep(10000);
}
}
What happens is that one image is taken from the webcam and displayed and then the GtkImage stops updating.
In addition, when I try to use cvReleaseImage, I get a seg fault which says that free has been passed an invalid pointer.
GTK is an event-driven toolkit, like many others. What you're doing is queuing the new images to draw in an infinite loop, but never give GTK a chance to draw them. This is not how a message pump works. You need to give a hand back to GTK, so it can draw the updated image. The way to do that is explained in gtk_events_pending documentation.
Moreover, allocating/drawing/deallocating a gdk-pixpuf for each image is sub-optimal. Just allocate the buffer once out of your loop, draw on it in your loop (it will overwrite the previous content), and display it. You only need to reallocate a new buffer if your image size changes.
I don't know how to work with GtkImgae, but my guess is that you are not passing the newer images to the window. You need something like the native cvShowImage to execute inside the loop. If it isn't that I don't know.
Also You shouldn't release the image used for capture. OpenCV allocates and deallocates it itself.
EDIT: Try using the OpenCV functions for viewing image and see if the problem is still there.
There is this weird bug in my program that I'm trying to fix, but I'm really at a loss for what it could be. This part of my program has a dialog which shows previews of various items using MFC/GDI. When I scroll through different items, sometimes the preview image just disappears and goes blank. However, it:
Only happens on some machines
Apparently happens on both Windows 7 and XP
Doesn't happen on the same item every time
Item IS STILL THERE when one takes a screenshot, but it is blank when viewing it normally.
Seems to happen at random places throughout the code when I'm attempting to trace through it with breakpoints. It's not always in the same location that the screen goes from image to blank, which leads me to believe that it's not happening in the same thread as my main thread, even though that's really the only thread that's not blocked at that point. That means that it's happening in a windows thread or something, doesn't it?
I'm assuming it's a race condition of some sort, but the behaviour of the preview in screenshots, in particular, rather confuses me. Why would it be fine when taking a screenshot but be blank when viewing it on screen? Is there some mechanic of the "printscreen" that bypasses what's displyed or updated on the screen?
I realize that I haven't given much information and that people obviously can't help much, but if anyone could think of ANYTHING, it would be much appreciated :)
Thanks!
Another theory: GDI resource leak
If you forget to free your GDI objects, weird things start to happen - including unpainted areas.
Run taskmgr.exe and add the "GDI Objects" column.
Run your software and monitor the GDI object count. Does it stabilize?
If your GDI Object count does not stabilize, look in your relevant WM_PAINT handlers.
Here's an example of a GDI leak:
void CMyWnd::OnPaint()
{
CPaintDC dc(this);
dc.SelectObject(&font);
}
Selected GDI objects must always be deselected:
void CMyWnd::OnPaint()
{
CPaintDC dc(this);
CFont *pOldFont = dc.SelectObject(&font);
// Use font
dc.SelectObject(pOldFont);
}
When you record your screen, are you reading the desktop using GDI apis? In that case, any hardware-accelerated surface may become black (or possibly white). To test this, you can disable hardware acceleration for your graphics card. If your recorder starts working then you've found the culprit!
To record these non-GDI surfaces you probably need to read the surface using DirectX/OpenGL. I would start with this article: http://www.codeproject.com/KB/dialog/screencap.aspx