OpenCV - 从 C/C++ 中的默认网络摄像头获取图片 - GTK 问题

Posted

技术标签:

【中文标题】OpenCV - 从 C/C++ 中的默认网络摄像头获取图片 - GTK 问题【英文标题】:OpenCV - Getting picture from default webcam in C/C++ - GTK Issues 【发布时间】:2014-02-26 01:35:18 【问题描述】:

我有一个简单的 GTK+ v3 GUI 应用程序,我正在使用 OpenCV 库,以便我有一个简单的功能,可以从连接到我的计算机的一个网络摄像头拍照。代码包含在这篇文章的底部。

我能够成功获取图像数据并将其呈现在屏幕上,但是当我将此代码包含在我的 GTK+ v3 项目中时,我收到如下启动错误:

(result:2944): Gtk-ERROR **: GTK+ 2.x symbols detected.
Using GTK+ 2.x and GTK+3 in the same process is not supported.
Trace/breakpoint trap.

所以,到目前为止,这是有道理的。 OpenCV 库之一显然使用了 Gtk+ v2。事实证明,如果我从要链接的库列表中删除 libopencv_highgui,我就不会有这个问题。但是,出于某种原因,用于从网络摄像头获取图像数据的函数包含在该库中。

是否有其他功能可以通过 CC++ OpenCV API 访问,不需要我使用 libopencv_highgui 并允许我轻松地从网络摄像头拍摄快照?

另一种选择似乎是将我的项目重写为 Gtk+ v2 应用程序,这不会那么糟糕,因为我还没有走得太远。

那里有隐藏选项C 吗? (请原谅双关语;))。

#include <opencv2/objdetect/objdetect.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

#include <iostream>
#include <stdio.h>
#include <errno.h>

using namespace std;
using namespace cv;

#define PROJECT_NAME       "CAMERA_MODULE" // Include before liblog
#include "../../lib/liblog/inc/log.h"

int cameraAcquireImage(void) 
   CvCapture* capture = 0;
   Mat frame, frameCopy, image;

   //0=default, -1=any camera, 1..99=your camera
   capture = cvCaptureFromCAM(CV_CAP_ANY);
   if(!capture) 
      logError("No camera interface detected");
      return (-EIO);
   

   cvNamedWindow( "result", CV_WINDOW_AUTOSIZE );
   if(capture) 
      logError("Capture in progress");
      for( ; ;) 
         IplImage* iplImg = cvQueryFrame(capture);
         frame = iplImg;

         if(frame.empty()) 
            break;
         
         if(iplImg->origin == IPL_ORIGIN_TL) 
            frame.copyTo(frameCopy);
          else 
            flip(frame, frameCopy, 0);
         
         cvShowImage( "result", iplImg );
         if( waitKey( 10 ) >= 0 ) 
            break;
         

      
   

   cvReleaseCapture( &capture );
   cvDestroyWindow("result");
   return 0;

【问题讨论】:

你用的是什么平台? 我正在使用 Ubuntu 12.04 为 Raspian Wheezy 上的 RPI 进行交叉编译。构建使用标准 GNU makefile 而不是 CMake、Autotools 或类似文件。 替代方法:使用github.com/ktossell/libuvc和gtk3,只需在注册到libuvc的回调中绘制视频帧。在该回调中,将像素数据绘制到所需的 cairo 上下文cairo_t(即在中间缓冲区中绘制,在绘制事件时交换缓冲区)。只是一个想法...... 【参考方案1】:

我可以想到以下解决方案:

    降级到 GTK 2 - 非常简单。

    由于 VideoCapture 是极少数依赖于 highgui,使用其他东西进行视频捕获(可能是 Video4Linux) 然后使用不依赖highgui的OpenCV模块。

    构建支持 GTK 3 的 OpenCV (WITH_GTK=ONWITH_GTK3=ON)。

    如果可以,请使用 Qt 而不是 GTK。

【讨论】:

我最终降级到 GTK2。它实际上比我最终想象的要简单。我遇到的问题及其解决方法在***.com/questions/22030177/…讨论 降级是简单而糟糕的解决方案。您应该为现在和未来编写新的应用程序,而不是为过去编写。想象一下,您遇到了一个 GTK+ 2.0 阻塞错误,您将没有机会修复它,因为该版本将不会被维护。我在 2014 年可能不是这样,但 GTK+ 3 已在 2011 年发布,GTK+ 4 开发开始(称为 3.9x 版本),可能会在 2019 年发布。GTK 3.22 将是最后一个维护的 GTK 3.x 版本.

以上是关于OpenCV - 从 C/C++ 中的默认网络摄像头获取图片 - GTK 问题的主要内容,如果未能解决你的问题,请参考以下文章

OpenCV 在不同线程上从网络摄像头运行视频

在 OpenCV C/C++ 中只过滤一个轮廓

OpenCv - 从网络摄像头捕获帧时发生内存泄漏

一次从 OpenCV 中的两个摄像头捕获视频

从保存的图像中预测情绪(OpenCV 网络摄像头)

提高 OpenCV 中的相机捕获分辨率