Windows使用MinGW跨平台编译裁剪OpenCV

2017/11/03 开源库

使用MinGW进行跨平台编译 OpenCV,这样编译出的静态库可以在任意平台下运行.

鉴于 OpenCV 模块较多,本次只编译最为基础的模块,其他模块暂时用不到.

  • core模块
  • imgproc模块

环境说明

OS:windows7 64b
Qt:5.7.0
MinGW:53032
CMake:3.10.0-rc-w64

全部编译

因为opencv模块比较多,如今3.3版本包含的更多了。模块化带了的好处就是我们可以自己编译需要的模块, 这个和Qt刚好类似,给我们开发者带来了极大的好处和方便。

使用 minGW 编译完成后最终生成了如下文件:

裁剪编译

因为本次只编译coreimgproc两大模块,所以只需要这两大模块源码即可.

编译配置工作全部在 windows 下进行,等windows下编译成功后在编译其他平台下.

windows平台配置

工程配置结构:

以下会记录一些编译过程中遇到的问题以及解决办法:

编译 core 模块

core模块编译过程中也是遇到了一些问题,大部分记录了下来,详细在后面问题记录里面

core模块编译时需要依赖opencv编译后生成的头文件,所以在编译模块化时需要提前将源码整体编译一遍,注意编译器版本、opencv版本对应。

错误

  • 找不到cvconfig.h

找不到配置头文件

需要到opencv工程里找对应的cvconfig.h,具体位置在opencv/build/include/opencv2

  • 找不到 opencl_kernels_imgproc.hpp

解决办法

查找该文件在哪里:build_mingw53_32\modules\imgproc

很奇怪,这个文件是之前我全部编译opencv后,生成的文件,而这里单独编译时需要这个文件, 仔细想应该是编译中某些开关设置没有打开或关闭吧。

opencl_kernels_imgproc.hpp该文件是编译后生成的,这里将该文件拷贝到了工程目录下,然后添加包含路径:

#build file
INCLUDEPATH +=$$PWD/../build_file/imgproc

添加后再次编译,通过了,生了了静态库,貌似有点大22.3M(debug)

编译后的静态库

  • 找不到OCL_PERFORMANCE_CHECK定义了

这个是个宏定义开关HAVE_OPENCL

  • __OPENCV_BUILD问题
 error this is a private header which should not be used from outside of the OpenCV library
``

**解决办法**
Google解决:一个朋友说是直接删除掉.....暂且不注释,添加宏定义好了.
![](/res/img/blog/3rdparty/opencv/opencv_build_q.png)

