imshow window freeze in opencv - c++

I'm doing opencv with leap motion. when I try to create a window with black screen but the window freezes and not respond. anyone have this problem? this is my code.
Mat PaintShow( 480,640,CV_8UC3);
int main(int argc, char* argv[])
{
rectangle( PaintShow,Point( 0, 0),Point( 2000, 2000),Scalar( 0, 0, 0 ),-1,8 );
// Create a sample listener and controller
SampleListener listener;
Leap::Controller controller;
.
.
.
}
the following is the leap motion method which update every few ms. so I put imshow here
void SampleListener::onFrame(const Leap::Controller& controller)
{
const Leap::Frame frame = controller.frame();
imshow("PaintShow",PaintShow);
.
.
.
}

you need to call waitKey(some_millis); somewhere after imshow(), else your window won't get updated.

Related

SDL2 Window Only Shows Black Background [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 months ago.
Improve this question
I'm starting a new project in SDL2 and as I'm still trying out different architectural approaches I usually start out by bringing up a white window to confirm that the new approach I'm trying out satisfies at least the bare minimum to get started with SDL2.
This time, I wanted to try wrapping my application into a separate Application class so as to unclutter main, like so:
#include <SDL2/SDL.h>
#include <stdio.h>
#include <string>
#include "HApplication/HApplication.h"
//Screen dimension constants
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
int main(int argc, char *argv[])
{
HApplication application = HApplication( SCREEN_WIDTH, SCREEN_HEIGHT );
bool hasStarted = application.checkRunning();
if ( hasStarted ){
application.run();
}
else{
std::string msg = "Application failed to initialize.";
SDL_LogError( SDL_LOG_CATEGORY_ERROR, msg.c_str() );
}
// add error codes
return 0;
}
Now, the run method in HApplication is meant to reflect the main loop until the user exits. For test purposes, I'd just like to get two lines crossing in the middle on a white background. After initializing SDL, the window, and the renderer, which all work out fine, I'm presented with a window filled completely back, although I've used very similar code successfully before:
void HApplication::run()
{
// while user doesn't quit, keep going
bool userQuit = false;
SDL_Event e
while( !userQuit )
{
// handle queued events
while ( SDL_PollEvent( &e ) != 0 )
{
if ( e.type == SDL_QUIT )
{
userQuit = true;
}
}
// clear screen
SDL_SetRenderDrawColor( appRenderer, 255, 255, 255, 255);
SDL_RenderClear( appRenderer );
// draw cross
SDL_SetRenderDrawColor( appRenderer, 0, 0, 0, 255 );
SDL_RenderDrawLine( appRenderer, 0, screenHeight/2, screenWidth, screenHeight/2);
SDL_SetRenderDrawColor( appRenderer, 0, 0, 0, 255 );
SDL_RenderDrawLine( appRenderer, screenWidth/2 , 0, screenWidth/2, screenHeight);
// update screen with new scene
SDL_RenderPresent( appRenderer );
SDL_UpdateWindowSurface( appWindow );
}
close();
}
I'm not quite sure why this happens, especially since I can see what I want stepping through the loop step-by-step using the debugger. I am quite honestly pretty much at a loss at where to even start.
I tried looking on Google and Stackoverflow for similar questions. However, these were mostly addressing problems with loading textures, which I haven't even gotten to yet.
If possible, I would like to keep a separate class handling game logic and resources.
EDIT: It seems like I needed to get rid of SDL_UpdateWindow. However, I'm not quite sure why. If anyone has an explanation, I'd be happy to hear!
SDL has both a CPU rendering API and a GPU one.
Everything that works with a SDL_Renderer belongs to the GPU API. For example, you can make a SDL_Texture and use SDL_RenderCopy to render it. The final step is to call SDL_RenderPresent so that everything that was rendered gets displayed.
SDL_UpdateWindowSurface is part of the CPU API. To use this API, you can for example draw to a SDL_Surface and then use SDL_BlitSurface with SDL_GetWindowSurface to render to the window's surface. The final step is to call SDL_UpdateWindowSurface to display the changes, which is the equivalent to SDL_Flip in SDL 1.2.
In short: after the SDL_RenderPresent call, you get what you wanted, but after the SDL_UpdateWindowSurface call, you overwrite that with the CPU window surface which is probably initialized to black. Just remove that SDL_UpdateWindowSurface call and use the GPU API only.

GTK+ moving window based on face detection coordinates

I have a program here that performs face detection and I would like to use these coordinates to move a window created with GTK+ 3.22 using GTK's
gtk_window_move function. I would like the window to remain open the entire time while it is moving similar to OpenCV's moveWindow function.
I just downloaded the GTK+ packages yesterday so I am not all too familiar.
The program will perform a loop 100 times, tracking a face the entire time. Currently, the face tracking works, but the window does not appear until the loop is complete. Why is this? I believe the gtk_move_window function is working, but the window does not stay open. I have tried reopening the window each time in the loop, or just opening once before the loop. If you are familiar with OpenCV's moveWindow function that is exactly what I am looking for. Here is the sample code.
By the way, if you know how a GTK+ function that will bring the window to the very top layer on top of all the other windows open when called, that is helpful information for me as well.
#include "FlyCapture2.h"
#include <opencv2/core/core.hpp>
#include <opencv2/objdetect/objdetect.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/core/cuda.hpp>
#include <opencv2/cudaobjdetect.hpp>
#include <math.h>
#include <thread>
#include <iostream>
#include <vector>
#include <gtk-3.0/gtk/gtk.h>
using namespace FlyCapture2;
cv::Ptr<cv::cuda::CascadeClassifier> face_detect;
void detect_faces(cv::Mat img, cv::cuda::GpuMat buf,GtkWidget *win)
{
std::vector<cv::Rect>faces;
cv::cuda::GpuMat image_gpu(img);
//Face detection here
...
if (faces.size() > 0)
{
float x = faces[0].x;
float y = faces[0].y;
int new_x = roundf(x*40/51);
int new_y = roundf(y*135/256);
gtk_window_move(GTK_WINDOW (win),new_x,new_y);
gtk_widget_show (win); //Should this go here?
std::cout<<faces[0]<<std::endl;
}
}
int main( int argc, char *argv[])
{
//Camera connect here
...
//face detect variables
face_detect = cv::cuda::CascadeClassifier::create("/home/nvidia/opencv/data/haarcascades_cuda/haarcascade_frontalface_default.xml");
cv::cuda::GpuMat objbuf;
//GTK+ Params
GtkWidget *window;
GdkRGBA *color;
gtk_init (&argc, &argv);
gdk_rgba_parse(color,"(0,0,0)");
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_decorated(GTK_WINDOW (window),FALSE);
gtk_window_set_position(GTK_WINDOW (window), GTK_WIN_POS_CENTER);
gtk_widget_override_background_color(window, GTK_STATE_FLAG_NORMAL, color);
gtk_widget_show (win); //Should this go here?
// capture loop
for (int i=0;i<100;i++)
{
// Get the image
Image rawImage;
camera.RetrieveBuffer( &rawImage );
// convert to rgb
Image rgbImage;
rawImage.Convert( FlyCapture2::PIXEL_FORMAT_MONO8, &rgbImage );
// convert to OpenCV Mat
unsigned int rowBytes = (double)rgbImage.GetReceivedDataSize()/(double)rgbImage.GetRows();
cv::Mat image = cv::Mat(rgbImage.GetRows(), rgbImage.GetCols(), CV_8UC1, rgbImage.GetData(),rowBytes);
//Detect Faces
detect_faces(image,objbuf,window);
}
//Disconnect Camera
camera.StopCapture();
camera.Disconnect();
gtk_main();
return 0;
}
The code in your capture loop should be in an event handler callback.
You first need to call g_timeout_add or g_idle_add to register your callback.
The callback you registered is a GSourceFunc that will be called after gtk_main is run. The return value (G_SOURCE_CONTINUE or G_SOURCE_REMOVE) controls if you want to have the callback be called again.

My SDL application not responding

I have a problem with SDL. When i run the following code it is not responding. I have .bmp in same folder as the executable file.Is problem in code or where.....?
#include "SDL/SDL.h"
int main( int argc, char* args[] )
{
SDL_Surface* robot = NULL;
SDL_Surface* screen = NULL;
SDL_Init( SDL_INIT_EVERYTHING );
screen = SDL_SetVideoMode( 640, 480, 32, SDL_SWSURFACE );
robot = SDL_LoadBMP( "robot.bmp" );
SDL_BlitSurface( robot, NULL, screen, NULL );
SDL_Flip( screen );
SDL_Delay( 12*1000 );
SDL_FreeSurface( robot );
SDL_Quit();
return 0;
}
SDL_Delay( 12*1000 ); will halt the current thread for 12 seconds. The issue is that the thread which is halted is the "video" thread, the one in charge of displaying your image. After 12 secons the window will close and the program will exit.
In order to see the image and exit at will, you need to wait on a specific event of your choice like a keyboard event. See here how to make basic event loop with SDL.

SDL loading my image messed up

I'm attemting to load an image that I exported from flash CS3 it's a very cute face but it loads very weird it loads on a blueish way this is the code for the two files:
//main.cpp
#include <SDL/SDL.h>
#include <SDL/SDL_image.h>
#include "test.hpp"
int main(int argc, char *argv[])
{
SDL_Init(SDL_INIT_VIDEO);
// Activamos modo de video
screen = SDL_SetVideoMode(640,480,32,SDL_SWSURFACE | SDL_DOUBLEBUF);
image = IMG_Load("face.bmp");
dest.x = 200;
dest.y = 200;
//Main Loop
while(Abierto)
{
//We Draw
Draw();
//Events
while( SDL_PollEvent(&event))
{
if(event.type == SDL_QUIT)
Abierto = false;
}
}
// We free the image
SDL_FreeSurface(image);
SDL_Quit();
return 0;
}
Now the other one the;
//test.hpp
DL_Surface *image = NULL, *screen = NULL;
SDL_Rect dest;
SDL_Event event;
bool Abierto = true;
float PlaneX = 300, PlaneY = 200;
float velX = 0.1, velY = 0.1;
void Draw()
{
Uint32 color;
// Black Background is created
color = SDL_MapRGB (screen -> format, 0, 0, 0);
SDL_FillRect (screen, NULL, color);
SDL_DisplayFormatAlpha(image);
SDL_BlitSurface(image, NULL, screen, &dest);
// Flip the working image buffer with the screen buffer
SDL_Flip (screen);
}
I need help with this please Im not that experienced on SDL stuff oh and if you want to take a closer look I uplaoded the project here.
Oh my bad I must add the image is 32 pixels with alpha according to flash exporting options
According to docs, SDL_DisplayFormatAlpha returns a new image and keeps the original intact.
So, try in the first part, when you load the image:
SDL_Surface *origImage = IMG_Load("face.bmp");
image = SDL_DisplayFormatAlpha(origImage);
SDL_FreeSurface(origImage)
As there is no need to call SDL_DisplayFormatAlpha each frame.
Then in the second part, just blit image, without calling SDL_DisplayFormatAlpha.
UPDATE
I've just checked your picture, and it looks like it is a weird bmp. I've seen that before: BMP format is such a mess that if you don't keep to the basics chances are that different programs will interpret the data differently.
In your case:
display face.bmp shows correctly.
gthumb face.bmp shows nothing.
eog face.bmp says "bogus header data".
I strongly recommend using PNG files for all your game cartoon-like pictures and JPG for all the photo-like ones.
So run
$ convert face.bmp face.png
And use the PNG file. I'll will work better and you will have a file 20% the size of the original.

OpenCV cvNamedWindow not appearing under Fedora

As the title suggests I'm simply trying to get a named window to come up. I've been working with OpenCV for over a year now, and never had this problem before. For some reason, the window never opens. I've tried running some of my old scripts and everything works fine.
As a very cut down example, see below
#include "cv.h"
#include "highgui.h"
int main(int argc, char** argv) {
cvNamedWindow( "video", 0 );
IplImage *im = cvCreateImage( cvSize(200,200), 8, 3 );
while(1) {
cvShowImage( "video", im );
}
return 0;
}
I can see no reason why that wouldn't work, but for some reason the window never appears.
Has anyone else experienced this? It's doing my head in!
Simply call cvWaitKey(int milliseconds) within the loop. This function notifies the GUI system to run graphics pending events.
Your code should be something like:
int main(int argc, char** argv) {
cvNamedWindow( "video", 0 );
IplImage *im = cvCreateImage( cvSize(200,200), 8, 3 );
while(1) {
cvShowImage( "video", im );
cvWaitKey(100); //wait for 100 ms for user to hit some key in the window
}
return 0;
}