我想在gtkmm编写的GUI中显示一个cv::Mat。所以我做了一个测试。
我有一个小部件Gtk::Image image
,我想用以下两种方法设置图像:
// first method, display from file
void displayImage1()
{
Glib::RefPtr<Gdk::Pixbuf> pixbuf = Gdk::Pixbuf::create_from_file("gtk.png");
image.set(pixbuf);
}
// second method, display from cv::Mat
void displayImage2()
{
cv::Mat outImage = cv::imread("gtk.png");
cv::cvtColor(outImage, outImage, CV_BGR2RGB);
Glib::RefPtr<Gdk::Pixbuf> pixbuf = Gdk::Pixbuf::create_from_data(outImage.data, Gdk::COLORSPACE_RGB,false, 8, outImage.cols, outImage.rows, outImage.step);
image.set(pixbuf);
}
第一种方法效果很好。
然而,第二种方法不太好用,我在屏幕上得到了一个被破坏的图像,如图所示。
如果我将has_alpha参数设置为true,结果也很奇怪(见下图)。
使用Gtk::DrawingArea进行了类似的测试。使用了不同的IDE(但所有的g++编译器都在linux下)。所有结果都相同。
更新:
我测试了很多图像。有时图像坏了,有时程序崩溃了
程序意外结束。
8条答案
按热度按时间0s7z1bwu1#
对于Gtkmm-2.4和OpenCv 4.6,检查https://onthim.blogspot.com/2015/10/using-opencv-in-gtk-applications.html和https://developer-old.gnome.org/gtkmm-tutorial/2.24/sec-draw-images.html.es
ycggw6v22#
通常,这种“破碎”的形象会在我的脑海中触发一个警告:“wrong rawstride!"。
Gdk::Pixbuf
中的rawstride在一行数据的字节长度中。这是因为您可能有一些字节对齐约束,因此在一行的末尾可能有一些填充。我检查了这个
step
参数是什么,是的,这在OpenCV中与Gdk::Pixbuf中的rawstride相同。直到我意识到outImage.step
是一个cv:MatStep
对象,而Gdk::Pixbuf::create_from_data
需要一个int。我认为你应该使用outImage.step[0]
。请阅读https://docs.opencv.org/2.4/modules/core/doc/basic_structures.html#mat
bkkx9g8r3#
我们开始吧:
guykilcj4#
这就是我所做的,它显示了良好的效果图像显示
2jcobegt5#
所以我测试了这个(add scale_simple),结果很成功:
From:http://orobotp.blogspot.com/2014/01/opencv-with-gtkmm3.html
版本:Gtkmm 3.22.2-2,OpenCV 4.4.0-开发版本,g++ 7.5.0
rbpvctlc6#
IMO,正如@三木在评论中所建议的那样,这只是一个终身问题。
我遇到了同样的问题,类似的代码:
上面的代码段根本不起作用(或者间歇性地起作用),因为引用
gdk_pixbuf_new_from_data
documentation,“数据由函数的调用者拥有”。问题是在渲染图像的时候,
rgb
已经被破坏了。在pixbuf
赋值之前添加一个rgb.addref()
可以解决这个问题,尽管会引入内存泄漏。一种解决方案是利用destroy回调取消引用
Mat
对象,例如:oewdyzsn7#
尝试添加对outimage的引用,如outimage.addref()。我所有的问题都与此有关。在gdk_pixbuf_new_from_data有机会Map它之前,源图像被取消引用。导致segfaults,corruption等。请确保稍后释放它,或使用gdk_pixbuf_new_from_data提供的回调
3j86kqsm8#
cv::MatoutImage会在执行超出函数displayImage2()的作用域时被破坏,因此您应该在您的自定义类中声明变量outImage,该自定义类派生自Gtk::Window。下面是一个使用gtkmm4和opencv4的示例: