自学内容网 自学内容网

Visual Studio 2022新建 cmake 工程测试 opencv helloworld

1. 参考博客:

        1.1. https://blog.csdn.net/yangSHU21/article/details/130237669( 利用OpenCV把一幅彩色图像转换成灰度图 )( vs2022_cmake_test.cpp 中的代码用的此博客的,就改了下图片文件路径而已 )

2. 检查 Visual Studio 2022是否支持 cmake:

        打开 Visual Studio installer:

已安装--》修改:

 工作负荷--》使用C++的桌面开发--》可选--》如果 "用于 windows的 C++ cmake工具" 勾选了,即表示你的 Visual Studio 2022 支持 cmake:

3. 操作步骤:

        打开 Visual Studio 2022 --》创建新项目--》搜索 cmake--》选择 "cmake 项目( 生成不依赖于 .sln 或 .vcxproj 文件的新式跨平台 C++ 应用。 )"--》点击下一步--》 设置项目名称、位置--》点击创建,默认生成的 vs2022_cmake_test_02.cpp 文件内容如下:

#include "vs2022_cmake_test_02.h"
using namespace std;

int main()
{
cout << "Hello CMake." << endl;
return 0;
}

默认生成的 CMakeLists.txt内容如下:        

cmake_minimum_required (VERSION 3.8)

# 如果支持,请为 MSVC 编译器启用热重载。
if (POLICY CMP0141)
  cmake_policy(SET CMP0141 NEW)
  set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT "$<IF:$<AND:$<C_COMPILER_ID:MSVC>,$<CXX_COMPILER_ID:MSVC>>,$<$<CONFIG:Debug,RelWithDebInfo>:EditAndContinue>,$<$<CONFIG:Debug,RelWithDebInfo>:ProgramDatabase>>")
endif()

project ("vs2022_cmake_test_02")

# 将源代码添加到此项目的可执行文件。
add_executable (vs2022_cmake_test_02 "vs2022_cmake_test_02.cpp" "vs2022_cmake_test_02.h")

if (CMAKE_VERSION VERSION_GREATER 3.12)
  set_property(TARGET vs2022_cmake_test_02 PROPERTY CXX_STANDARD 20)
endif()

将 vs2022_cmake_test.cpp 的内容修改为如下所示:

#include "vs2022_cmake_test_02.h"
#include <opencv2\opencv.hpp>

using namespace cv;
using namespace std;

void opencv_test();
void ConvertRGB2GRAY(const Mat& image, Mat& imageGray);

void opencv_test() {
Mat src = imread("D:/素材/图片/壁纸/0001.jpg");
Mat src0 = imread("D:/素材/图片/壁纸/0001.jpg", 0);
Mat grayImage;
Mat cvt_gray_image;

//读入的彩色图
namedWindow("origin_image", WINDOW_NORMAL);
imshow("origin_image", src);

//opencv使用imread函数读入彩色图,设置第二个参数为0得到的灰度图
namedWindow("opencv_image", WINDOW_NORMAL);
imshow("opencv_image", src0);

//使用公式GRAY=0.299*R+0.587*G+0.114*B
ConvertRGB2GRAY(src, grayImage);
namedWindow("my_gray_image", WINDOW_NORMAL);
imshow("my_gray_image", grayImage);

//先读入彩色图,然后使用cvtColor函数进行灰度转化
cvtColor(src, cvt_gray_image, COLOR_BGR2GRAY);
namedWindow("cvt_gray_image", WINDOW_NORMAL);
imshow("cvt_gray_image", cvt_gray_image);
waitKey(0);
}

void ConvertRGB2GRAY(const Mat& image, Mat& imageGray)
{
if (!image.data || image.channels() != 3)
{
return;
}
//创建一张单通道的灰度图像
imageGray = Mat::zeros(image.size(), CV_8UC1);
//取出存储图像像素的数组的指针
uchar* pointImage = image.data;
uchar* pointImageGray = imageGray.data;
//取出图像每行所占的字节数
size_t stepImage = image.step;
size_t stepImageGray = imageGray.step;


for (int i = 0; i < imageGray.rows; i++)
{
for (int j = 0; j < imageGray.cols; j++)
{
//opencv的通道顺序是BGR,而不是我们常说的RGB顺序
pointImageGray[i * stepImageGray + j] =
(uchar)(0.114 * pointImage[i * stepImage + 3 * j] +
0.587 * pointImage[i * stepImage + 3 * j + 1] +
0.299 * pointImage[i * stepImage + 3 * j + 2]);
}
}
}



int main()
{
cout << "Hello CMake." << endl;
opencv_test();
return 0;
}

此时 vs2022 报错 "找不到opencv 的头文件":

 找到 opencv2 的位置如下所示:

可以直接将 "D:\install\opencv\opencv\build\include" 加入进来,即在 CMakeLists.txt 中加入 如下指令:

