OpenCV阻塞了我的GTK接口

OpenCV blocking my GTK interface

本文关键字:GTK 接口 我的 OpenCV      更新时间:2023-10-16

我用GTK3编写了一个非常简单的GUI,有三个按钮:

  • 启动:调用OpenCV VideoCapture
  • 停止:停止VideoCapture
  • 退出:破坏窗口

当我点击"停止"时,问题就出现了,OpenCV进程会阻塞GUI,并且命令会在几秒钟(通常是一分钟)后执行。

这是我的主菜:

bool stop = false;
static void start_webcam (GtkWidget *widget, gpointer   data)
{
    cout<<"Webcam On"<<endl;
    int err = 0;
    **err = opencv_webcam(); // this function loads the OpenCV Webcam**
    // troubles?
    if (err != 0)
    {
        cout<<"Unable to load the webcam. Error Code # "<<err<<endl;
    }
}
static void stop_webcam (GtkWidget *widget, gpointer  data)
{
    stop = true;
    cout<<"Webcam Off"<<endl;
}
int main (int   argc, char *argv[])
{
    // Widgets
    GtkWidget *window;
    GtkWidget *grid;
    GtkWidget *button;
    // GTK Init
    gtk_init (&argc, &argv);
    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title (GTK_WINDOW (window), "WEBCAM CONTROL PANEL");
    g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
    gtk_container_set_border_width (GTK_CONTAINER (window), 10);
    grid = gtk_grid_new ();
    gtk_container_add (GTK_CONTAINER (window), grid);
    /// START WEBCAM
    button = gtk_button_new_with_label ("Start");
    g_signal_connect (button, "clicked", G_CALLBACK (start_webcam), NULL);
    gtk_grid_attach (GTK_GRID (grid), button, 0, 0, 1, 1);
    /// STOP WEBCAM
    button = gtk_button_new_with_label ("Stop");
    g_signal_connect (button, "clicked", G_CALLBACK (stop_webcam), NULL);
    gtk_grid_attach (GTK_GRID (grid), button, 1, 0, 1, 1);

    /// QUIT
    button = gtk_button_new_with_label ("Quit");
    g_signal_connect (button, "clicked", G_CALLBACK (gtk_main_quit), NULL);
    gtk_grid_attach (GTK_GRID (grid), button, 0, 1, 2, 1);

    /// GO!
    gtk_widget_show_all (window);
    gtk_main ();

    return 0;
}

我想为"退出"按钮设置一些高优先级。我尝试在Windows中通过SetPriorityClass()设置main中的最高优先级,但没有成功。

非常感谢!

编辑

这是我的openCV代码:

extern bool stop;
int opencv_webcam()
{
    /// Various stuff
    cv::Mat frame;
    cv::namedWindow("Webcam Session");
    /// Webcam Opening
    cv::VideoCapture clip(0);
    while(stop != true)
    {
        // frames extraction
        clip.grab();
        clip.retrieve(frame);
        // troubles?
        if ((frame.empty()==1))
        {
            // errore!
            return -1;
        }
        /// SHOW the frames
        cv::imshow("Webcam Session", frame);
        if (waitKey(30)>= 0)
        {
            break;
        }
    }
    return 0;
}

GTK+是NOT多线程的。当您的一个信号处理程序正在运行时,所有其他GUI处理都会停止opencv_webcam()函数在GUI线程上运行,并在处理"开始"按钮信号时运行其主循环。停止和退出按钮不起作用的原因是它们从未有机会运行(至少在opencv_webcam()出错之前)。

我不知道什么是合适的解决方案;我对OpenCV的了解还不够,无法提出一个解决方案,让你在玩GTK+的同时有稳定的时间。不过,我知道两种可能性:

  1. gdk_threads_add_idle()回调中执行所有OpenCV处理(稳定的定时将更困难)
  2. 在不同的线程上运行OpenCV(如果你想在窗口中显示帧图像,你需要跨线程交流帧图像)

你需要四处搜索,找出最好的解决方案。试着在谷歌上搜索"gtk-opencv",看看你得到了什么。

或者,如果你正在做严格的网络摄像头工作,你可能想看看libcheese,它是专门针对网络摄像头的GTK+补充。


至于按钮优先级,据我所知,没有信号优先级。考虑到上面对您的错误的诊断,您应该能够理解为什么优先级无论如何都没有帮助。事实上,我不知道有任何GUI工具包适用于任何具有这种能力的平台。相反,您应该修复阻止GUI快速运行的线程错误。