2017-07-14 105 views
0

我有一个程序在这里执行人脸检测,我想用这些坐标来移动GTK + 3.22使用GTK的 gtk_window_move函数创建的窗口。我希望窗口在OpenCV的moveWindow函数移动过程中保持全部打开状态。基于人脸检测坐标的GTK +移动窗口

我昨天刚刚下载了GTK +包,所以我并不都太熟悉。

该程序将执行一个循环100次,跟踪整个时间的脸部。目前,人脸跟踪工作,但窗口不会出现,直到循环完成。为什么是这样?我相信gtk_move_window函数正在工作,但窗口不会保持打开状态。我试过每次在循环中重新打开窗口,或者在循环之前打开一次。如果您熟悉OpenCV的moveWindow函数,那正是我正在寻找的。这里是示例代码。顺便说一下,如果你知道一个GTK +函数如何将窗口带到顶层的顶层,并在调用时打开所有其他窗口,这对我来说也是有用的信息。

#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; 
} 
+0

我对Gtk +并不熟悉,但通常GUI框架是基于消息的,并且需要一些代码来“抽取消息”以使UI响应。在这种情况下,'gtk_main'似乎是唯一的功能。我的猜测是你必须在你的捕获中调用像['gtk_main_iteration_do()'](https://developer.gnome.org/gtk3/stable/gtk3-General.html#gtk-main-iteration-do)循环以便GUI更新。 –

回答

0

捕获循环中的代码应该在事件处理程序回调中。 您首先需要拨打g_timeout_addg_idle_add来注册您的回拨。

您注册的回调是在运行gtk_main之后调用的GSourceFunc。返回值(G_SOURCE_CONTINUEG_SOURCE_REMOVE)控制是否要再次调用回调。