OpenCV - C++实战(01) — OpenCV简介

news2024/11/15 14:01:18

目录

第1章  OpenCV简介

1.1 简介        

1.1.1 OpencV 库简介  

1.1.2 命名空间

1.2 OpenCV模块

1.3 装载、显示和存储图像

1.3.1 创建图像

1.3.2 读取图像

1.3.3 定义窗口与显示图像

1.3.4 图像翻转

1.3.5 保存图像

1.3.6 图像的复制

1.3.7 创建数组和向量

1.3.8 完整代码 

1.4 深入了解cv::Mat

1.4.1 cv::Mat的用途

1.4.2 cv::Mat的结构

1.4.3 cv::Mat常见的属性

1.4.4 构造函数


Github代码地址:https://github.com/Qinong/OpenCV.git

第1章  OpenCV简介

1.1 简介        

1.1.1 OpencV 库简介  

        OpencV 是一个开源的计算机视觉程序库,可在 Windows、 Linux、Mac、 Android、iOS等多种平台下运行。在 BSD 许可协议下,它可以用于学术应用和商业应用的开发,可随意使用、发布和修改。

        从第3版开始,OpenCV 已经分成了两个主要部分。第一部分是包含了成熟算法的 OpenCV 主源码库。此外还有一个独立的代码库,它包含了最近加人 OpenCV 的计算机视觉算法。如果只想使用 OpenCV 的核心两数,就不需要这个 contrib包;但如果要使用最先进的算法,可能需要这个额外的模块。实际上,本专栏介绍了其中的几种高级算法,因此需要准备好 contrib 模块一一到(https://github.com/opencv/opencv_contrib)即可下载额外的 OpenCV 模块。模块解压后,可以放在任何目录下,但需要能够在openev_contrib-master/modules 中找到。

1.1.2 命名空间

        在OpenCV 的C++ APT中,所有类和的数都在命名空间 cv 内定义。访问它们的方法共有两种,

        (1)第一种是在定义 main 两数前使用如下声明:using namespace cv;

        (2)第二种方法是根据命名空间规范给所有 OpenCV的类和两数加上前级cv::,本案例采用的就是这种方法,添加前缀后,代码中 OpenCV 的类和函数将更容易识别。

1.2 OpenCV模块

        OpenCV 库有众多的功能模块:opencv_core 模块包含库的核心功能,openev_imgproc 模块包含主要的图像处理函数,openev_ highgui模块提供读写图像和视频的函数以及一些用户交互函数等等,OpenCV 库主要功能模块如下表格。

        在使用某个模块之前,需要包含该模块对应的头文件。很多使用 OpenCV 的应用程序会在文件的开头处声明: 

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

        在学习 OpenCV 的过程中,你会逐生发现它的众多模块中包含的大量功能。

OpenCV主要模块
模块功能说明
core核心模块定义了多种数据结构(比如矩阵等)包括了重要的Mat模块。
imgproc图像处理模块包含了图像相关的基础功能(图像过滤、几何图像变换、其他图像转换等),以及一些衍生的高级功能(结构分析和形状描述符、运动分析与目标跟踪、特征检测、目标检测、图像分割等。
highgui高级图形用户界面模块比如图形交互界面,图像/视频文件的IO等。
calib3d摄像机标定与三维重建模块。包含了基本的多视角几何算法,单个立体摄像头标定,物体姿态估计,立体相似性算法,3D信息的重建等。
features2d特征提取和特征匹配模块用于特征检测和描述,关键点绘制函数和匹配功能绘制函数。
objdetect目标检测模块包含Cascade Classification(级联分类)和Latent SVM这两个部分。
gpugpu加速计算机视觉模块OpenCV的GPU模块利用GPU计算功能的类和函数, 使用NVIDIA公司的CUDA API实现,仅支持NVIDIA GPU。 OpenCV GPU模块包括工具函数,和高级算法,为开发利用GPU的快速视觉算法提供了强大的基础。
ml机器学习模块基本上是统计模型和分类算法,包含如下内容:统计模型、一般贝叶斯分类器、K-近邻 、支持向量机 、决策树 、提升、梯度提高树、随机树、超随机树、期望最大化、神经网络 。
stitching图像拼接模块包含如下部分:拼接流水线、特点寻找和匹配图像、估计旋转、自动校准、图片歪斜、接缝估测、曝光补偿、图片混合。

1.3 装载、显示和存储图像

1.3.1 创建图像

(1)创建一个空图像,大小为0  

cv::Mat image;

(2)指定矩阵大小,指定数据类型:

cv::Mat image(100,100,CV_8U);        // 三个参数为:矩阵行数,矩阵列数,数据类型;

(3)指定矩阵大小,指定数据类型,设置初始值:

cv::Mat image1(300,300,CV_8U, 100);        // 四个参数为:矩阵行数,矩阵列数,数据类型,初始值
cv::Mat image2(300,300,CV_8U, Scalar(0));    // 对于灰度图像:可以直接给出初始值,也可以使用Scalar()
cv::Mat image3(300,300,CV_8UC3, Scalar(0,0,255));    //对于三通道图像:使用Scalar()

1.3.2 读取图像

cv::Mat cv::imread(const String & filename,  
                   int flags=IMREAD_COLOR)
  •  filename:需要打开图片的路径,可以是绝对路径或者相对路径,路径中不能出现中文。
  •  flag:图像的通道和色彩信息(默认值为1)。

                cv::IMREAD_GRAYSCALE:读入灰度图片,可以直接写0 

                cv::IMREAD_UNCHANGED:读入完整图片,包括alpha通道,可以直接写-1 

                flag = -1, 8位深度,原通道

                flag = 0, 8位深度,1通道

                flag = 1, 8位深度,3通道

                flag = 2, 原深度, 1通道

                flag = 3, 原深度, 3通道

                flag = 4, 8位深度,3通道

(1)读取并转换为灰度图像

        在使用 imread装载图像时,可以通过设置选项把它转换为灰度图像。这个选项非常实用,因为有些计算机视觉算法是必须使用灰度图像的。在读人图像的同时进行色彩转换,可以提高运行速度并減少内存使用,做法如下所示:

image4 = cv::imread("Audi_S7.jpg");
image5 = cv::imread("Audi_S7.jpg", cv::IMREAD_GRAYSCALE);

         注意:当用 imread 打开路径指定不完整的图像时,imread 会自动采用默认目录。如果从控制台运行程序,默认目录显然就是当前控制台的目录;但是如果直按在 DDE中运行程序,默认目录通常就是项目文件所在的目录。因此,要确保图像文件在正确的目录下。

1.3.3 定义窗口与显示图像

(1)定义窗口

cv::namedWindow(const String & winname,int flags = WINDOW_AUTOSIZE )
  • winname:新建的窗口的名称。自己随便取。
  • flags:窗口的标识,一般默认为WINDOW_AUTOSIZE 。

                WINDOW_AUTOSIZE :窗口大小自动适应图片大小,并且不可手动更改。

                WINDOW_NORMAL: 用户可以改变这个窗口大小。

                WINDOW_OPENGL :窗口创建的时候会支持OpenGL。

(2)显示图像

cv::imshow(const String & winname,InputArray mat)	
  • winname:窗口的名称
  • mat:待显示的图像

1.3.4 图像翻转

void cv::flip(cv::InputArray src, cv::OutputArray dst, int flipCode = 0);
  • src:输入图像
  • dst:输出图像
  • flipCode:沿y-轴翻转, 0: 沿x-轴翻转, <0: x、y轴同时翻转 
cv::flip(image4,image6,1); 

1.3.5 保存图像

cv::imwrite(const String& filename, InputArray img,
            const std::vector<int>& params = std::vector<int>());
  • filename:图片名称
  • img:Mat类型的图像数据,
  • params:特定格式保存的参数编码,默认值std::vector<int>()  所以一般可以不写 

1.3.6 图像的复制

// 所有图像指向同一个数据块,会影响原数据块
cv::Mat image7(image4);
image7= image4;
// 复制图像的副本,不会影响原数据
cv::Mat image8= image4.clone();
image8.copyTo(image4);
// 复制图像,两者的数据类型不一定相同,转换为浮点型图像[0,1]
image4.convertTo(image9,CV_32F,1/255.0,0.0);

1.3.7 创建数组和向量

cv::Matx33d matrix(3.0, 2.0, 1.0,
                   2.0, 1.0, 3.0,
                   1.0, 2.0, 3.0);    // 创建3x3双精度型矩阵
cv::Matx31d vector(5.0, 1.0, 3.0);    // 创建3x1双精度型矩阵(向量)
cv::Matx31d result = matrix*vector;    // 相乘

1.3.8 完整代码 

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

int main() {
    // code1
	// 创建图像
    cv::Mat image1(100,100,CV_8U, 100);    // 四个参数为:矩阵行数,矩阵列数,数据类型,初始值
    cv::Mat image2(100,100,CV_8U, cv::Scalar(0));    // 对于灰度图像:可以直接给出初始值,也可以使用Scalar()  
	cv::Mat image3(240,320,CV_8UC3,cv::Scalar(0,0,255)); //对于三通道图像,创建一个红色的图像,通道顺序为BGR
	// or:
	// cv::Mat image3(cv::Size(320,240),CV_8UC3);
	// image3= cv::Scalar(0,0,255);

	cv::imshow("Image1", image1); // 显示图像
    cv::imshow("Image2", image2); // 显示图像
    cv::imshow("Image3", image3); // 显示图像
	cv::waitKey(0); // 等待按键

    // code2
	// 读取图像
    cv::namedWindow(image4,WINDOW_AUTOSIZE )
    cv::namedWindow(image5,WINDOW_AUTOSIZE )
    image4 = cv::imread("Audi_S7.jpg", cv::IMREAD_GRAYSCALE);
    image5 = cv::imread("Audi_S7.jpg", cv::IMREAD_GRAYSCALE);
	cv::imshow("Image4", image4); 
    cv::imshow("Image5", image5); 
	cv::waitKey(0); 

    // code3
	// 转换图像
	cv::flip(image4,image6,1); 
    cv::imshow("Image6", image6); 
	cv::waitKey(0);

    // code4
    // 图像的复制
	// 所有图像指向同一个数据块,会影响原数据块
	cv::Mat image7(image4);
	image7= image4;
	// 复制图像的副本,不会影响原数据
	cv::Mat image8= image4.clone();
	image8.copyTo(image4);
	// 复制图像,两者的数据类型不一定相同,转换为浮点型图像[0,1]
	image4.convertTo(image9,CV_32F,1/255.0,0.0);


	// code5
    // 数组和向量
	// 创建3x3双精度型矩阵
	cv::Matx33d matrix(3.0, 2.0, 1.0,
		               2.0, 1.0, 3.0,
		               1.0, 2.0, 3.0);
	// 创建3x1双精度型矩阵(向量)
	cv::Matx31d vector(5.0, 1.0, 3.0);
	// 相乘
	cv::Matx31d result = matrix*vector;
	std::cout << result;
	cv::waitKey(0); 
	return 0;
}

1.4 深入了解cv::Mat

1.4.1 cv::Mat的用途

        (1)存储图像(图像可以看成一个矩阵)

        (2)存储矩阵

1.4.2 cv::Mat的结构

        cv::Mat有两个必不可少的组成部分,Mat头部和Mat数据块两部分。Mat头部分大小是固定的,包含矩阵的大小,存储的方式,矩阵存储的地址等,数据部分是一个指向矩阵包含像素值的指针(data)。

1.4.3 cv::Mat常见的属性

        要熟练使用OpenCV,最重要的就是学会Mat数据结构,在OpenCV中Mat被定义为一个类,把它看作一个数据结构,以矩阵的形式来存储数据的,Mat常见的属性如下:

属性功能
flagsMat中的一些标记,一共32位,从低位到高位,包含了数据类型(0-2位)、通道数(3-11)等
data指向数据的指针
dims矩阵的维度
rows矩阵行数,维度大于2 则rows = -1
cols矩阵列数,维度大于2 则cols = -1
channels通道数量,若图像为RGB、HSV等三通道图像,则channels = 3;若图像为灰度图,则为单通道,则channels = 1
typetype() 表示了矩阵中元素的类型以及矩阵的通道个数
 depth矩阵中元素的一个通道的数据类型,这个值和type是相关的。例如 type为 CV_16SC2,一个2通道的16位的有符号整数。那么,depth则是CV_16S。depth也是一系列的预定义值,将type的预定义值去掉通道信息就是depth值。
size数据内是一维数组,有个两元素,size[0]矩阵的行数,size[1]矩阵的列数
elemSize

矩阵中每一个元素的数据大小,elemSize = channels * depth / 8 。例如:type是CV_8UC3,elemSize = 3 * 8 / 8 = 3bytes

elemSize1

单通道的矩阵元素占用的数据大小,elemSize1 = depth / 8。例如:type是CV_8UC3,elemSize1 = 8 / 8 = 1bytes

step数据内是一维数组,有个两元素,step[0]矩阵一行共多少字节,step[1]表示矩阵一个元素多少字节
refcount矩阵数据的引用次数,浅拷贝得到的矩阵同步这个参数,同时增加或减少,可以用来判断有多少矩阵使用该矩阵的数据内容

        type()数据类型:type() 表示了矩阵中元素的类型以及矩阵的通道个数,它是一系列的预定义的常量。其命名规则为CV_(位数)+(数据类型)+(通道数)。

                U(unsigned integer):无符号整数

                S(signed integer):有符号整数

                F(float): 浮点数

        例如:CV_8UC3,可拆分为:CV_:type的前缀,8U:8位无符号整数(depth),C3:3通道(channels)

type数据类型
CV_8UC1、CV_8UC2、CV_8UC3uchar
CV_8SC1、CV_8SC2、CV_8SC3char
CV_16UC1、CV_16UC2、CV_16UC3ushort
CV_16SC1、CV_16SC2、CV_16SC3short
CV_32SC1、CV_32SC2、CV_32SC3int
CV_32FC1、CV_32FC2、CV_32FC3float
CV_64FC1、CV_64FC2、CV_64FC3double

1.4.4 构造函数

构造函数类型构造函数说明
Mat()无参构造方法
Mat(int rows, int cols, int type)创建行数为 rows,列数为 col,类型为 type 的图像
Mat(Size size, int type)创建大小为 size,类型为 type 的图像
Mat(int rows, int cols, int type, const Scalar& s)创建行数为 rows,列数为 col,类型为 type 的图像,并将所有元素初始化为值 s
Mat(Size size, int type, const Scalar& s)创建大小为 size,类型为 type 的图像,并将所有元素初始化为值 s
 Mat(const Mat& m)将m赋值给新创建的对象,此处不会对图像数据进行复制,m和新对象共用图像数据,属于浅拷贝
Mat(int rows, int cols, int type, void* data, size_t step=AUTO_STEP)创建行数为rows,列数为col,类型为type的图像,此构造函数不创建图像数据所需内存,而是直接使用data所指内存,图像的行步长由 step指定
Mat(Size size, int type, void* data, size_t step=AUTO_STEP)创建大小为size,类型为type的图像,此构造函数不创建图像数据所需内存,而是直接使用data所指内存,图像的行步长由step指定
Mat(const Mat& m, const Range& rowRange, const Range& colRange)创建的新图像为m的一部分,具体的范围由rowRange和colRange指定,此构造函数也不进行图像数据的复制操作,新图像与m共用图像数据
Mat::Mat(const Mat& m, const Rect& roi)创建的新图像为m的一部分,具体的范围roi指定,此构造函数也不进行图像数据的复制操作,新图像与m共用图像数据

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

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

相关文章

01、前端使用 thymeleaf 后,视图页面找不到---Cannot resolve MVC View ‘xxxxx前端页面‘

Cannot resolve MVC View ‘xxxxx前端页面’ 没有找到对应的mvc的前端页面。 代码&#xff1a;前端这里引入了 thymeleaf 模板 解决&#xff1a; 需要添加 thymeleaf 的依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>s…

APP调用bindService的跨进程调用过程

app执行bindService时会经过如下8次跨系统进程调用过程&#xff1a; 第1步&#xff1a;通过AMS.getService跨进程调用 第2步&#xff1a;AMS返回它的IBinder 第3步&#xff1a;通过AMS的IBinder调用AMS的bindService方法 第4步&#xff1a;而AMS存放有Server端的IBinder&…

华为数通方向HCIP-DataCom H12-821题库(单选题:101-120)

第101题 可用于多种路由协议,由 ​​if-match​​​和 ​​apply​​子句组成的路由选择工具是 A、​​route-policy​​ B、​​IP-Prefix​​ C、​​commnityfilter​​ D、​​as-path-filter​​ 答案&#xff1a;A 解析&#xff1a; Route-policy&#xff08;路由策…

扫雷小游戏

目录 一.扫雷小游戏 二.游戏主体一览 ​编辑 三.模块化设计扫雷游戏 3.1打印欢迎菜单 3.2创建两个二维数组 3.3棋盘稍加修改 3.4布置雷 3.5排查雷 四.游戏总体代码 4.1game.h头文件 4.2game.c函数实现源文件 4.3游戏main函数主体 五.游戏效果图 一.扫雷小游戏 这是…

EB Tresos第一个项目报13026

EB项目创建 前期的准备工作见以上这篇文章&#xff0c;不做过多叙述&#xff1b;但是点击Generate Project会报错&#xff0c;报错如下&#xff1a; Code generator finished. Errors “1” Warnings “0” 然后点击 Problems View 查看提示&#xff0c;提示如下&#xff1a; …

大数据:AI大模型对数据分析领域的颠覆(文末送书)

随着数字化时代的到来&#xff0c;大数据已经成为了各行各业中不可或缺的资源。然而&#xff0c;有效地分析和利用大数据仍然是一个挑战。在这个背景下&#xff0c;OpenAI推出的Code Interpreter正在对数据分析领域进行颠覆性的影响。 如何颠覆数据分析领域&#xff1f;带着这…

为什么Python列表和字典前面会加星号(**)?

目录标题 前言一、列表&#xff08;list&#xff09;、元组&#xff08;tuple&#xff09;前面加星号*二、字典&#xff08;dict&#xff09;前面加两星号**尾语 前言 嗨喽~大家好呀&#xff0c;这里是魔王呐 ❤ ~! Python 中&#xff0c;单星号*和双星号**除了作为“乘”和“…

视频汇聚/云存储/安防监控AI视频智能分析平台——明厨亮灶解决方案

人工智能技术已经越来越多地融入到视频监控领域中&#xff0c;近期我们也发布了基于AI智能视频云存储/安防监控视频AI智能分析平台的众多新功能&#xff0c;该平台内置多种AI算法&#xff0c;可对实时视频中的人脸、人体、物体等进行检测、跟踪与抓拍&#xff0c;支持人脸检测、…

算法 for GAMES

栈 #include <iostream> #include <stack>int main() {std::stack<int> intStack;// 压入元素到堆栈intStack.push(5);intStack.push(10);intStack.push(15);// 查看堆栈顶部元素std::cout << "Top element: " << intStack.top() <…

虚虚实实,让敌人难以琢磨

与敌作战&#xff0c;虚虚实实&#xff0c;难以琢磨 【安志强趣讲《孙子兵法》第20讲】 第六篇&#xff1a;虚实篇 【全篇趣讲白话】 打仗就是要虚虚实实&#xff0c;让敌人难以琢磨。 【原文】 孙子曰&#xff1a;凡先处战地而待敌者佚&#xff0c;后处战地而趋战者劳。故善…

Locked勒索病毒:最新变种locked袭击了您的计算机?

导言&#xff1a; 在数字时代&#xff0c;一场隐秘的威胁正悄然而至&#xff0c;它的名字是.locked勒索病毒。这个黑暗的存在以其狡猾的攻击方式和致命的数据封锁能力&#xff0c;威胁着我们的数字生活。本文91数据恢复将带您深入了解.locked勒索病毒的本质&#xff0c;探索恢…

【Day-20慢就是快】代码随想录-栈与队列-有效的括号

给定一个只包括 ‘(’&#xff0c;‘)’&#xff0c;‘{’&#xff0c;‘}’&#xff0c;‘[’&#xff0c;‘]’ 的字符串&#xff0c;判断字符串是否有效。 有效字符串需满足&#xff1a; 左括号必须用相同类型的右括号闭合。 左括号必须以正确的顺序闭合。 注意空字符串可被…

Redis7安装

1. 使用什么系统安装redis 由于企业里面做Redis开发&#xff0c;99%都是Linux版的运用和安装&#xff0c;几乎不会涉及到Windows版&#xff0c;上一步的讲解只是为了知识的完整性&#xff0c;Windows版不作为重点&#xff0c;同学可以下去自己玩&#xff0c;企业实战就认一个版…

会声会影2023全新中文专业版下载安装教程

熟练使用会声会影视频编辑工具&#xff0c;对视频创作过程的帮助是极大的。大家可以放心大胆地去研究会声会影的视频编辑技巧&#xff0c;会声会影2023与以往版本会声会影版本最大的区别是&#xff1a;账户制管理。可以通过账户添加或移除设备&#xff0c;非常便捷。该软件一直…

Vue2向Vue3过度Vuex核心概念mutations

目录 1 核心概念-mutations1.定义mutations2.格式说明3.组件中提交 mutations4.练习5.总结 2 带参数的 mutations1.目标&#xff1a;2.语法2.1 提供mutation函数&#xff08;带参数&#xff09;2.2 提交mutation 3 练习-mutations的减法功能1.步骤2.代码实现 4 练习-Vuex中的值…

05.Image Captioning with Semantic Attention

目录 前言泛读摘要Introduction创新/贡献点Related Work 精读输入的注意力模型输出的注意力模型模型学习视觉属性/概念预测实验MS-COCO的性能实验分析 Conclusion 代码略 前言 本课程来自深度之眼《多模态》训练营&#xff0c;部分截图来自课程视频。 文章标题&#xff1a;Ima…

多维时序 | Matlab实现BiLSTM-Adaboost和BiLSTM多变量时间序列预测对比

多维时序 | Matlab实现BiLSTM-Adaboost和BiLSTM多变量时间序列预测对比 目录 多维时序 | Matlab实现BiLSTM-Adaboost和BiLSTM多变量时间序列预测对比预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 多维时序 | Matlab实现BiLSTM-Adaboost和BiLSTM多变量时间序列预…

用AI + Milvus Cloud搭建着装搭配推荐系统教程

以下函数定义了如何将图像转换为向量并插入到 Milvus Cloud 向量数据库中。代码会循环遍历所有图像。(注意:如果需要开启 Milvus Cloud 全新特性动态 Schema,需要修改代码。) 查询向量数据库 以下代码演示了如何使用输入图像查询 Milvus Cloud 向量数据库,以检索和上传…

智能文件批量改名工具,覆盖复制时轻松处理相同文件名!

亲爱的用户们&#xff0c;您是否在批量复制文件时常常被相同文件名困扰&#xff0c;手动一个个改名繁琐又费时&#xff1f;现在&#xff0c;我们为您推出一款智能的文件批量改名工具&#xff0c;帮助您轻松处理复制时的相同文件名&#xff0c;让文件管理更从容&#xff01; 首…

建设全球研发中心城市,长沙政协将会发挥怎样的作用?

政协力量&#xff0c;会如何推动一座城市的发展&#xff1f;在全国各大城市都力“拼经济、搞创新”的时代大背景下&#xff0c;人民政协的力量会如何助推长沙建设全球研发中心城市呢&#xff1f; 这是笔者此前一直很好奇的两个问题。8月24日&#xff0c;一场由长沙市政协举办的…