• 使用CMake构建OpenCV项目


    这篇文章我们来对我们的安装进行测试,并介绍如何用CMake工具快捷地构建OpenCV项目。
    为了使整个项目更加条理,我们的文件夹采用如下组织方式:

    bin
    build
    CMakeLists.txt
    src

    其中bin目录用于放编译生成的可执行文件,build目录用于cmake构建项目,src用于放源代码。"CMakeLists.txt"这个名字,一个字都不能错。
    编写的OpenCV示例代码:
    #include <opencv2/core/core.hpp>
    #include <opencv2/highgui/highgui.hpp>
    #include <opencv2/imgproc/imgproc.hpp>
    #include <iostream>

    using namespace std;
    using namespace cv;

    int main(int argc, char** argv)
    {
        if (argc != 2)
        {
            cout << "Usage: opencv_test <image path>" << endl;
            return -1;
        }

        char *imgName = argv[1];
        Mat image;

        image = imread(imgName, 1);
        if (!image.data)
        {
            cout << "No image data" << endl;
            return -1;
        }
        Mat gray_img;

        cvtColor(image, gray_img, COLOR_BGR2GRAY);
       // imwrite("~/template/result.jpg", gray_img);
        imshow("gray",gray_img);
       cv::waitKey(0);

        return 0;
    }
    这是一个很简单的例子:读取图片然后转化成灰度图。取名为main.cpp。需要注意的是在没有“语法糖”的情况下编写代码非常困难,我选择首先在vs中编好,然后复制。

    CMake文件的文件名CMakeLists.txt有严格的大小写要求,注意不要写错。
    # project name
    PROJECT(opencv_test)
    # requirement of cmake version
    cmake_minimum_required(VERSION 3.5)

    # set the directory of executable files
    set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${opencv_test_SOURCE_DIR}/bin)

    # find required opencv
    find_package(OpenCV REQUIRED)
    # directory of opencv headers
    include_directories(${OpenCV_INCLUDE_DIRS})
    # name of executable file and path of source file
    add_executable(opencv_test src/opencv_test.cpp)
    # directory of opencv library
    link_directories(${OpenCV_LIBRARY_DIRS})
    # opencv libraries
    target_link_libraries(opencv_test ${OpenCV_LIBS})
    PROJECT指令的语法是:
    PROJECT(projectname [CXX] [C] [Java])
    你可以用这个指令定义工程名称,并可指定工程支持的语言,支持的语言列表是可以忽略的,这个指令隐式的定义了两个cmake变量:<projectname>_BINARY_DIR以及<projectname>_SOURCE_DIR。前者指构建路径,后者指工程路径,即CMakeLists.txt所在的路径。
    同时cmake系统也帮助我们预定义了PROJECT_BINARY_DIR和PROJECT_SOURCE_DIR变量,他们的值分别跟opencv_test_BINARY_DIR与opencv_test_SOURCE_DIR一致。【注意这里的许多约定,这个名字应该就是目录名称】
    为了统一起见,建议以后直接使用PROJECT_BINARY_DIR,PROJECT_SOURCE_DIR,即使修改了工程名称,也不会影响这两个变量。如果使用了<projectname>_SOURCE_DIR,修改工程名称后,需要同时修改这些变量。
    接下来是设置cmake要求的最低版本号:
    cmake_minimum_required(VERSION 3.5)
    SET指令的语法是:
    SET(VAR [VALUE] [CACHE TYPE DOCSTRING [FORCE]])
    现阶段,你只需要了解SET指令可以用来显式的定义变量即可。这里我们将变量CMAKE_RUNTIME_OUTPUT_DIRECTORY定义为${opencv_test_SOURCE_DIR}/bin也就是工程路径下的bin目录。
    下面介绍一个很重要的指令:find_package这个指令以被用来在系统中自动查找配置构建工程所需的程序库。在linux和unix类系统下这个命令尤其有用。CMake自带的模块文件里有大半是对各种常见开源库的find_package支持,支持库的种类非常多。
    当它找到OpenCV程序库之后,就会帮助我们预定义几个变量,OpenCV_FOUND、OpenCV_INCLUDE_DIRS、OpenCV_LIBRARY_DIRS、OpenCV_LIBRARIES,它们分别指是否找到OpenCV,OpenCV的头文件目录,OpenCV的库文件目录,OpenCV的所有库文件列表。接着我们就可以使用这些变量来配置了:
    include_directories(${OpenCV_INCLUDE_DIRS})
    这个指令用来设置包含的头文件的路径。
    link_directories(${OpenCV_LIBRARY_DIRS})
    这个指令用来设置库文件的路径。
    target_link_libraries(opencv_test ${OpenCV_LIBS})
    这个指令用来设置需要的库文件,它的语法是:
    TARGET_LINK_LIBRARIES(target library1<debug | optimized> library2...)
    其中的target就是前面设置生成的目标文件(可执行文件):
    add_executable(opencv_test src/opencv_test.cpp)
    这个命令很好理解,首先是可执行文件的名字,然后是源码的名字。因此,这个命令一定要在TARGET_LINK_LIBRARIES之前使用。
    现在我们的CMakeLists.txt就介绍完了。
    进入build目录,然后开始构建:
    cd build
    cmake ..
    因为CMakeLists.txt在buil的父目录中,因此make命令之后使用..。
    -- Configuring done
    -- Generating done
    -- Build files have been written to: /home/liuchaoyang/grad_proj/opencv_test/build
    这样就构建成功了,构建之后会生成很多文件,其中就有Makefile文件。
    然后编译生成可执行文件:
    make
    [ 50%] Building CXX object CMakeFiles/opencv_test.dir/src/opencv_test.cpp.o
    [100%] Linking CXX executable ../bin/opencv_test
    [100%] Built target opencv_test
    运行生成的可执行文件以测试我们是否成功,该程序需要传递一个命令行参数。下面是运行结果:
    这里非常神奇的就是CMake能够自动给你找到环境。那么也就是说当我们进行类库移植的时候,最好进行一次CMake和make ,看上去非常高级。
    总结:
    这几个标黄的地方,改成和目录名称一样,应该就可以了。




    附件列表

    • 相关阅读:
      C++总结
      KMP算法
      理解I/O Completion Port(完成端口)
      [转载]Windows网络编程系列教程之四:Select模型
      [转载]理解 I/O Completion Port (IOCP完成端口)
      [转载]IOCP模型的总结
      发个IOCP的C++例子
      说说网络通信模型
      几个网络模型的示例代码(BlockingModel、OverlappedModel、WSAEventSelect、CompletionRoutine)..c++
      关于Socket 多线程 的一篇好文章
    • 原文地址:https://www.cnblogs.com/jsxyhelu/p/12804033.html
    Copyright © 2020-2023  润新知