CMake 使用 OpenCV:从库中查找包含头文件

news2024/11/18 3:21:03

在这里插入图片描述

前言

       在开发使用 OpenCV 的项目时,正确配置 CMake 是确保项目顺利构建和运行的关键。开发过程经常存在各种各样的意外和偶然, 是困难也是收获. 比如一直好好的项目, include某个头文件, 编译突然出现:No such file or directory

CmakeTest/test_opencv.h:4: error: opencv2/highgui.hpp: No such file or directory
    4 | #include <opencv2/highgui.hpp>
      |          ^~~~~~~~~~~~~~~~~~~~~

find_package查找 OpenCV 库

CMakeLists.txt 文件中,使用 find_package(OpenCV REQUIRED) 来查找并引入 OpenCV 库。这行代码的作用如下:

  1. 查找 OpenCV 库:CMake 会在系统的标准位置以及环境变量中指定的位置查找 OpenCV 库。
  2. 设置相关变量:找到 OpenCV 后,CMake 会设置一些变量,如 OpenCV_INCLUDE_DIRS(头文件路径)和 OpenCV_LIBS(库文件)。
  3. 配置编译选项:CMake 使用这些变量配置项目,使代码能够包含 OpenCV 的头文件并链接到 OpenCV 库。

CMakeLists.txt 文件示例:

cmake_minimum_required(VERSION 3.4.1)
project(CMakeTest)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# 配置OpenCV 路径
set(OpenCV_DIR /sdk/opencv-linux-aarch64/lib/cmake/opencv4)

# 查找 OpenCV 库
find_package(OpenCV REQUIRED)

#message(OpenCV_LIBS "=${OpenCV_LIBS}")
# 输出: 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

#message(OpenCV_INCLUDE_DIRS "=${OpenCV_INCLUDE_DIRS}")
# 输出: OpenCV_INCLUDE_DIRS=/sdk/opencv-linux-aarch64/include/opencv4

#target_include_directories(my_executable PRIVATE ${OpenCV_INCLUDE_DIRS})

#include_directories(${CMAKE_SOURCE_DIR}/include2)
# 添加可执行文件
add_executable(test_opencv
    test_opencv.cpp)
    
# 链接 OpenCV 库
target_link_libraries(test_opencv
  ${OpenCV_LIBS}
)

在这个示例中,CMake 首先查找 OpenCV 库,然后设置包含路径和库路径,最后将这些路径添加到编译选项中,以便在编译和链接时使用 OpenCV 库。

包含 OpenCV 头文件

假设项目目录结构如下:

CMakeTest/
├── CMakeLists.txt
├── test_opencv.cpp
├── main.cpp
└── test_opencv.h

test_opencv.htest_opencv.cpp 文件中,需要正确包含 OpenCV 的头文件:

test_opencv.h

#ifndef _TEST_OPENCV_H_
#define _TEST_OPENCV_H_

#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>

class ImageUtils{
public:
    void init(){
        cv::Mat img = cv::imread("/data/test.jpg");
    }
};

#endif

test_opencv.cpp

#include "test_opencv.h"
#include "stdio.h"
#include "stdlib.h"

int main()
{
    printf("[%s] start\n", __FUNCTION__);

    return 0;
}

通过上述设置,test_opencv.htest_opencv.cpp 文件都能正确包含 OpenCV 的头文件。

通常, 在正常情况下, 使用外部的动态库时, 只需要2步:

  1. 包含所需的头文件
  2. 链接所需的库.

在前面代码中, 并没有显式地使用 include_directoriestarget_include_directories 包含OpenCV的头文件.

为什么不需要显式设置 include_directories

      原因是在 CMake 中,find_package(OpenCV REQUIRED) 会引入 OpenCV 的目标(targets),这些目标包含了库文件和包含路径信息。当你链接 OpenCV 目标时,这些包含路径会自动应用于你的目标。

示例项目结构

cmake_minimum_required(VERSION 3.10)
project(MyProject)

# 查找 OpenCV 库
find_package(OpenCV REQUIRED)

# 添加可执行文件
add_executable(my_executable main.cpp mycpp.cpp)

# 链接 OpenCV 库
target_link_libraries(my_executable ${OpenCV_LIBS})

在这个配置中,target_link_libraries(my_executable ${OpenCV_LIBS}) 会自动将 OpenCV 的包含路径应用到 my_executable 目标的所有源文件(main.cppmycpp.cpp)。

全局范围与目标范围的 include_directories

虽然在现代 CMake 中不需要显式调用 include_directories(${OpenCV_INCLUDE_DIRS}),但为了确保兼容性和避免潜在问题,明确设置包含路径仍然是个好习惯:

  1. 全局范围:在项目的顶部调用 include_directories,会影响整个项目中的所有目标和源文件。

    include_directories(${OpenCV_INCLUDE_DIRS})
    
  2. 目标范围:使用 target_include_directories,只会影响特定目标。

    target_include_directories(my_executable PRIVATE ${OpenCV_INCLUDE_DIRS})
    

