所以我正在尝试实现以下目的:为用户创建一个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窗口,然后无响应并写入图像,直到我取消该过程。
总结一下:
有没有一种方法可以在gtk中执行后台任务而不会使ui无响应
如何在gtk窗口/窗口小部件中显示opencv :: Mat?