opencv c++编程基础

1、图片的本质

图像在 OpenCV 中的本质

在 OpenCV 中,图像被表示为一个多维数组,其中每个元素对应于图像中的单个像素。图像的维度取决于其通道数和像素数。

  • **通道数:**图像可以有多个通道,每个通道存储图像的不同信息。例如,彩色图像通常有 3 个通道(红色、绿色和蓝色),而灰度图像只有一个通道。
  • **像素数:**图像的像素数决定了其宽度和高度。

图像存储方式

OpenCV 中的图像通常以以下格式存储:

  • **Mat:**这是 OpenCV 中最常用的图像表示形式。Mat 是一个多维数组,可以存储不同类型的图像数据(例如,uint8、float32 等)。
  • **IplImage:**这是一个旧的图像表示形式,在 OpenCV 2.0 之前使用。它与 Mat 类似,但有一些限制。

Mat 中图像的存储

Mat 中的图像数据以行优先顺序存储。这意味着图像的第一个维度对应于行,而第二个维度对应于列。对于一个 3 通道的彩色图像,Mat 中的元素顺序如下:

[B00, G00, R00, B01, G01, R01, ..., Bmn, Gmn, Rmn]

其中:

  • BGR 表示蓝色、绿色和红色通道
  • mn 是图像的高度和宽度

通道的顺序

OpenCV 中图像的通道顺序通常为 BGR(蓝色、绿色、红色)。这与其他一些图像处理库(如 PIL)中使用的 RGB 顺序不同。

其他图像存储格式

除了 Mat 和 IplImage 之外,OpenCV 还支持其他图像存储格式,包括:

  • **UMat:**一种优化的 Mat,可利用 GPU 加速。
  • **cuda::GpuMat:**一种专用于 GPU 处理的 Mat。
  • **std::vector<uchar>:**一种使用标准 C++ 向量存储图像数据的格式。

2、Mat

从文件读取图片并显示

#include <iostream>
#include "opencv2/core.hpp"
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>using namespace std;
using namespace cv;int main(){Mat image;image = imread("firefox.png");      //imread()读取图片if(!image.empty()){imshow("1",image);              //imshow展示图片,前面为展示名,后面为图片。waitKey(0);}destroyAllWindows();return 0;
}

从文件读取图片并显示

waitKey(0) 是 OpenCV 中的一个函数,用于等待用户按下一个键。它有以下作用:

  • 暂停程序执行:waitKey(0) 会暂停程序执行,直到用户按下一个键。这通常用于在显示图像或视频时让用户有机会查看内容。
  • **获取按键:**当用户按下一个键时,waitKey(0) 会返回该键的 ASCII 码。这可用于检测用户输入并做出相应操作。
  • 无限等待:waitKey(0) 的参数为 0 表示无限等待。这意味着程序将一直暂停,直到用户按下一个键。

使用示例:

cv::Mat image = cv::imread("image.png");cv::imshow("Image", image);cv::waitKey(0);

在上面的示例中,程序将暂停执行,直到用户按下一个键。然后,程序将继续执行,关闭图像窗口并释放资源。

注意:

  • waitKey(0) 是一个阻塞函数,这意味着它会阻止程序执行,直到用户按下一个键。
  • 如果您不希望程序暂停执行,可以使用 waitKey(1),它将等待 1 毫秒的按键输入。如果在此期间没有按键输入,程序将继续执行。
  • waitKey(0) 通常用于交互式应用程序,例如图像查看器或视频播放器。

展示结果:

图片大小resize函数

resize后保存为新图片

#include <iostream>
#include "opencv2/core.hpp"
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/core/mat.hpp>
#include <opencv2/imgproc.hpp>using namespace std;
using namespace cv;int main(){Mat image;image = imread("firefox.png");      //imread()读取图片if(!image.empty()){imshow("image",image);              //imshow展示图片,前面为展示名,后面为图片。waitKey(0);}// destroyAllWindows();Mat resize_image;resize(image, resize_image, Size(), 1, 0.5);     //resize()改变大小 前为高度 后为宽度if(!image.empty()){imshow("resize",resize_image);             waitKey(0);}imwrite("resize.png",resize_image);     //imwrite(文件名,图片)写入文件   需要指定扩展名,否则exceptiondestroyAllWindows(); return 0;
}

图片旋转