结论

  • CMake:依赖目标导入机制,target_link_libraries 会自动处理包含路径。
  • 兼容性:为了避免路径冲突或未找到头文件的问题,显式设置包含路径是个好习惯。

通过正确配置 CMake 和 OpenCV,确保项目顺利构建和运行。

问题解决

首先, 关于 include某个头文件, 编译突然出现:No such file or directory 这个问题是如何出现的:

cmake_minimum_required(VERSION 3.4.1)
project(CMakeTest)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# 配置OpenCV 路径
set(OpenCV_DIR /sdk/opencv-linux-aarch64/lib/cmake/opencv4)

# 查找 OpenCV 库
find_package(OpenCV REQUIRED)

# 添加可执行文件
add_executable(test_opencv
    test_opencv.cpp)
    
# 链接 OpenCV 库
target_link_libraries(test_opencv
  ${OpenCV_LIBS}
)


### 分界线 ###
add_executable(test_main
    main.cpp)

配置输出两个可执行文件: test_opencv, test_main
问题就出在 test_main

main.cpp 源码内容和test_opencv.cpp是一样的

#include "test_opencv.h"
#include "stdio.h"
#include "stdlib.h"

int main()
{
    printf("[%s] start\n", __FUNCTION__);

    return 0;
}
CmakeTest/main.cpp:1: In file included from CmakeTest/main.cpp:1:
CmakeTest/test_opencv.h:4: error: opencv2/highgui.hpp: No such file or directory
    4 | #include <opencv2/highgui.hpp>
      |          ^~~~~~~~~~~~~~~~~~~~~

因为 test_main 没有链接OpenCV库, 解决方案有:

  1. 增加: target_link_libraries(test_main ${OpenCV_LIBS} )

  2. 全局增加include_directories(${OpenCV_INCLUDE_DIRS})

  3. 针对 test_main 增加 target_include_directories(test_main PRIVATE ${OpenCV_INCLUDE_DIRS})

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1949080.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

一套成熟的实验室信息管理系统源码,.Net 检验系统LIS源码,实现从采集、检测、报告、归档的全程跟踪管理

一套成熟的实验室信息管理系统源码。在长期的医疗信息化实践中&#xff0c;我们分析总结了大量客户实例&#xff0c;建立了以病人为中心、以业务处理为基础、以提高检验科室管理水平和工作效率为目标的产品开发思路&#xff0c;将医学检验、科室管理和财务统计等检验科室/实验室…

ControlNet on Stable Diffusion

ControlNet on Stable Diffusion 笔记来源&#xff1a; 1.Adding Conditional Control to Text-to-Image Diffusion Models 2.How to Use OpenPose & ControlNet in Stable Diffusion 3.ControlNet与DreamBooth&#xff1a;生成模型的精细控制与主体保持 4.Introduction t…

【Python实战】Google Chrome的离线小恐龙游戏

文章目录 Google Chrome的离线小恐龙游戏项目结构大纲 &#x1f4ca;&#x1f463;逐步编码过程 &#x1f9e9;&#x1f4a1;第一步&#xff1a;项目初始化与主程序框架第二步&#xff1a;实现T-Rex的跳跃功能第三步&#xff1a;添加障碍物和碰撞检测第四步&#xff1a;添加得分…

Python3网络爬虫开发实战(1)爬虫基础

一、URL 基础 URL也就是网络资源地址&#xff0c;其满足如下格式规范 scheme://[username:password]hostname[:port][/path][;parameters][?query][#fragment] scheme&#xff1a;协议&#xff0c;常用的协议有 Http&#xff0c;https&#xff0c;ftp等等&#xff1b;usern…

正点原子 通用外设配置模型 GPIO配置步骤 NVIC配置

1. 这个是通用外设驱动模式配置 除了初始化是必须的 其他不是必须的 2. gpio配置步骤 1.使能时钟是相当于开电 2.设置工作模式是配置是输出还是输入 是上拉输入还是下拉输入还是浮空 是高速度还是低速度这些 3 和 4小点就是读写io口的状态了 3. 这个图是正点原子 将GPIO 的时…

2024中国大学生算法设计超级联赛(2)

&#x1f680;欢迎来到本文&#x1f680; &#x1f349;个人简介&#xff1a;陈童学哦&#xff0c;彩笔ACMer一枚。 &#x1f3c0;所属专栏&#xff1a;杭电多校集训 本文用于记录回顾总结解题思路便于加深理解。 &#x1f4e2;&#x1f4e2;&#x1f4e2;传送门 A - 鸡爪解题思…

eclipse修改tomcat的Jre运行环境

1.双击tomcat 2.RuntimeEnvironment 3.选择

轨道式智能巡检机器人,助力综合管廊安全运维

