一起使用opencv和gtk + 2

时间:2016-12-08 15:01:31

标签: c++ opencv raspberry-pi gtk gtk2

所以我正在尝试实现以下目的:为用户创建一个gui,用户可以看到网络摄像头的实时进纸,并且还有两个按钮,用于启动和停止录制。所有这一切都必须在树莓派上运行。

我正在使用basler相机,所以我无法使用视频捕捉对象,但使用pylon sdk(用于basler相机的sdk)我设法抓取图像并将其转换为opencv :: mat。

然而,我坚持两点:

首先我根本不知道如何在gtk小部件上显示opencv :: mat。

第二个问题是我不知道如何获得直播。我试图使用g_timeout_add函数但是ui没有响应。它在后台调用该函数,但由于我每隔100ms调用它,它似乎永远停留在函数中,因此我无法点击任何按钮。

我在下面提供了一些代码。

#include <gtk/gtk.h>

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/video/video.hpp>

#include <pylon/PylonIncludes.h>

using namespace Pylon;
using namespace cv;
using namespace std;

void callback(GtkWidget *widget, gpointer labelstatus) {}

gint delete_event(GtkWidget *widget, GdkEvent  *event) {
    gtk_main_quit ();
}

static gboolean livefeed_func(gpointer data) {

    Pylon::PylonAutoInitTerm autoInitTerm;
    CInstantCamera camera(CTlFactory::GetInstance().CreateFirstDevice());
    camera.Open();
    GenApi::INodeMap& nodemap = camera.GetNodeMap();
    .
    . Some other pylon related stuff
    .
    CImageFormatConverter formatConverter;
    formatConverter.OutputPixelFormat= PixelType_BGR8packed;
    CPylonImage pylonImage;

    Mat openCvImage;
    cv::Size frameSize = Size((int)width->GetValue(), (int)height->GetValue());
    .
    . Some other pylon related stuff
    .
    formatConverter.Convert(pylonImage, ptrGrabResult);
    openCvImage = cv::Mat(ptrGrabResult->GetHeight(), ptrGrabResult->GetWidth(), CV_8UC3, (uint8_t *) pylonImage.GetBuffer());
    imwrite("tmp_name.jpg", openCvImage);
}

int main(int argc, char *argv[]) {

    //GTK

    GtkWidget *window;
    GtkWidget *table;
    GtkWidget *labelstatus;
    GtkWidget *labellog;
    GtkWidget *buttonexit;
    GtkWidget *buttonstart;
    GtkWidget *buttonstop;
    GtkWidget *livefeed;

    gtk_init (&argc, &argv);

    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title (GTK_WINDOW (window), "Table");
    gtk_container_set_border_width (GTK_CONTAINER (window), 20);

    gtk_signal_connect (GTK_OBJECT (window), "delete_event", GTK_SIGNAL_FUNC (delete_event), NULL);

    table = gtk_table_new (6, 6, TRUE);
    gtk_container_add (GTK_CONTAINER (window), table);

    labelstatus = gtk_label_new ("Status: Idle");
    gtk_table_attach_defaults (GTK_TABLE(table), labelstatus, 0, 2, 0, 1);
    gtk_widget_show (labelstatus);

    buttonstart = gtk_button_new_with_label ("Start");
    gtk_signal_connect (GTK_OBJECT (buttonstart), "clicked", GTK_SIGNAL_FUNC (callback), (gpointer) labelstatus);
    gtk_table_attach_defaults (GTK_TABLE(table), buttonstart, 0, 1, 1, 2);
    gtk_widget_show (buttonstart);

    buttonstop = gtk_button_new_with_label ("Stop");
    gtk_signal_connect (GTK_OBJECT (buttonstop), "clicked", GTK_SIGNAL_FUNC (callback), NULL);
    gtk_table_attach_defaults (GTK_TABLE(table), buttonstop, 1, 2, 1, 2);
    gtk_widget_show (buttonstop);

    labellog = gtk_label_new ("11:31:54: Started Recording\n11:36:54: Stopped Recording");
    gtk_table_attach_defaults (GTK_TABLE(table), labellog, 0, 2, 2, 3);
    gtk_widget_show (labellog);

    buttonexit = gtk_button_new_with_label ("Quit");
    gtk_signal_connect (GTK_OBJECT (buttonexit), "clicked",GTK_SIGNAL_FUNC (delete_event), NULL);
    gtk_table_attach_defaults (GTK_TABLE(table), buttonexit, 0, 2, 3, 4);
    gtk_widget_show (buttonexit);

    livefeed = gtk_drawing_area_new();
    gtk_table_attach_defaults (GTK_TABLE(table), livefeed, 2, 5, 0, 4);
    gtk_widget_show (livefeed);

    gtk_widget_show (table);
    gtk_widget_show (window);

    g_timeout_add(100, livefeed_func, livefeed);

    gtk_main ();

}

所以,如果我运行此代码,它将显示gtk窗口,然后无响应并写入图像,直到我取消该过程。

总结一下:

  1. 有没有一种方法可以在gtk中执行后台任务而不会使ui无响应

  2. 如何在gtk窗口/窗口小部件中显示opencv :: Mat?

0 个答案:

没有答案