include_directories( "D:/install/opencv/opencv/build/include" ) 

但是这样不太优雅,优雅的做法是加入如下指令:

 find_package(OpenCV REQUIRED) 

其作用是查找 OpenCV 包,找到以后就可以直接使用内置变量 OpenCV_INCLUDE_DIRS 和 OpenCV_LIBS 了( 分别表示 opencv 的 头文件的目录位置和 链接库的目录位置 ),但是 cmake 是从哪里去找 opencv 呢?可能它内置的有一些策略吧,不放心的话或者电脑装了多个版本的 opencv,其实可以手动指定查找位置,即使用如下指令:

set(OpenCV_DIR "D:/install/opencv/opencv/build")

这里指定 "D:/install/opencv/opencv/build" 的依据是什么呢?到底是 opencv 的根目录还是头文件目录还是链接库目录呢?其实应该写 opencv 编译目录中 

OpenCVConfig.cmake

文件所在的目录,例如我电脑中 OpenCVConfig.cmake  所在位置如下所示:

所以我指定的是  D:/install/opencv/opencv/build( ps:windows中 CMakeLists.txt 中的路径最好写正斜线,不能写反斜线!!!不知道双反斜线可不可以?没试过 )

修改后的最终完整的 CMakeLists.txt 如下所示:

cmake_minimum_required (VERSION 3.8)

# 如果支持,请为 MSVC 编译器启用热重载。
if (POLICY CMP0141)
  cmake_policy(SET CMP0141 NEW)
  set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT "$<IF:$<AND:$<C_COMPILER_ID:MSVC>,$<CXX_COMPILER_ID:MSVC>>,$<$<CONFIG:Debug,RelWithDebInfo>:EditAndContinue>,$<$<CONFIG:Debug,RelWithDebInfo>:ProgramDatabase>>")
endif()

project ("vs2022_cmake_test_02")

set(OpenCV_DIR "D:/install/opencv/opencv/build")
# 查找OpenCV包
find_package(OpenCV REQUIRED)

# include_directories( "D:/install/opencv/opencv/build/include" )
# set(CMAKE_LIBRARY_PATH "D:/install/opencv/opencv/build/x64/vc16/bin"  "D:/install/opencv/opencv/build/x64/vc16/lib" )

# 如果OpenCV被找到,包含其头文件目录和库
message( "--------------------------------------------------" )
message( "--------------------------------------------------" )
message( "--------------------------------------------------" )
message( "OpenCV_INCLUDE_DIRS = ${OpenCV_INCLUDE_DIRS}"  )
message( "OpenCV_LIBS = ${OpenCV_LIBS}" )
message( "OpenCV_FOUND = ${OpenCV_FOUND}" )

if(OpenCV_FOUND)
  message( "OpenCV founded" )
  include_directories(${OpenCV_INCLUDE_DIRS})
endif()


# 将源代码添加到此项目的可执行文件。
add_executable (vs2022_cmake_test_02 "vs2022_cmake_test_02.cpp" "vs2022_cmake_test_02.h")

if(OpenCV_FOUND)
  message( "OpenCV founded" )
  target_link_libraries(vs2022_cmake_test_02 ${OpenCV_LIBS})
endif()

message( "------------------------------------------------" )
message( "-----------------------------------------------" )
message( "--------------------------------------------------" )

if (CMAKE_VERSION VERSION_GREATER 3.12)
  set_property(TARGET vs2022_cmake_test_02 PROPERTY CXX_STANDARD 20)
endif()

这时候编译就成功了,部分输出信息如下:

1> 工作目录: D:/code/c_code/cpp_study_demo/vs2022/vs2022_cmake_test_02/out/build/x64-debug
1> [CMake] -- OpenCV ARCH: x64
1> [CMake] -- OpenCV RUNTIME: vc16
1> [CMake] -- OpenCV STATIC: OFF
1> [CMake] -- Found OpenCV 4.10.0 in D:/install/opencv/opencv/build/x64/vc16/lib
1> [CMake] -- You might need to add D:\install\opencv\opencv\build\x64\vc16\bin to your PATH to be able to run your applications.
1> [CMake] --------------------------------------------------
1> [CMake] --------------------------------------------------
1> [CMake] --------------------------------------------------
1> [CMake] OpenCV_INCLUDE_DIRS = D:/install/opencv/opencv/build/include
1> [CMake] OpenCV_LIBS = opencv_calib3d;opencv_core;opencv_dnn;opencv_features2d;opencv_flann;opencv_gapi;opencv_highgui;opencv_imgcodecs;opencv_imgproc;opencv_ml;opencv_objdetect;opencv_photo;opencv_stitching;opencv_video;opencv_videoio;opencv_world
1> [CMake] OpenCV_FOUND = 1
1> [CMake] OpenCV founded
1> [CMake] OpenCV founded
1> [CMake] ------------------------------------------------
1> [CMake] -----------------------------------------------
1> [CMake] --------------------------------------------------
1> [CMake] -- Configuring done (0.0s)
1> [CMake] -- Generating done (0.0s)
1> [CMake] -- Build files have been written to: D:/code/c_code/cpp_study_demo/vs2022/vs2022_cmake_test_02/out/build/x64-debug
1> 已提取 CMake 变量。
1> 已提取源文件和标头。
1> 已提取代码模型。
1> 已提取工具链配置。
1> 已提取包含路径。
1> CMake 生成完毕。

