OpenCV 基本使用

news2024/11/15 10:09:50

OpenCV 基本使用

参考教程:

GitHub - gaoxiang12/slambook2: edition 2 of the slambook

1. 安装 OpenCV

1.1 下载 OpenCV

参考教程:

无法定位软件包libjasper-dev的解决办法-CSDN博客

视觉slam14讲ch5 opencv安装 ubuntu20.04_libvtk5-dev-CSDN博客

OpenCV提供了大量的开源图像算法,是计算机视觉领域使用极广的图像处理算法库。在Ubuntu系统下,OpenCV有从源代码安装和只安装库文件两种方式可以选择:

(1)从源代码安装,是指从OpenCV网站下载所有的OpenCV源代码,并在机器上编译以便使用。好处是可以选择的版本比较丰富,而且也能看到源代码,不过需要花费一些编译时间。

(2)只安装库文件,是指通过Ubuntu安装由Ubuntu社区人员已经编译好的库文件,无须重新编译一遍。

因为我们使用较新版本的OpenCV,所以必须选择从源代码安装的方式来安装它。一来,可以调整一些编译选项,匹配编程环境(例如,需不需要GPU加速等);再者,可以使用一些额外的功能。OpenCV目前维护三个主要版本,分为OpenCV2.4系列、OpenCV 3系列和OpenCV 4系列。当前使用OpenCV 3系列。

从如下网站中下载源代码:

Releases - OpenCV

页面下滑,选择OpenCV – 3.4.16版本,点击”Sources“进行下载

下载得到如下的压缩包

opencv-3.4.16.zip文件拖拽至虚拟机的home文件夹下:

点击opencv-3.4.16.zip文件,右键,选择“提取到此处

1.2 配置依赖项并编译

编译之前,先来安装OpenCV的依赖项:

rosnoetic@rosnoetic-VirtualBox:~$ sudo add-apt-repository "deb http://security.ubuntu.com/ubuntu xenial-security main"

rosnoetic@rosnoetic-VirtualBox:~$ sudo apt update

rosnoetic@rosnoetic-VirtualBox:~$ sudo apt upgrade

rosnoetic@rosnoetic-VirtualBox:~$ sudo apt-get install build-essential libgtk2.0-dev libvtk6-dev libjpeg-dev libtiff5-dev libjasper-dev libopenexr-dev libtbb-dev libcanberra-gtk-module

事实上,OpenCV的依赖项很多,缺少某些编译项会影响它的部分功能。OpenCVcmake阶段检查依赖项是否会安装,并调整自己的功能。如果电脑上有GPU并且安装了相关依赖项,OpenCV也会把GPU加速打开。不过当前,上述依赖项已经足够了。

安装完依赖项后进行编译:

rosnoetic@rosnoetic-VirtualBox:~$ cd opencv-3.4.16/

rosnoetic@rosnoetic-VirtualBox:~/opencv-3.4.16$ mkdir build

rosnoetic@rosnoetic-VirtualBox:~/opencv-3.4.16$ cd build/

rosnoetic@rosnoetic-VirtualBox:~/opencv-3.4.16/build$ cmake ..

接着进行编译

rosnoetic@rosnoetic-VirtualBox:~/opencv-3.4.16/build$ make

整个编译过程大概需要二十分钟到一小时不等。

make之后,调用sudo make installOpenCV安装到电脑上(而不是仅仅编译)。

rosnoetic@rosnoetic-VirtualBox:~/opencv-3.4.16/build$ sudo make install

2. 操作 OpenCV 图像

2.1 编写 imageBasics 函数

2.1.1 创建文件夹

通过终端创建一个名为imageBasics的文件夹以保存我们的VSCode项目,在/imageBasics目录下打开vscode

rosnoetic@rosnoetic-VirtualBox:~$ mkdir -p imageBasics

rosnoetic@rosnoetic-VirtualBox:~$ cd imageBasics/

rosnoetic@rosnoetic-VirtualBox:~/imageBasics$ code .

2.1.2 编写源代码

新建文件imageBasics.cpp

imageBasics.cpp粘贴如下代码并保存(Ctrl+S)

#include <iostream>
#include <chrono>

using namespace std;

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

