记录一次关于OpenCV的CmakeLists的探索

wonner 2020-05-07

       编写基于OpenCV的图像处理程序,其中很重要的一道门槛就是编译OpenCV,应该说如果你对其中的内容如果不是很熟悉的话,即使是最简单粗暴的“两次configure,一次generate”都可能会出现各种错误;对于我来说,之前也是停留在能够编译、会解决一些问题阶段,直到前一段时间我需要研究《基于pybind11实现Python调用c++编写的CV算法--下(Linux+Cmake)》的过程中,因为这个方面的资料非常难找,没有办法必须对cmake有深入认识,才进行了系统研究。
       这个时候,当我重新Cmake的时候,发现很多有趣的东西。这里一起来分享我的发现,相信对于大家理解这方面内容会有帮助。
一、基本情况
       下载下来的源代码解压以后是这个样子的
记录一次关于OpenCV的CmakeLists的探索
你会看到那个非常明显的CMakeLists.txt。实际上,所有的Cmake文件都叫这个名字。打开以后,会发现里面没什么东西:
其实这里都是各种各样奇怪的宏,如果我们在opencv的文件夹下搜索"CMakeLists.txt",会发现有很多。
因为CmakeList都是级联存在的。我们可以使用CMkae_gui直接打开根目录,它会将这里级联的内容解析出来。
那么所谓的“两次configure,一次generate”,就是这里的1、2、3、4,第一次Configure是让cmake_gui把这里级联的内容都出来,然后你打勾进行选择,第二次Configure是把你选择的东西写进去,然后generate,然后OpenProject直接打开IDE,可以编译了,这个有经验的都知道。

二、发现的奇怪东西
     以前我也是无脑的直接编译生成的,但是由于有了pybind的经验,我就想看看OpenCV这个这么巨大的CmakeLists里面都是有些什么东西,一看就发现了一些奇怪的东西。
1、BUIILD_opencv_apps
一般意义上来说,都会理解apps是手机上的app,但是这个翻开来看以后是这样的:
基本上可以确定是示例程序之类,我觉得应该可以去掉,肯定是和手机没关系。

2、BUIILD_opencv_python3 和 BUIILD_opencv_python_bindings_generator 和 BUIILD_opencv_pythons_tests
这三个都是关于python的,我比较关心python_bindings_generator ,我认为这个东西会不会和前一段时间研究的pybind11有关系?有重复,查询相关资料,进一步明确。

 Steps for building the Python module

We are now ready to go over the steps for building our Python module.

  1. Step 1: Put your c++ source code and header files inside the src directory.
  2. Step 2: Include your header file in headers.txt
  3. Step 3: Make a build directory.
    <i><span>1</span><span>    mkdir build</span></i>

    Step 4: Use gen2.py to generate the Python binding files. You need to specify the prefix (pybv), the location of the temporary files (build) and the location of the header files (headers.txt).

    <i><span>1</span><span>    python3 gen2.py pybv build headers.txt</span></i>

    This should generate a whole bunch of header files with prefix pybv_*.h. If you are curious, feel free to inspect the generated files.

  4. Step 5: Compile the module
    <i><span>1</span><span>    g</span><span>++</span> <span>-</span><span>shared </span><span>-</span><span>rdynamic </span><span>-</span><span>g </span><span>-</span><span>O3 </span><span>-</span><span>Wall </span><span>-</span><span>fPIC \</span><br /><span>2</span><span>    bv.cpp src</span><span>/</span><span>bvmodule.cpp \</span><br /><span>3</span><span>    </span><span>-</span><span>DMODULE_STR</span><span>=</span><span>bv </span><span>-</span><span>DMODULE_PREFIX</span><span>=</span><span>pybv \</span><br /><span>4</span><span>    </span><span>-</span><span>DNDEBUG </span><span>-</span><span>DPY_MAJOR_VERSION</span><span>=</span><span>3</span><span> \</span><br /><span>5</span><span>    </span><span>`</span><span>pkg</span><span>-</span><span>config </span><span>--</span><span>cflags </span><span>--</span><span>libs opencv</span><span>`</span><span>  \</span><br /><span>6</span><span>    </span><span>`</span><span>python3</span><span>-</span><span>config </span><span>--</span><span>includes </span><span>--</span><span>ldflags</span><span>`</span><span> \</span><br /><span>7</span><span>    </span><span>-</span><span>I . </span><span>-</span><span>I</span><span>/</span><span>usr</span><span>/</span><span>local</span><span>/</span><span>lib</span><span>/</span><span>python3.</span><span>5</span><span>/</span><span>dist</span><span>-</span><span>packages</span><span>/</span><span>numpy</span><span>/</span><span>core</span><span>/</span><span>include \</span><br /><span>8</span><span>    </span><span>-</span><span>o build</span><span>/</span><span>bv.so  </span></i>


    In Line 2 we specify the source files. In Line 3, we set the module name using MODULE_STR and MODULE_PREFIX (pybv) used in the previous step. In Line 4 we specify the Python version. In Line 5 we include OpenCV library and the header files and in Line 6 we include Python 3 related header files and some standard libraries. In my machine, numpy was not in the included path and so I had to add an extra Line 7 for numpy. Your location for numpy may be different. Finally, in Line 8 we specify the location of the output module (build/bv.so).

       可以证明,在python中的cv2的确是采用翻译的方式,将其封装为python代码的的,这个也是完全没有问题的,如果是我来设计肯定也是这样。但是,这里OpenCV是站在代码库的立场上面,逐条翻译;而对于应用来说,采用打包翻译(三明治方法)效果更好,因此这里我认为BUIILD_opencv_python_bindings_generator的方法过于繁琐,相比较而言pybind11的方法更方便部署。

3、thunder
      thunder不是迅雷吗?难道OpenCV和它还有关系。怀着探究心态,不断挖掘,发现原来是这个东西:
很有可能进一步使这个东西
因为我给OpenCV投过代码,我知道它的代码审核、自动生成等是比较严格的。

三、我筛选的OpenCV_Cmake
      我记得上学的时候,老师经常会说“可以对Linux进行裁剪”,感觉这个是很高大上的一件事情,但是当然是不知道如何“裁剪”。实际上,OpenCV作为老牌开源项目,它这里这么多的BUILD选项,就是给你一个裁剪”的接口。你可以根据需要进行选择。
记录一次关于OpenCV的CmakeLists的探索
对于我来说,我最近一次编译Cmake是在写构建自己的专用OpenCV----一个由applyColorMap()引发的探索(上)》的时候发生的,因为我需要修改OpenCV的代码,实现一个它自己没有的applyColorMap色彩,所以需要编译OpenCV。
记录一次关于OpenCV的CmakeLists的探索
由于我知道applyColorMap属于imgproc,是比较基础的库,因此这里很多东西都没必要选择。这个时候,我对OpenCV的裁剪”是这样的
记录一次关于OpenCV的CmakeLists的探索
其中,我勇敢地去掉了BUILD_EXAMPLES、BUILD_opencv_dnn、BUILD_opencv_gapi、BUILD_opencv_java_*、BUILD_opencv_python_*、BUILD_opencv_video*等这些我很明确用不着的东西,对于BUILD_opencv_apps之类搞不清楚的东西进行了保留,特别是添加了BUILD_opencv_world,这样可以生成一个dll,免得添加麻烦。
记录一次关于OpenCV的CmakeLists的探索
最后的结果是29个项目,可能还能够再去掉一些,但是没有继续尝试,这样的话每次编译,速度都比较快。

四、参考资料






相关推荐

greent00 / 0评论 2020-05-29