getRotationMatrix2D()和warpAffine()函数

 Mat rotated_image;double angle = 90;                                               //旋转角度Point2f center(image.cols / 2.0, image.rows / 2.0);              //获取旋转中心Mat rotation_matix = getRotationMatrix2D(center, angle, 0.5);    //getRotationMatrix2D()计算旋转矩阵 参数:旋转中心、旋转角度、放大倍数warpAffine(image, rotated_image, rotation_matix, image.size());  //warpAffine旋转图片  参数:原图、目标图片、旋转矩阵、生成图片的大小if(!rotated_image.empty()){imshow("rotate",rotated_image);             waitKey(0);}imwrite("rotate.png",rotated_image);   destroyAllWindows(); 

Point2f 是 OpenCV 中的一个结构,用于表示二维点。它包含两个浮点成员:xy,分别表示点的横坐标和纵坐标。

声明:

struct Point2f {float x;float y;};

构造函数:

  • **Point2f():**创建一个默认构造的 Point2f,其中 xy 都为 0。
  • **Point2f(float x, float y):**创建一个 Point2f,其中 xy 设置为指定的值。

图片平移

warpAffine()函数和平移矩阵

平移矩阵:

平移矩阵是一个 2x3 的仿射变换矩阵,

[ 1 0 tx ][ 0 1 ty ]

其中:

  • tx 是水平平移量。
  • ty 是垂直平移量。

为tx提供正值将使图像向右移动,而负值将使图像向左移动。

同样,ty值为正值时,图像会向下平移,而ty值为负值时,图像会向上平移。

warpAffine()本质是仿射变换。

3、这里可以看到调整了大小或者平移过后窗口大小存在一些问题,:

可以使用 OpenCV 的 namedWindow() 函数来设置 imshow() 窗口的大小。

示例:

cv::namedWindow("Image", cv::WINDOW_NORMAL); // 创建一个可调整大小的窗口cv::imshow("Image", image);// 设置窗口大小cv::resizeWindow("Image", 640, 480);

参数:

  • **window_name:**窗口的名称。
  • **flag:**一个标志,指定窗口的类型。WINDOW_NORMAL 创建一个可调整大小的窗口。

其他标志:

  • **WINDOW_AUTOSIZE:**窗口大小自动调整为图像大小。
  • **WINDOW_FREERATIO:**窗口可以自由调整大小,而无需保持图像的宽高比。
  • **WINDOW_FULLSCREEN:**窗口以全屏模式显示。

注意:

  • namedWindow() 函数必须在 imshow() 函数之前调用。
  • 窗口大小只能在创建窗口后设置。
  • 窗口大小设置仅适用于可调整大小的窗口(即使用 WINDOW_NORMAL 标志创建的窗口)。

图片拼接

在 OpenCV 中,可以使用 hconcat()vconcat() 函数水平和垂直拼接图像。

水平拼接(并排):

cv::Mat image1 = cv::imread("image1.png");cv::Mat image2 = cv::imread("image2.png");cv::Mat拼接图像;cv::hconcat(std::vector[cv::Mat](cv::Mat){image1, image2},拼接图像);

垂直拼接(上下):

cv::Mat image1 = cv::imread("image1.png");cv::Mat image2 = cv::imread("image2.png");cv::Mat拼接图像;cv::vconcat(std::vector[cv::Mat](cv::Mat){image1, image2},拼接图像);

参数:

  • **images:**要拼接的图像的向量。
  • **拼接图像:**用于存储拼接图像的 Mat 对象。

注意:

  • 要拼接的图像必须具有相同的通道数和深度。
  • hconcat()vconcat() 函数将自动调整图像大小以匹配。
  • 拼接图像的尺寸取决于要拼接的图像的尺寸和拼接的方向。

图片翻转

在 OpenCV 中,可以使用 flip() 函数水平或垂直翻转图像。

水平翻转:

cv::Mat image = cv::imread("image.png");cv::Mat flipped_image;// 水平翻转cv::flip(image, flipped_image, 1);

垂直翻转:

cv::Mat image = cv::imread("image.png");cv::Mat flipped_image;// 垂直翻转cv::flip(image, flipped_image, 0);

参数:

  • **image:**要翻转的图像。
  • **flipped_image:**用于存储翻转后图像的 Mat 对象。
  • **flipCode:**指定翻转方向的标志。

flipCode 标志:

  • **0:**垂直翻转
  • **1:**水平翻转
  • **-1:**水平和垂直翻转

注意:

  • 翻转图像不会修改原始图像。
  • 翻转图像可能会导致图像质量下降,尤其是在翻转包含文本或其他非对称特征的图像时。

高斯模糊

