MacOS 配置支持OpenGL的OpenCV

启用OpenCV中的OpenGL支持

最近计算机视觉的作业要弄AR,因此一些3D图形的渲染与绘制就要用到OpenGL。但是Homebrew安装的OepnCV默认是不开启WITH_OPENGL选项的,因此就需要下载源码然后手动安装。

下载源码

这里就听老师的,下载的是OpenCV2.4.13.6版本。

不知为何官网Releases下的源码下载总是下到一半就中断,因此就在官方的Github仓库里下载压缩包。下载链接

下载好源码后将其解压放置在电脑的个人目录下,准备开始CMake。

下载QT

MacOS上启用OpenGL支持最坑的一点就是,必须联合QT一起编译才能正确启用OpenGL。因此必须预先下载并安装好QT。可以使用Homebrew安装,不过我是通过官网下载的Qt5。
P.S. 在网上看了好多博客,然后老师给的代码里的README也说必须要下载Qt4才行。但是我之前已经装好Qt5了,实在不想删掉再弄个Qt4。因此就头铁继续干了。

利用CMake配置编译选项

  • 首先在源码所在的同级目录下新创建一个build文件夹。

  • 勾选上WITH_QT和WITH_OPENGL后点击configure。
    Config Cmake
    点完之后会报出几个错误,显示关于Qt5的几个路径无法找到,查了半天终于找到以下解决方法。

  • 找到build文件夹下的CMakeCache文件,打开文件并找到所有关于Qt5的代码,将其中的路径替换成如下图所示:
    CMakeCache

  • 更改完后保存,重新configure,发现之前的错误都没有了,然后点击generate。

在命令行中编译

  • 跳转到build文件夹所在路径,然后执行sudo make指令。
    编译的过程中,在编译到highgui模块时,会报错并终止编译。错误信息大致就像以下这样

error: ‘CODEC_FLAG_GLOBAL_HEADER’ was not declared in this scope

error: ‘AVFMT_RAWPICTURE’ was not declared in this scope

error: ‘CODEC_FLAG_GLOBAL_HEADER’ was not declared in this scope

for target ‘modules/highgui/CMakeFiles/opencv_highgui.dir/src/cap_ffmpeg.cpp.o’ failed
make[2]: [modules/highgui/CMakeFiles/opencv_highgui.dir/src/cap_ffmpeg.cpp.o] Error 1

这是因为FFMPEG与OpenCV的版本产生了冲突,两者是分别开发的,因此在编译本版本的OpenCV时使用的FFMPEG并不是此时使用的这个库。所以想要尝试下载不同版本的FFMPEG来匹配,直到在stackoverflow上看到了一位大佬的解决方法。总结来讲就是将以下这三个宏定义复制到cap_ffmpeg_impl.hpp这个头文件的开头即可。

1
2
3
#define AV_CODEC_FLAG_GLOBAL_HEADER (1 << 22)
#define CODEC_FLAG_GLOBAL_HEADER AV_CODEC_FLAG_GLOBAL_HEADER
#define AVFMT_RAWPICTURE 0x0020
  • 重新执行sudo make指令,之后的编译就都正常进行了
  • 最后zhi xingsudo make install,所有的头文件和库文件就都安装在/usr/local/include/usr/local/lib路径下了。编译工作大功告成

配置Xcode

与之前配置OpenCV项目一样,唯一需要注意的一点就是在链接库文件进项目里时,不要将cv2.so这个文件链接进去。之前无脑全选链接进去的时候,总是会在编译时报错,后来发现是这个鬼。

测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <opencv2/opencv.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>
#include <string>
#include <OpenGL/gl.h>

using namespace cv;
using namespace std;

void onDraw(void* param)
{
glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);

glColor3f(1.0f, 0.0f, 0.0f);
glRectf(-0.5f, -0.5f, 0.5f, 0.5f);
glFlush();
}

int main()
{
string openGLWindowName = "OpenGLDemo";
namedWindow(openGLWindowName, WINDOW_OPENGL);
resizeWindow(openGLWindowName, 640, 480);
setOpenGlContext(openGLWindowName);
setOpenGlDrawCallback(openGLWindowName, onDraw, NULL);

waitKey(0);
updateWindow(openGLWindowName);
waitKey(0);
return 0;
}

如果能正确编译上述代码,就证明以正确开启openGL支持,并会看到以下结果:

result