int main(int argc, char argv) {
    // 读取argv[1]指定的图像
    cv::Mat image;
    //cv::image函数读取制定路径下的图像
    image = cv::imread(argv[1]);

    // 判断图像文件是否正确读取
    if (image.data == nullptr) {
        // 数据不存在,可能是文件不存在
        cerr << "文件" << argv[1] << "不存在" <<endl;
        return 0;
    }

    // 文件顺利读取,首先输出一些基本信息
    cout << "图像宽为: " << image.cols << ",高为: " << image.rows
              << ",通道数为" << image.channels() << endl;
    cv::imshow("image",image);   // cv::imshow显示图像
    cv::waitKey(0);   // 暂停程序,等待一个按键输入

    // 判断imgae的类型
    if (image.type() != CV_8UC1 && image.type() != CV_8UC3) {
        // 图像类型不符合要求
        cout << "请输入一张彩色图或灰度图" << endl;
        return 0;
    }

    // 遍历图像,请注意以下遍历方式也使用于随机像素访问
    // 使用std::chrono给算法计时
    chrono::steady_clock::time_point t1 = chrono::steady_clock::now();
    for (size_t y = 0; y < image.rows; y++) {
        // 用cv::Mat::ptr获得图像的行指针,<unsigned char>指定类型,(y)是一个索引值,表示我们要访问的行数
        unsigned char *row_ptr = image.ptr<unsigned char>(y);
        for (size_t x = 0; x < image.cols; x++) {
            // 访问位于x,y处的像素
            unsigned char *data_ptr = &row_ptr[x * image.channels()];   // data_ptr指针指向待访问的像素数据
            // 输出该像素的每个通道,如果是灰度图,那么通道是1
            for (int c = 0; c != image.channels(); c++) {
                unsigned char data = data_ptr[c];   // data为I(x,y)第c个通道的像素值
            }
        }
    }
    chrono::steady_clock::time_point t2 = chrono::steady_clock::now();
    // 计算消耗时间
    chrono::duration<double> time_used = chrono::duration_cast<chrono::duration<double>> (t2-t1);
    cout << "遍历图所用时间: " << time_used.count() << "秒。"<< endl;

    // 关于cv::Mat的拷贝
    // 直接赋值并不会拷贝数据
    cv::Mat image_another = image;
    // 此时修改image_another,会导致image发生变化
    image_another(cv::Rect(0, 0, 100, 100)).setTo(0);   // 将左上角100*100的块置为0
    cv::imshow("image",image);
    cv::waitKey(0);

    // 使用clone深拷贝复制数据
    cv::Mat image_clone = image.clone();
    image(cv::Rect(0, 0, 100, 100)).setTo(255);
    cv::imshow("image", image);
    cv::imshow("image_clone", image_clone);
    cv::waitKey(0);

    // 删除所有的窗口
    cv::destroyAllWindows();

    return 0;
}

2.2 新建 CMakeLists.txt 文件

新建CMakeLists.txt文件

CMakeLists.txt中添加如下内容:

# 声明要求的cmake最低版本
cmake_minimum_required(VERSION 2.8)

# 声明一个cmake工程
project(IMAGEBASICS)

# 添加C++ 11支持
set(CMAKE_CXX_FLAGS "-std=c++11")

# 寻找OpenCV库
find_package( OpenCV REQUIRED)
# 添加头文件
include_directories(${OpenCV_INCLUDE_DIRS})

add_executable(imageBasics imageBasics.cpp)
# 链接OpenCV库
target_link_libraries(imageBasics ${OpenCV_LIBS})

由于程序中使用了C++11标准(如nullptrchrono),因此需要设置编译器set(CMAKE_CXX_FLAGS "-std=c++11")

2.3 cmake 编译

ctrl+alt+T打开终端,执行如下指令进行cmake编译

rosnoetic@rosnoetic-VirtualBox:~$ cd imageBasics/

rosnoetic@rosnoetic-VirtualBox:~/imageBasics$ mkdir build

rosnoetic@rosnoetic-VirtualBox:~/imageBasics$ cd build/

rosnoetic@rosnoetic-VirtualBox:~/imageBasics/build$ cmake ..

我们新建了一个中间文件夹”build“,然后进入build文件夹,通过cmake ..命令对上一层文件夹,也就是代码所在的文件夹进行编译。这样,cmake产生的中间文件就会生成在build文件夹中,如下图所示,和源代码分开。

接着make对工程进行编译