在 OpenCV 中,可以使用 GaussianBlur() 函数对图像应用高斯模糊。

示例

cv::Mat image = cv::imread("image.png");
cv::Mat blurred_image;// 高斯模糊
cv::GaussianBlur(image, blurred_image, cv::Size(5, 5), 0);

参数

**image:**要模糊的图像。

**blurred_image:**用于存储模糊后图像的 Mat 对象。

**kernel_size:**模糊核的大小。它必须是一个奇数。

**sigmaX:**高斯核在 x 方向的标准偏差。如果为 0,则从 kernel_size 计算。

注意

高斯模糊是一种线性滤波器,它使用高斯核来平滑图像。

高斯核是一个钟形曲线,其中心权重最大,边缘权重逐渐减小。

kernel_size 越大,模糊效果越强。

sigmaX 越大,模糊效果越明显。

高斯模糊可能会导致图像质量下降,尤其是边缘和细节丢失。

4、完整代码:

#include <iostream>
#include "opencv2/core.hpp"
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/core/mat.hpp>
#include <opencv2/imgproc.hpp>using namespace std;
using namespace cv;int main(){Mat image;image = imread("firefox.png");      //imread()读取图片if(!image.empty()){namedWindow("image", cv::WINDOW_NORMAL);imshow("image",image);              //imshow展示图片,前面为展示名,后面为图片。resizeWindow("image", 640, 480);waitKey(0);}// destroyAllWindows();Mat resize_image;resize(image, resize_image, Size(), 1, 0.5);     //resize()改变大小 前为高度 后为宽度if(!resize_image.empty()){namedWindow("resize", cv::WINDOW_NORMAL);imshow("resize",resize_image);             resizeWindow("resize", 640, 480);waitKey(0);}imwrite("resize.png",resize_image);     //imwrite(文件名,图片)写入文件   需要指定扩展名,否则exception// destroyAllWindows(); Mat rotated_image;double angle = 90;                                               //旋转角度Point2f center(image.cols / 2.0, image.rows / 2.0);              //获取旋转中心Mat rotation_matix = getRotationMatrix2D(center, angle, 0.5);    //getRotationMatrix2D()计算旋转矩阵 参数:旋转中心、旋转角度、放大倍数warpAffine(image, rotated_image, rotation_matix, image.size());  //warpAffine旋转图片  参数:原图、目标图片、旋转矩阵、生成图片的大小if(!rotated_image.empty()){namedWindow("rotate", cv::WINDOW_NORMAL);imshow("rotate",rotated_image);    resizeWindow("rotate", 640, 480);         waitKey(0);}imwrite("rotate.png",rotated_image);   // destroyAllWindows(); Mat translated_image;                    float tx = float(image.rows) / 4;                           //平移距离 1/4 float ty = float(image.cols) / 4;                           //平移距离 1/4 float warp_values[] = { 1.0, 0.0, tx, 0.0, 1.0, ty };       //构建平移矩阵Mat translation_matrix = Mat(2, 3, CV_32F, warp_values);    //构建平移矩阵warpAffine(image, translated_image, translation_matrix, image.size());   //warpAffine平移图片if(!translated_image.empty()){namedWindow("translated", cv::WINDOW_NORMAL);imshow("translated",translated_image); resizeWindow("translated", 640, 480);               waitKey(0);}imwrite("translated.png",translated_image);   destroyAllWindows(); Mat flipped_image_row;Mat flipped_image_col;flip(image, flipped_image_row, 1); //水平翻转flip(image, flipped_image_col, 0); //垂直翻转imshow("row",flipped_image_row);imshow("col",flipped_image_col);imshow("image",image);waitKey(0);destroyAllWindows(); Mat blurred_image;GaussianBlur(image, blurred_image, cv::Size(99,99), 0);imshow("blurred_image",blurred_image);waitKey(0);destroyAllWindows(); return 0;
}

简单四宫格:

