0

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;
}
liberforce
  • 11,189
  • 37
  • 48
Alex Magsam
  • 53
  • 1
  • 7
  • I'm not familiar with Gtk+, but usually GUI frameworks are message based, and need some code to "pump messages" in order for the UI to be responsive. In this case it seems that `gtk_main` is the only function that does so. My guess would be that you have to call something like [`gtk_main_iteration_do ()`](https://developer.gnome.org/gtk3/stable/gtk3-General.html#gtk-main-iteration-do) in your capture loop in order for the GUI to update. – Dan Mašek Jul 14 '17 at 23:01

1 Answers1

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.

liberforce
  • 11,189
  • 37
  • 48