[解决方案地址](http://answers.opencv.org/question/79178/error-compiling-traincascade-in-opencv-30/)

- 类型出现问题

```C++
Opencv\core\src\glob.cpp:117: error: cannot convert 'WIN32_FIND_DATA*
{aka _WIN32_FIND_DATAW*}' to 'LPWIN32_FIND_DATAA {aka _WIN32_FIND_DATAA*}'
 for argument '2' to 'WINBOOL FindNextFileA(HANDLE, LPWIN32_FIND_DATAA)'
             if (::FindNextFileA(dir->handle, &dir->data) != TRUE)

解决办法

Google了下,这个问题是编码问题造成了,需要把自己电脑的编码转为Unicode编码才行,但是为了统一工程编码结构,显然这样不行,所以自己添加了一个编码定义头文件

#ifndef CODEDEF_H
#define CODEDEF_H

#ifndef UNICODE
#define UNICODE
#define UNICODE_WAS_UNDEFINED
#endif

#ifdef Q_OS_WIN
#include <Windows.h>

#endif

#ifdef UNICODE_WAS_UNDEFINED
#undef UNICODE
#endif

#define WINRT

#endif // CODEDEF_H

然后再core模块中将该头文件包含进去即可解决.

上述解决方案其实多此一举了,直接在cvconfig.h文件中添加WINRT宏定义即可

cvconfig.h中定义了好多模块编译的开关.

编译imgproc模块

imgproc模块依赖于core模块,所以需要将core模块头文件、静态库(上一步编译好的)包含进来.

添加core模块包含路径,然后接着编译

错误

和编译core模块类似,出现了找不到opencl_kernels_imgproc.hpp文件,同样该文件是编译opencv源码后生成的,此处需要拷贝过来,然后添加包含路径:

编译错误

接着进行编译,约1分钟编译ok了.

测试

测试工程添加包含路径,和库路径:

引入静态库路径

在main函数文件中引入时出现了链接错误,意思是找不到某些函数方法的实现了,即找不到.cpp文件实现了,这说明上一步生成的静态库中缺少某些函数的实现,静态库编译不正确,重新编译.

测试错误

需要添加zlib支持

进到该函数中,可以看到,跑到了mingw32自带的zlib库中了。

  • 编译zlib库

此时需要下载第三方的zlib库.

网上查找说是opencv使用自带的zlib会和开发过程中使用的zlib冲突,最好都使用第三方的库.

zlib库很好编译,直接添加到Qt子工程中即可,设置目标target和templete。

很是奇怪的问题,zlibi已经编译成功了,而且已经添加到了core模块子工程配置中,但是最后程序链接时提示还是找不到某些zlib方法

解决方案 既然将zlib编译成静态库无法连接,那么就直接将zlib源码包含进来好了,和core模块一起编译算了,修改后终于编译成功了,最后连接成功了.

编译imgcodecs模块

编译imgcodecs模块是为了编译higugui模块,后者依赖于前者,所以需要提前编译,测试发现,imgcoedcs模块依赖于imgproc模块,刚好该模块在上一步编译过了.

直接拷贝到当前工程下,配置到pro中,参数按照上2个模块配置方法,编译.

出现错误:

  • 找不到ImfHeader.h文件

该文件是属于openexr开源库,是视觉效果行业使用的一种文件格式,适用于高动态范围图像.

出现静态库无法连接问题

  • 问题描述:imgcoedcs模块依赖tiff库,已经将tiff编译成静态库了,并在imgcoedcs工程中引入了对应的头文件和库路径,在最后连接过程中无法找到……

编译highgui模块

higugui模块依赖于imgcodecs模块,所以要先编译该模块.

还依赖 videoio 模块。

……未完(有时间再研究)

android 平台编译

android 平台编译前需要配置好环境变量,以下是我的环境变量:

android平台环境参数

设置好编译环境后,添加宏定义,以便区分编译后的文件:

android平台编译宏定义

然后直接编译,大约5分钟左右,编译完成,没有出现错误,很幸运.

最终生成的库文件:

android平台编译生成库文件


Linux 平台编译

这里就不贴图了,经过测试linux顺利编译通过,太棒了!

Qt Creator 是在是太棒了,按照不同平台配置好后即可编译,不用担心其他问题了!


ios平台编译

配置好Qt for ios环境。以下是我编译时配置的环境.

ios平台环境参数

基本编译也是没有问题的,最终生成了两个模块对应的库文件:

core模块

ios平台生成的库文件

imgproc模块

ios平台生成的库文件

比较发现,同样的模块,在不同平台下编译出来大小不一样,差距还是很大的.

问题与展望

目前关于opencv这块相关模块参数配置项都在cvconfig.h中,可以考虑将其容纳到工程pro文件中,这样修改时直接修改工程文件即可,带来更大的方便.

版本修改

  • V0.0.1 添加了可以编译成功的core、imgproc两个模块,成功编译成静态库;
  • V0.0.2 成功静态编译core模块;
  • V0.0.3 成功静态编译imgProc模块;
  • V0.0.5 编写测试demo,检测静态编译两大模块OK;
  • V0.0.6 在android平台成功编译成功两大模块;
  • V0.0.7 在ios平台成功编译两大模块;

本博客的文章标有 原创 标签都属于作者原创文章,欢迎大家转载分享。 但是,希望您注明来源,并留下原文地址,这是对作者最大的尊重,也是对知识的尊重。

Show Disqus Comments

Search

    欢迎关注我的微信号

    一个不羁的码农

    不羁的程序员

    转载请注明出处!

    Table of Contents