#include <opencv2/core/mat.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>using namespace cv;int main(){Mat image = imread("firefox.png");// Mat image_45;Mat image_90;Mat image_180;Mat image_270;// double angle_45 = 45;double angle_90 = 90;   double angle_180 = 180;double angle_270 = 270;                                            Point2f center(image.cols / 2.0, image.rows / 2.0);              // Mat rotation_matix_45 = getRotationMatrix2D(center, angle_45, 1.0);    // warpAffine(image, image_45, rotation_matix_45, image.size()); Mat rotation_matix_90 = getRotationMatrix2D(center, angle_90, 1.0);    warpAffine(image, image_90, rotation_matix_90, image.size()); Mat rotation_matix_180 = getRotationMatrix2D(center, angle_180, 1.0);    warpAffine(image, image_180, rotation_matix_180, image.size()); Mat rotation_matix_270 = getRotationMatrix2D(center, angle_270, 1.0);    warpAffine(image, image_270, rotation_matix_270, image.size()); Mat row_1;Mat row_2;Mat image_4x4;hconcat(std::vector<cv::Mat>{image, image_90},row_1);                 //横向拼接hconcat(std::vector<cv::Mat>{image_270, image_180},row_2);            //纵向拼接vconcat(std::vector<cv::Mat>{row_1, row_2},image_4x4);imshow("4x4",image_4x4);waitKey(0);destroyAllWindows();return 0;
}

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

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

相关文章

李廉洋:5.22黄金原油高位震荡,今日最新行情分析策略。

黄金消息面分析&#xff1a;根据4月份的通胀数据&#xff0c;加拿大央行6月5日降息应该是“理所当然的”。加拿大的整体通货膨胀率在4月份降至2.7%&#xff0c;为自2021年初以来的最低水平&#xff0c;核心CPI中加拿大央行的两项首选数据均降至3%以下。加拿大央行在决定降息之前…

鸿蒙学习第一课--认识目录结构

项目结构介绍 module.json5 src > main > module.json5&#xff1a;Stage模型模块配置文件。主要包含HAP包的配置信息、应用/服务在具体设备上的配置信息以及应用/服务的全局配置信息。具体的配置文件说明&#xff0c;详见module.json5配置文件。 资源分类和访问 关于s…

awk编辑器

目录 工作原理 命令格式 普通格式 BEGIN格式 语句循环格式 awk常见的内建变量&#xff08;可直接用&#xff09; 按行打印行内容 统计行数量 按字段输出文本 通过管道、双引号调用 Shell 命令 awk编辑器是一种流编辑器 工作原理 逐行读取文本,默认以空格或tab键为分…

java第十八课 —— 重载、可变参数

方法重载 基本介绍 java 中允许同一个类中&#xff0c;多个同名方法的存在&#xff0c;但要求形参列表不一致&#xff01; 比如&#xff1a;System.out.println(); out 是 PrintStream 类型 重载的好处 减轻了起名的麻烦减轻了记名的麻烦 注意事项和使用细节 方法名&…

【Vue】Vue2中的Vuex

目录 Vuex介绍Vuex 中的核心概念 在vue2中使用Vuex安装 Vuex创建一个 Vuex Store在 Vue 实例中使用 Vuex编写 Vuex 的 state、mutations 和 actions在组件中使用 Vuex Vuex的核心State组件中获取 Vuex 的状态mapState 辅助函数对象展开运算符 Getter基本使用示例 通过属性访问通…

从多站点到多活,XEOS 对象数据容灾能力再提升

近日&#xff0c; XSKY SDS V6.4 新版本发布&#xff0c;其中 XEOS V6.4 全新升级并完善了统一命名空间功能&#xff0c;更进一步增强和完善了异地容灾方案&#xff0c;配合强一致代理读&#xff0c;可以实现异地多活&#xff1b;同时大幅降低管理复杂度&#xff0c;有效降低容…

TikTok电商带货特训营,跟随时代潮流,跨境掘金(8节课)

课程内容&#xff1a; 1-先导课 2-一、店铺运营认知与思路 3-二、店铺风控注意事项 4-三、美区Tiktok前期工作-1店铺入驻模式 5-三、美区Tiktok前期工作-2指纹浏览器介绍 6-三、美区Tiktok前期工作-4绑定电话号码 7-三、美区Tiktok前期工作-5添加仓库地址 8-三、美区Ti…

【秒杀系统】从零开始打造简易秒杀系统(一):防止超卖

【秒杀系统】从零开始打造简易秒杀系统&#xff08;一&#xff09;&#xff1a;防止超卖 前言 大家好&#xff0c;好久不发文章了。&#xff08;快一个月了- -&#xff09;最近有很多学习的新知识想和大家分享&#xff0c;但无奈最近项目蛮忙的&#xff0c;很多文章写了一半搁…

深入Java:JSON解析与操作的艺术

哈喽&#xff0c;大家好&#xff0c;我是木头左&#xff01; 一、初识JSON&#xff1a;数据格式的优雅舞者 在现代Web开发中&#xff0c;JSON&#xff08;JavaScript Object Notation&#xff09;以其轻量级和易于阅读的特点成为了数据交换的首选格式。它基于JavaScript的一个…