可以看到 :

OpenCV_INCLUDE_DIRS = D:/install/opencv/opencv/build/include
OpenCV_LIBS = opencv_calib3d;opencv_core;opencv_dnn;opencv_features2d;opencv_flann;opencv_gapi;opencv_highgui;opencv_imgcodecs;opencv_imgproc;opencv_ml;opencv_objdetect;opencv_photo;opencv_stitching;opencv_video;opencv_videoio;opencv_world

这时候运行 vs2022_cmake_test_02.exe报错:

使用 Everything 搜索下 opencv_world4100.dll:

应该把 D:\install\opencv\opencv\build\x64\vc16\bin 加入环境变量,其实刚才 cmake 的输入信息中已经建议这样做了:

1> [CMake] -- Found OpenCV 4.10.0 in D:/install/opencv/opencv/build/x64/vc16/lib
1> [CMake] -- You might need to add D:\install\opencv\opencv\build\x64\vc16\bin to your PATH to be able to run your applications.
1> [CMake] --------------------------------------------------
1> [CMake] --------------------------------------------

加入环境变量:

 这时候就运行成功了:

 记得打开新的 cmd 测试,如果是在 vs2022中测试也需要关闭工程重新打开进行测试。

4. CMakeLists.txt 中直接使用的变量 OpenCV_INCLUDE_DIRS、OpenCV_LIBS、OpenCV_FOUND 是在哪里定义的?

打开 D:\install\opencv\opencv\build 下面的 OpenCVConfig.cmake,找到如下内容:

#    This file will define the following variables:
#      - OpenCV_LIBS                     : The list of libraries to link against.
#      - OpenCV_INCLUDE_DIRS             : The OpenCV include directories.
#      - OpenCV_COMPUTE_CAPABILITIES     : The version of compute capability
#      - OpenCV_VERSION                  : The version of this OpenCV build: "4.10.0"
#      - OpenCV_VERSION_MAJOR            : Major version part of OpenCV_VERSION: "4"
#      - OpenCV_VERSION_MINOR            : Minor version part of OpenCV_VERSION: "10"
#      - OpenCV_VERSION_PATCH            : Patch version part of OpenCV_VERSION: "0"
#      - OpenCV_VERSION_STATUS           : Development status of this build: ""

说此文件定义了这几个变量,但是这只是注释,此文件并没有直接有声明比如 set( OpenCV_INCLUDE_DIRS ... )  的地方,可能是 该文件引用的其他文件声明了,在该文件中找到了如下内容:


function(check_one_config RES)
  set(${RES} "" PARENT_SCOPE)
  if(NOT OpenCV_RUNTIME OR NOT OpenCV_ARCH)
    return()
  endif()
  set(candidates)
  if(OpenCV_STATIC)
    list(APPEND candidates "${OpenCV_ARCH}/${OpenCV_RUNTIME}/staticlib")
  endif()
  if(OpenCV_CUDA)
    list(APPEND candidates "gpu/${OpenCV_ARCH}/${OpenCV_RUNTIME}/lib")
  endif()
  if(OpenCV_CUDA AND OpenCV_STATIC)
    list(APPEND candidates "gpu/${OpenCV_ARCH}/${OpenCV_RUNTIME}/staticlib")
  endif()
  list(APPEND candidates "${OpenCV_ARCH}/${OpenCV_RUNTIME}/lib")
  foreach(c ${candidates})
    set(p "${OpenCV_CONFIG_PATH}/${c}")
    if(EXISTS "${p}/OpenCVConfig.cmake")
      set(${RES} "${p}" PARENT_SCOPE)
      return()
    endif()
  endforeach()
endfunction()

定义了一个集合变量 candidates,如下一行:

 list(APPEND candidates "${OpenCV_ARCH}/${OpenCV_RUNTIME}/lib")

应该是往集合 candidates 中追加一个路径类型的元素,其中路径中的 OpenCV_ARCH 应该对应我电脑环境的 x64,OpenCV_RUNTIME 应该对应 vc16,果然在 D:\install\opencv\opencv\build\x64\vc16\lib 下面找到了 OpenCVConfig.cmake:

打开此文件,发现了定了定义变量 OpenCV_INCLUDE_DIRS 的地方:

 


原文地址:https://blog.csdn.net/heshiyuan1406146854/article/details/140656685

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!