1.因需要用cmake对opencv源码进行编译,详细配置参考Clion+Opencv3.2终极配置教程。因为下载回来的opencv中的build文件夹中都是专用于特定版本的vs,不适用于clion;
步骤1可能出现的问题:
1)cmake要有MinGW Makefiles,没有的重新安装最新版cmake。
2)注意opencv2.4用的是mingw-64的6.4版本。(我只试过8.x版本是不适用opencv2.4,只挑选了6.4版本是运行成功,其他低版本可以自行尝试)
3)如果以下8线程编译时出错,把8线程去掉以单线程编译。
mingw32-make -j8 # 以8线程进行编译
2.配置环境变量:
![环境配置](https://i-blog.csdnimg.cn/blog_migrate/b8c8d4fd72625e0687d4779e886ecd66.png)
3.配置c++项目中的CMakeLists.txt:
#cmake verson,指定cmake版本
cmake_minimum_required(VERSION 3.10)
#project name,指定项目的名称,一般和项目的文件夹名称对应
project(testa)
# c++11 required
set(CMAKE_CXX_STANDARD 11)
#添加c++11标准支持
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
# Where to find CMake modules and OpenCV
set(OpenCV_DIR "D:\\Program Files\\opencv\\mingw-build\\install")
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/")
#找到后面需要库和头文件的包
find_package(OpenCV REQUIRED)
#add executable file,添加要编译的可执行文件
add_executable(testa ExtractMain.cpp extractTable.hpp extractTable.cpp)
# add libs you need
set(OpenCV_LIBS opencv_core opencv_imgproc opencv_highgui)
#这个添加可执行文件所需的库(一般就是刚刚生成的工程的库),比如我们用到了libm.so(命名规则:lib+name+so),就添加该库的名称"m"
target_link_libraries(testa ${OpenCV_LIBS} )
4.异常处理,本次出现以下异常:
参考:OPENCV编辑问题汇总
异常情况1:
使用cmake发布makefile的时候,请禁用BUILD_TESTS,否则将在42%左右报以下错误:
G:\Coding\MinGW\msys\1.0\home\Administrator\opencv-3.2.0\modules\ts\src\ts_gtest.cpp: In constructor 'testing::internal::Mutex::Mutex()':
G:\Coding\MinGW\msys\1.0\home\Administrator\opencv-3.2.0\modules\ts\src\ts_gtest.cpp:8829:45: error: cannot convert 'CRITICAL_SECTION* {aka _CRITICAL_SECTION*}' to '_RTL_CRITICAL_SECTION*' in initialization
critical_section_(new CRITICAL_SECTION) {
^
G:\Coding\MinGW\msys\1.0\home\Administrator\opencv-3.2.0\modules\ts\src\ts_gtest.cpp:8830:48: error: cannot convert '_RTL_CRITICAL_SECTION*' to 'LPCRITICAL_SECTION {aka _CRITICAL_SECTION*}' for argument '1' to 'void InitializeCriticalSection(LPCRITICAL_SECTION)'
::InitializeCriticalSection(critical_section_);
^
G:\Coding\MinGW\msys\1.0\home\Administrator\opencv-3.2.0\modules\ts\src\ts_gtest.cpp: In destructor 'testing::internal::Mutex::~Mutex()':
G:\Coding\MinGW\msys\1.0\home\Administrator\opencv-3.2.0\modules\ts\src\ts_gtest.cpp:8840:46: error: cannot convert '_RTL_CRITICAL_SECTION*' to 'PCRITICAL_SECTION {aka _CRITICAL_SECTION*}' for argument '1' to 'void DeleteCriticalSection(PCRITICAL_SECTION)'
::DeleteCriticalSection(critical_section_);
^
G:\Coding\MinGW\msys\1.0\home\Administrator\opencv-3.2.0\modules\ts\src\ts_gtest.cpp: In member function 'void testing::internal::Mutex::Lock()':
G:\Coding\MinGW\msys\1.0\home\Administrator\opencv-3.2.0\modules\ts\src\ts_gtest.cpp:8848:43: error: cannot convert '_RTL_CRITICAL_SECTION*' to 'LPCRITICAL_SECTION {aka _CRITICAL_SECTION*}' for argument '1' to 'void EnterCriticalSection(LPCRITICAL_SECTION)'
::EnterCriticalSection(critical_section_);
^
G:\Coding\MinGW\msys\1.0\home\Administrator\opencv-3.2.0\modules\ts\src\ts_gtest.cpp: In member function 'void testing::internal::Mutex::Unlock()':
G:\Coding\MinGW\msys\1.0\home\Administrator\opencv-3.2.0\modules\ts\src\ts_gtest.cpp:8858:43: error: cannot convert '_RTL_CRITICAL_SECTION*' to 'LPCRITICAL_SECTION {aka _CRITICAL_SECTION*}' for argument '1' to 'void LeaveCriticalSection(LPCRITICAL_SECTION)'
::LeaveCriticalSection(critical_section_);
^
G:\Coding\MinGW\msys\1.0\home\Administrator\opencv-3.2.0\modules\ts\src\ts_gtest.cpp: In member function 'void testing::internal::Mutex::ThreadSafeLazyInit()':
G:\Coding\MinGW\msys\1.0\home\Administrator\opencv-3.2.0\modules\ts\src\ts_gtest.cpp:8879:33: error: cannot convert 'CRITICAL_SECTION* {aka _CRITICAL_SECTION*}' to '_RTL_CRITICAL_SECTION*' in assignment
critical_section_ = new CRITICAL_SECTION;
^~~~~~~~~~~~~~~~
G:\Coding\MinGW\msys\1.0\home\Administrator\opencv-3.2.0\modules\ts\src\ts_gtest.cpp:8880:54: error: cannot convert '_RTL_CRITICAL_SECTION*' to 'LPCRITICAL_SECTION {aka _CRITICAL_SECTION*}' for argument '1' to 'void InitializeCriticalSection(LPCRITICAL_SECTION)'
::InitializeCriticalSection(critical_section_);
^
modules\ts\CMakeFiles\opencv_ts.dir\build.make:237: recipe for target 'modules/ts/CMakeFiles/opencv_ts.dir/src/ts_gtest.cpp.obj' failed
mingw32-make[2]: *** [modules/ts/CMakeFiles/opencv_ts.dir/src/ts_gtest.cpp.obj] Error 1
CMakeFiles\Makefile2:5379: recipe for target 'modules/ts/CMakeFiles/opencv_ts.dir/all' failed
mingw32-make[1]: *** [modules/ts/CMakeFiles/opencv_ts.dir/all] Error 2
Makefile:161: recipe for target 'all' failed
mingw32-make: *** [all] Error 2
异常情况2:
参考:openCV mingw+cmake编译的bug/error笔记
C:\opencv\sources\modules\highgui\src\window_w32.cpp: In function 'int icvCreateTrackbar(const char*, const char*, int*, int, CvTrackbarCallback, CvTrackbarCallback2, void*)':
C:\opencv\sources\modules\highgui\src\window_w32.cpp:1853:81: error: 'BTNS_AUTOSIZE' was not declared in this scope
WS_CHILD | CCS_TOP | TBSTYLE_WRAPABLE | BTNS_AUTOSIZE | BTNS_BUTTON,
^
C:\opencv\sources\modules\highgui\src\window_w32.cpp:1853:97: error: 'BTNS_BUTTON' was not declared in this scope
WS_CHILD | CCS_TOP | TBSTYLE_WRAPABLE | BTNS_AUTOSIZE | BTNS_BUTTON,
^
modules\highgui\CMakeFiles\opencv_highgui.dir\build.make:187: recipe for target 'modules/highgui/CMakeFiles/opencv_highgui.dir/src/window_w32.cpp.obj' failed
mingw32-make[2]: *** [modules/highgui/CMakeFiles/opencv_highgui.dir/src/window_w32.cpp.obj] Error 1
CMakeFiles\Makefile2:2198: recipe for target 'modules/highgui/CMakeFiles/opencv_highgui.dir/all' failed
mingw32-make[1]: *** [modules/highgui/CMakeFiles/opencv_highgui.dir/all] Error 2
Makefile:159: recipe for target 'all' failed
mingw32-make: *** [all] Error 2
处理:主要就是有几个变量没有找到,后来在一个opencv的issues里找到了解答,大概意思就是在mingw的头文件commctrl.h中,对于上面的变量宏的定义实际上是由_WIN32_IE是否定义来决定的,找到MingW\include\commctrl.h文件却发现,他的写法竟然是直接#if 0,问题很明显,这这个宏在原始状态是关闭的,把下面#if 0改成#if 1和0x0500就行了
#include <prsht.h> #ifdef __cplusplus extern "C" { #endif #ifndef _WIN32_IE /* define _WIN32_IE if you really want it */ #if 0 #define _WIN32_IE 0x0300 #endif #endif