FreeRTOS_信号量_学习笔记

信号量的特性 消息队列用于传输多个数据&#xff0c;但是有时候我们只需要传递状态&#xff0c;这个状态值需要用一个数值表示。套用队列笔记中的流水线例子&#xff0c;可以理解为流水线上工件的数量。 信号&#xff1a;起通知作用 量&#xff1a;还可以用来表示资源的数量 当…

打印机手动双面打印技巧

一、WORD和PDF &#xff08;1&#xff09;首先选择要打印的页面范围&#xff0c;然后选择仅奇数页打印 &#xff08;2&#xff09;将打印完的纸张翻过来&#xff0c;白纸朝上&#xff0c;纸张的头部先放入打印机 &#xff08;3&#xff09;选择要打印的页面范围&#xff0c;然…

大模型部署_书生浦语大模型 _作业2

本节课可以让同学们实践 4 个主要内容&#xff0c;分别是&#xff1a; 1、部署 InternLM2-Chat-1.8B 模型进行智能对话 1.1安装依赖库&#xff1a; pip install huggingface-hub0.17.3 pip install transformers4.34 pip install psutil5.9.8 pip install accelerate0.24.1…

Elasticsearch之文本分析

文本分析基本概念 官网&#xff1a;Text analysis | Elasticsearch Guide [7.17] | Elastic 官网称为文本分析&#xff0c;这是对文本进行一直分析处理的方式&#xff0c;基本处理逻辑是为按照预先制定的分词规则&#xff0c;把原本的文档进行分割成多个小颗粒度的词项&#x…

如何给出好的“文言一心”指令?

一、文言一心是什么&#xff1f; 在现代技术背景下&#xff0c;“文言一心”还是百度公司创建的一款大语言模型。这款模型基于飞桨深度学习平台和文心知识增强大模型&#xff0c;并拥有强大的中文语料库&#xff0c;可以理解和生成富含文化内涵和哲理的文本内容。其核心技术架构…

社区医院|基于SprinBoot+vue的社区医院管理服务系统(源码+数据库+文档)

社区医院管理服务系统 目录 基于SprinBootvue的社区医院管理服务系统 一、前言 二、系统设计 三、系统功能设计 1系统功能模块 2管理员功能模块 3用户功能模块 4医生功能模块 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取…

看花眼,眼花缭乱的主食冻干到底应该怎么选?靠谱的主食冻干分享

随着科学养猫知识的普及&#xff0c;主食冻干喂养越来越受到养猫人的青睐。主食冻干不仅符合猫咪的饮食天性&#xff0c;还能提供均衡的营养&#xff0c;有助于维护猫咪的口腔和消化系统健康。许多猫主人认识到了主食冻干喂养的诸多益处&#xff0c;计划尝试这种喂养方式&#…

C++面向对象程序设计 - 标准输出流

在C中&#xff0c;标准输出流通常指的是与标准输出设备&#xff08;通常是终端或控制台&#xff09;相关联的流对象。这个流对象在C标准库中被定义为std::cout、std::err、std::clog&#xff0c;它们是std::ostream类的一个实例。 一、cout&#xff0c;cerr和clog流 ostream类…

echarts(6大基础图表)的使用

目录 一、vue2挂载 二、柱状图 2.1、基础柱状图介绍 2.2、标记&#xff1a;最大值\最小值(markPoint)、平均值(markLine) 2.3、显示&#xff1a;数值显示(label)、柱子宽度(barWidth)、横向柱状图 三、折线图 3.1、标记&#xff1a;最大值\最小值(markPoint)、平均值(ma…

android11禁止进入屏保和自动休眠

应某些客户要求&#xff0c;关闭了开机进入屏保&#xff0c;一段时间会休眠的问题。以下diff可供参考&#xff1a; diff --git a/overlay/frameworks/base/packages/SettingsProvider/res/values/defaults.xml b/overlay/frameworks/base/packages/SettingsProvider/res/value…

常见5大开发进度盲点问题及解决方案

在软件开发项目中&#xff0c;识别并解决常见的进度管理盲点问题&#xff0c;对于确保项目按时、按预算、高质量完成至关重要。它直接关系到项目能否顺利进行&#xff0c;忽视任何一个问题&#xff0c;都可能导致项目延期、成本超支、质量下降&#xff0c;甚至项目失败。 因此&…