rosnoetic@rosnoetic-VirtualBox:~/imageBasics/build$ make

2.4 运行

ubuntu.png文件拖拽至imageBasics/build文件夹下

进一步的调用可执行文件:

rosnoetic@rosnoetic-VirtualBox:~/imageBasics/build$ ./imageBasics ubuntu.png 

依次显示如下内容:

image窗口,按enter键执行下一个程序(也就是停留在了cv::waitKey()

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

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

相关文章

机器学习——聚类算法K-Means

目录 一、初识聚类 1. 认识聚类算法 2. 聚类的流程 3. 簇内误差平方和 Inertia越小模型越好吗&#xff1f; 二、KMeans介绍 1. 重要参数n_clusters 2. 模型评估指标 &#xff08;1&#xff09;真实标签己知的时候 &#xff08;2&#xff09;真实标签未知的时候 三、s…

Tomcat 最大连接数实现原理

spring boot 内置tomcat设置连接数 max-connections: 5 server:port: 9898servlet:context-path: /testtomcat:connection-timeout: 5000max-connections: 5accept-count: 5 ##初始化连接数量connectionLimitLatch protected LimitLatch initializeConnectionLatch() {if (ma…

【区块链+食品安全】农业产业全过程溯源云平台 | FISCO BCOS应用案例

近年来&#xff0c;食品安全问题频发&#xff0c;尤其疫情期间&#xff0c;海鲜、冷冻畜牧产品的入口安全成为大众关注焦点&#xff0c;追溯、确保相关产品生产、运输、售卖等环节的信息真实、有效&#xff0c;成为保证食品安全的核心环节。浙江天演维真网络科技股份有限公司基…

基于ICMP(Ping)的多线程网络通道监视程序(QT)开发

基于ICMP(Ping)的多线程网络通道监视程序(QT)开发 1、 ICMP原理简介 可参考 ICMP(Ping)功能原理及其C实现简介 。 2、 网络通道监视程序开发 设计原理&#xff1a; 通过PING 功能实现服务器、交换机、网闸等设备的网络检测&#xff0c;判断网络的否可达和TTL计算 。 具备功…

微深节能 库区智能化无人天车管理系统 格雷母线

格雷母线在库区智能化无人天车管理系统的应用中&#xff0c;发挥了至关重要的作用。 一、系统构成与原理 系统构成&#xff1a; 格雷母线高精度位移测量系统主要由格雷母线、天线箱、地址解码器、地址编码器四个核心部分组成。这些组件协同工作&#xff0c;实现对移动设备的精确…

c++41两头堵模型

直接拷到自己的内存空间 字符串反转 递归&#xff1a;参数的入栈模型 函数的调用模型 先被调用的模型后执行 向局部变量拷贝内存 传两个参数 做函数结果

【解析几何笔记】1.课程介绍与要求

听的是B站UP主唐小谦的解析几何课&#xff0c;万年的老计算机专业人也想学数学OWO。 1. 课程介绍与要求 前面都是老师的课程介绍&#xff0c;从板书证明开始记 【证明】在三角形ABC中&#xff0c;D为BC边的中点&#xff0c;证明&#xff1a; ∠ ABC 9 0 ∘ \angle \text{ABC…

出现 AWS ECS 错误:集群中未找到容器实例处理办法?

使用部署docker容器映像&#xff0c;但未创建 EC2 实例的情况下。出现下面错误提示。 “调用 RunTask 操作时发生客户端错误 (InvalidParameterException)&#xff1a;在您的集群中未找到容器实例。” 经过以下的步骤&#xff1a; 1.将 Docker 映像从 Ubuntu 推送到我的 Amazo…

c++ - 特殊类设计

文章目录 一、设计一个不允许拷贝的类二、设计一个只能在堆上实例对象的类三、设计一个只能在栈上创建对象的类四、设计一个不能被继承的类五、设计一个只能创建一个对象的类&#xff08;单例模式&#xff09; 一、设计一个不允许拷贝的类 1、方法一&#xff1a;将拷贝构造和赋…

在Windows上配置VSCode MinGW+CMake(包括C++多线程编程的两套API:posix和win32)

创建目录 首先&#xff0c;需要电脑上安装VSCode, 并且创建三个文件夹&#xff1a;cmake、MinGW-posix、MinGW-w32 文件下载 下载posix-seh posix和win32分别是c多线程变成的两套API,可根据不同需求安装&#xff0c;现在先下载配置环境需要的几个文件 百度搜索MinGW-64 点…

Django 链接MySQL数据库,报错Did you install mysqlclient?

据说是在python3里面&#xff0c;已经用pymysql替换了MySQLdb来进行数据库连接 所以&#xff0c;先安装pymysql pip install pymysql之后为了测试这个问题是否和mysql-connector-c有关系&#xff0c;我提前把这个应用给卸了。 之后在整个项目根目录的init文件内写入以下内容 im…

在docker中进行日志切割

先在Linux中安装docker&#xff0c;然后在docker中安装appnode面板&#xff0c;并进行docker网络端口映射。接着进入docker&#xff0c;进行nginx日志切割。 安装docker 第一步&#xff0c;卸载旧版本docker。 若系统中已安装旧版本docker&#xff0c;则需要卸载旧版本docke…

大模型在资源全生命周期的应用探索

资源全生命周期管理的传统价值 运营商的网络涉及接入网、数据网、承载网、核心网、传输网、无线网、光缆网、云专网、动力网、业务平台等十数类大专业。网络资源的全生命周期体现在以下六大生产活动环节&#xff1a;网络规划→网络设计→网络工程建设→网络资源的投入使用→网络…

数据安全防护措施有哪些?防数据泄露的10大措施丨让你一次性看够!

古时烽火传信&#xff0c;密语藏于竹简之间&#xff0c;以防外泄&#xff0c;保家国安宁。 今朝数字洪流&#xff0c;数据如织&#xff0c;信息安全之重&#xff0c;不亚于昔日之密信。 在信息爆炸的时代&#xff0c;数据安全防护犹如筑起铜墙铁壁&#xff0c;以防数据泄露之患…

想要数字人直播平台赚钱,前期源码部署要注意哪些要点?

随着人工智能时代的到来&#xff0c;数字人直播的应用频率不断升高&#xff0c;展现巨大收益潜力的同时&#xff0c;也让不少想要通过数字人源码厂商搭建数字人直播平台的创业者产生好奇&#xff0c;并开始从各方面打听数字人直播平台怎么赚钱等相关问题的答案。 本期&#xf…

开营啦!| 上海交通大学 AI for Bioengineering 暑期学校开营仪式圆满举行!

开营仪式 2024年8月12日 &#xff0c;“AI for Bioengineering暑期学校”在上海交通大学闵行校区理科群楼300号报告厅开幕。本次暑期学校吸引了来自国内外30余所高校&#xff08;包括芝加哥大学、曼彻斯特大学、哥伦比亚大学、爱丁堡大学、南加利福尼亚大学、北京大学、清华大…

element-plus的表单输入框有清除按钮的,文字输入前后宽度不一致怎么解决

输入内容之后多了一个可清除的图标&#xff0c;输入框的宽度也被撑开了 根据输入前后的dom对比发现&#xff0c;多了一个图标的span标签 :deep(.el-input__wrapper) {position: relative;.el-input__inner {padding-right: 18px;}.el-input__suffix {position: absolute;right:…

服务器重启后的端口占用分析及解决方案

个人名片 &#x1f393;作者简介&#xff1a;java领域优质创作者 &#x1f310;个人主页&#xff1a;码农阿豪 &#x1f4de;工作室&#xff1a;新空间代码工作室&#xff08;提供各种软件服务&#xff09; &#x1f48c;个人邮箱&#xff1a;[2435024119qq.com] &#x1f4f1…

Android Studio报错 Failed to transform ‘...‘ using Jetifier. Reason null

Android Studio报错 Failed to transform ‘…‘ using Jetifier. Reason null 问题描述&#xff1a; AndroidX提示Failed to transform ‘/…/’ using Jetifier. Reason: null. 解决方案&#xff1a; 在gradle.properties中&#xff0c;将 android.enableJetifiertrue改为…

uniapp 对于scroll-view滑动和页面滑动的联动处理

需求 遇到一个需求 解决方案 这个时候可以做一个内页面滑动判断 <!-- scroll-y 做true或者false的判断是否滑动 --> <view class"u-menu-wrap" style"background-color: #fff;"><scroll-view :scroll-y"data.isGo" scroll-wit…