我可以用 C 包装 OpenCV 的 C++ 接口,然后用 Lisp 的 CFFI 包装它吗?

Posted

技术标签:

【中文标题】我可以用 C 包装 OpenCV 的 C++ 接口,然后用 Lisp 的 CFFI 包装它吗?【英文标题】:Can I wrap OpenCV's C++ interface with C and then wrap that with Lisp's CFFI? 【发布时间】:2013-09-27 04:33:56 【问题描述】:

我还想知道是否可以将 OpenCV 的 C++ 接口包装在 C 中,然后将其包装在 Lisp 中,这样我就可以将所有 C++ 功能也添加到我的 cl-opencv 包装器中,因为我想让它完整...... . 还想知道我是否这样做,我可以在 lisp 中将 C++ 包装器与 C 包装器一起使用 ....如果您可以向我展示一个快速示例程序,例如打开的窗口并显示图片功能,仅在c 和 c++ 一起......就像使用 cv::namedWindow 而不是 cvNamedWindow 而所有其他部分都是 c ......这是我尝试下面的程序在我只使用 cv::namedWindow 时运行但失败

 shape.cpp:37:32: error: invalid initialization of 
 reference of type ‘cv::InputArray aka const cv::_InputArray&’
  from expression of type ‘IplImage* aka _IplImage*’In file included from 
 /usr/local/include/opencv/highgui.h:48:0,

                   from shape.cpp:4:
 /usr/local/include/opencv2/highgui/highgui.hpp:78:19: error: 
 in passing argument 2 of ‘void cv::imshow(const string&, cv::InputArray)’
 Compilation exited abnormally with code 1 at Thu Sep 26 21:18:00

当我添加 cv::imshow

  #include <cv.h>
  #include <highgui.h>
  using namespace std;


  int main()
        CvCapture* capture =0;       

        capture = cvCaptureFromCAM(0);
        if(!capture)
  printf("Capture failure\n");
  return -1;
        

        IplImage* frame=0;


        cv::namedWindow("Video");



   // cout << "colorModel = " << endl << " " << size << endl << endl;


   while(true)

              frame = cvQueryFrame(capture);           
              if(!frame) break;

              frame=cvCloneImage(frame);




          cv::imshow("Video", frame );


              cvReleaseImage(&frame);

              //Wait 50mS
              int c = cvWaitKey(10);
              //If 'ESC' is pressed, break the loop
              if((char)c==27 ) break;      
        

        cvDestroyAllWindows() ;
        cvReleaseCapture(&capture);     

        return 0;
  

我想知道它是否可行......就像在我开始之前 100% 确定,我至少可以将每个 c++ 函数包装在 c 中并用 lisp 包装......或者如果你认为 id run在某些地方甚至是不可能的地方陷入障碍……而且还会将其包裹两次使其变慢吗?并且 id c 接口比 c++ 更好/更差..或者我可以在 c 接口中完成我在 c++ 中可以做到的所有事情

我问这个是因为在 swig 和 cffi 文档中它说 c++ 支持不完整。

哦,是的,我还尝试使用所有这些标头运行上述代码

#include <cv.h>
#include <highgui.h>
#include "opencv2/highgui/highgui.hpp"
#include <iostream>

using namespace cv;
using namespace std;

仍然出现上述错误

【问题讨论】:

这只是一个猜测,我从来没有这样做过。我听说用 Lisp 包装 C++ 代码是可能的,而且这是一项非常困难的任务,当然不是直截了当的。我的另一个猜测是尝试什么,我会研究 extern "C" ... 声明,也许从那里开始工作,尽管这真的只是直觉。 【参考方案1】:

来自the OpenCV documentation,InputArray

可以从 Mat、Mat_、Matx、std::vector、std::vector > 或 std::vector 构造的类。它也可以由矩阵表达式构造。

您正在尝试传递IplImage,其中需要InputArray,这是不允许的。 你可以使用

cvShowImage("Video", frame);

或者将您的 IplImage 转换为 Mat 并将其传递给 imshow()

IplImage* frame;
// write to frame
...
// convert to cv::Mat and show the converted image
cv::Mat mat_frame(frame);
cv::imshow("Video", mat_frame)

完全不使用 IplImage 更好,它是遗留 API 的一部分。垫子是首选。

cv::VideoCapture capture;
capture.open(0);
cv::Mat frame;
cv::namedWindow("Video");

if (capture.isOpened()) 
   while (true) 
       capture >> frame;
       if (!frame.empty()) 
           cv::imshow("Video", frame);

           int c = cv::waitKey(10);
           if ((char) c == 27) 
               break;
           
       
    

理论上,您可以为所有内容编写包装器以允许从 Lisp CFFI 调用,但这可能不值得花时间和痛苦。我会用 C++ 编写应用程序的 OpenCV 部分,然后使用 C/CFFI 从 Lisp 调用它。

【讨论】:

嘿,这也是我的昵称...我喜欢在 lisp 中编写所有代码,所以我必须将所有 opencv(因为它是最好的)转换为 lisp 但如果我决定“为所有内容编写包装器以允许从 Lisp CFFI 调用”是否会降低包装两次的速度......并且对于 opencv,c 是否与 c++ 一样好,或者我是否会从尝试包装 c++ 中受益 速度下降可能没什么大不了的。 C api 中的许多函数已经是 C++ API 的包装器。好吧,你喜欢 Lisp,但你可能会花更多的时间用 C/C++ 编写包装器,这样你就可以使用 Lisp,而不是一开始就用 C++ 编写应用程序。 感谢有关速度的信息...是的,我也喜欢包装...喜欢它的骇人听闻

以上是关于我可以用 C 包装 OpenCV 的 C++ 接口,然后用 Lisp 的 CFFI 包装它吗?的主要内容,如果未能解决你的问题,请参考以下文章

如何创建一个.so 文件,其中仅包含用 C 代码包装的 C++ 代码 - OpenCV 相关?

C++ - 错误:为 OpenCV 的 cv::Scalar::all 创建 C 包装器时出现预期的类型说明符

OpenCv c++ 为基本打印垫功能创建一个 C 包装器?

为 OpenCV 的 C++ createTrackbar 运行 C 包装器时出现编译分段错误(核心转储)

包装 OpenCV C++ 以与 C# 一起使用

为python(使用opencv)包装c ++类,给出错误