【问题标题】:GTK+ moving window based on face detection coordinates基于人脸检测坐标的GTK+移动窗口
【发布时间】:2017-12-20 01:43:41
【问题描述】:

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

我昨天刚下载了 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;
}

【问题讨论】:

  • 我不熟悉 Gtk+,但通常 GUI 框架是基于消息的,并且需要一些代码来“泵送消息”以使 UI 响应。在这种情况下,gtk_main 似乎是唯一这样做的函数。我的猜测是,您必须在捕获循环中调用类似 gtk_main_iteration_do () 的东西才能更新 GUI。

标签: c++ windows opencv gtk face-detection


【解决方案1】:

捕获循环中的代码应位于事件处理程序回调中。 您首先需要调用g_timeout_addg_idle_add 来注册您的回调。

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

【讨论】:

    猜你喜欢
    • 2013-05-15
    • 1970-01-01
    • 2013-08-22
    • 2016-05-19
    • 2019-06-18
    • 2014-04-06
    • 2016-03-17
    • 2019-12-01
    • 2019-11-18
    相关资源
    最近更新 更多