1 引言 当前城市综合管廊建设已经成为世界范围内的发展趋势&#xff0c;2017年5月住建部、发改委联合发布《全国城市市政基础设施建设“十三五”规划》&#xff0c;截至2017年4月底国内地下综合管廊试点项目已开工建设687 km&#xff0c;建成廊体260 km&#xff0c;完成投资40…

redis的使用场景-热点数据缓存

1.什么是缓存&#xff1f; 把一些经常访问的数据放入缓存中&#xff0c;减少访问数据库的频率&#xff0c;减少数据库的压力&#xff0c;从而提高程序的性能。【内存中存储】 2.缓存的原理 通过上图可以看出程序首先访问缓存&#xff0c;如果缓存中有访问的数据会直接方会给客…

分布式系统常见软件架构模式

常见的分布式软件架构 Peer-to-Peer (P2P) PatternAPI Gateway PatternPub-Sub (Publish-Subscribe)Request-Response PatternEvent Sourcing PatternETL (Extract, Transform, Load) PatternBatching PatternStreaming Processing PatternOrchestration Pattern总结 先上个图&…

基于Golang+Vue3快速搭建的博客系统

WANLI 博客系统 项目介绍 基于vue3和gin框架开发的前后端分离个人博客系统&#xff0c;包含md格式的文本编辑展示&#xff0c;点赞评论收藏&#xff0c;新闻热点&#xff0c;匿名聊天室&#xff0c;文章搜索等功能。 项目在线访问&#xff1a;http://bloggo.chat/ 或 http:/…

Photos框架 - 自定义媒体资源选择器(数据部分)

引言 在iOS开发中&#xff0c;系统已经为我们提供了多种便捷的媒体资源选择方式&#xff0c;如UIImagePickerController和PHPickerViewController。这些方式不仅使用方便、界面友好&#xff0c;而且我们完全不需要担心性能和稳定性问题&#xff0c;因为它们是由系统提供的&…

基于扩散的生成模型的语音增强和去噪

第二章 目标说话人提取之《Speech Enhancement and Dereverberation with Diffusion-based Generative Models》 文章目录 前言一、任务二、动机三、挑战四、方法1.方法:基于分数的语音增强生成模型(sgmse)2.网络结构 五、实验评价1.数据集2.采样器设置和评价指标3.基线模型4.评…

godot新建项目及设置外部编辑器为vscode

一、新建项目 初次打开界面如下所示&#xff0c;点击取消按钮先关闭掉默认弹出的框 点击①新建弹出中间的弹窗②中填入项目的名称 ③中设置项目的存储路径&#xff0c;点击箭头所指浏览按钮&#xff0c;会弹出如下所示窗口 根据图中所示可以选择或新建自己的游戏存储路径&…

音视频开发之旅(85)- 图像分类-VGG模型解析

目录 1. VGG解决的问题 2. 网络结构和参数 3. pytorch搭建vgg 4.flower_photos分类任务实践 5.资料 一、VGG解决的问题 论文链接&#xff1a;https://arxiv.org/pdf/1409.1556 在VGG之前&#xff0c;大多数深度学习模型相对较浅&#xff0c;比如下面的AlexNet(5层卷积和3…

记录阿里云部署gitlab

登录阿里云&#xff1a; 阿里云登录 - 欢迎登录阿里云&#xff0c;安全稳定的云计算服务平台 选择自己的ECS实例。我的实例是 使用VNC登录&#xff1a;输入用户名和密码 安装所需的依赖包&#xff1a; sudo yum install -y yum-utils device-mapper-persistent-data lvm2 添…

Git(分布式版本控制系统)(fourteen day)

一、分布式版本控制系统 1、Git概述 Git是一种分布式版本控制系统&#xff0c;用于跟踪和管理代码的变更&#xff0c;它由Linux、torvalds创建的&#xff0c;最初被设计用于Linux内核的开发。Git允许开发人员跟踪和管理代码的版本&#xff0c;并且可以在不同的开发人员之间进行…

货架管理a

路由->vue的el标签->Api->call方法里calljs的api接口->数据声明const xxxData-> 编辑按钮:点击跳出页面并把这一行的数据给到表单formDataba2 保存按钮:formDataba2改过的数据->xxApi发送->查询Api 跳转仓库:把tableData.value数据清空->callXxxAp…

华为云依赖引入错误

问题&#xff1a;记录一次项目加在华为云依赖错误&#xff0c;如下&#xff1a; 错误信息&#xff1a;Could not find artifact com.huawei.storage:esdk-obs-java:pom:3.1.2.1 in bintray-qcloud-maven-repo (https://dl.bintray.com/qcloud/maven-repo/) 找到本地仓库&#…

mac环境Qt Creator报错:Warning: You are changing a read-only file.

mac环境Qt Creator报错&#xff1a; Warning: You are changing a read-only file. 权限许可 文件权限问题 修改文件夹权限的基本语法&#xff1a; 打开终端&#xff1a;打开 macOS 中的终端应用程序。 sudo chmod -R permissions folder_pathchmod 是改变文件或文件夹权限…