【C++的OpenCV】第三课-OpenCV图像加载和显示

这篇具有很好参考价值的文章主要介绍了【C++的OpenCV】第三课-OpenCV图像加载和显示。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、OpenCV加载图片和显示图片

本章节中,将会学习到:

  • 加载图像(cv::imread()函数)
  • 创建一个图像显示的窗口(cv::namedWindow()函数)
  • 在窗口中显示图片(cv::imshow()函数)

1.1 imread()函数的介绍

Mat image;
image = imread( imageName, IMREAD_COLOR ); // Read the file
  • 功能介绍:
            从指定路径中读取所选择的图像

  • 参数解释:

    • Mat image:
          image是一个Mat的对象。
          Mat是一种OpenCV中的图像存储的容器(稍后我们将会展开和大家介绍Mat的详细信息,请先往后看)
    • IMREAD_COLOR:
          这是一个普通的宏,表示图像对象的色彩通道的模式。 有三种选择:
      • IMREAD_UNCHANGED(<0)按原样加载图像(包括alpha通道(如果存在)
      • IMREAD_GRAYSCALE(0)将图像作为强度加载
      • IMREAD_COLOR(> 0)以RGB格式加载图像
    • imageName:
          imageName是一个图像的路径位置,数据类型为String类型(使用String()类构造函数将C字符数组构造String对象即可)。
String imageName( "../data/HappyFish.jpg" );
  • 关于图像类型
        OpenCV支持图像格式Windows位图(bmp),便携式图像格式(pbm,pgm,ppm)和Sun光栅(sr,ras),也可以加载像JPEG(jpeg,jpg,jpe),JPEG 2000(jp2 - 代号为CMake的Jasper),TIFF文件(tiff,tif)和便携式网络图形(png)。此外,OpenEXR也是一种可能性。

1.2 cv::namedWindow()函数的介绍

 namedWindow( "Display window", WINDOW_AUTOSIZE );
  • 功能介绍
    创建一个用于显示图像的窗口。
  • 参数解释
    • “Display window” : 窗口的名称,使用标准字符串(C字符数组)即可。
    • WINDOW_AUTOSIZE :
      • 如果不使用Qt后端,WINDOW_AUTOSIZE是唯一支持的。在这种情况下,窗口大小将占据显示的图像的大小。不允许调整大小!
      • WINDOW_NORMAL在Qt你可以使用它来允许窗口调整大小。图像将根据当前窗口大小自行调整大小。通过使用| 操作员还需要指定是否希望图像保持其宽高比:
        • WINDOW_KEEPRATIO(保持长宽比)
        • WINDOW_FREERATIO(不保持长宽比)。

1.4 imshow()函数介绍

imshow( "Display window", image );  
  • 功能介绍
        在窗口中显示Mat对象(即对象)。

  • 参数解释

    • “Display window” : 显示窗口的名称。即在哪个窗口中显示。
    • image:Mat容器的对象实例(继续往下来介绍Mat)

1.5 Mat容器介绍

    需要了解Mat的第一件事是,不再需要手动分配其内存。在执行此操作仍然是可能的情况下,大多数OpenCV功能将自动分配其输出数据。如果传递已经存在的Mat对象(已经为矩阵分配了所需的空间),那么这是一个很好的事情,这将被重用。换句话说,我们在任何时候都使用与我们需要执行任务一样多的内存。

    Mat基本上是一个具有两个数据部分的类:矩阵头(包含矩阵的大小,用于存储的方法,存储在哪个地址的信息等等)和指向包含像素值(取决于所选存储方法的任何维度)。矩阵头大小是恒定的,然而矩阵本身的大小可以随着图像的不同而变化,通常会大一个数量级。

    OpenCV使用引用计数系统。这个想法是每个Mat对象都有自己的头,但是通过使它们的矩阵指针指向相同的地址,矩阵可以在它们的两个实例之间共享。此外,复制操作符只会将头和指针复制到大矩阵,而不是数据本身。

Mat A, C;                          // 创建两个MAT容器的对象头
A = imread(argv[1], IMREAD_COLOR); // 为A对象添加实际的矩阵数据,imread() 返回的就是一个Mat对象。
Mat B(A);                                 // 使用拷贝构造函数创建Mat对象B
C = A;                                    // 修改操作

    所有上述对象,最后指向相同的单个数据矩阵。然而,它们的头部是不同的,并且使用它们中的任何一个进行修改也会影响所有其他的。在实践中,不同的对象只是向相同的底层数据提供不同的访问方法。然而,他们的头部不一样。

    可以询问矩阵本身是否属于多个Mat对象,它们在不再需要时负责清理它。简短的答案是:使用它的最后一个对象。这是通过使用引用计数机制来处理的。每当有人复制Mat对象的标题时,矩阵的计数器就会增加。每当头部被清洁时,这个计数器就会减少。当计数器达到零时,矩阵也被释放。有时你也想复制矩阵本身,所以OpenCV提供了cv :: Mat :: clone()和cv :: Mat :: copyTo()函数。例如:

Mat F = A.clone(); //F和A将不会采用同一个引用计数系统
Mat G;
A.copyTo(G); // 现在修改F和G都不会影响A

二、 代码实例(带注释)

2.1 代码

opencv源码链接:imread()函数使用案例

#include <opencv2/core.hpp> // opencv的核心组件,后续会为大家介绍其文件组件和大概功能
#include <opencv2/imgcodecs.hpp> // 图像编码组件,处理图像的功能
#include <opencv2/highgui.hpp> // 可视化窗口组件
#include <iostream>
#include <string>
using namespace cv; // opencv的命名空间,表明使用的工具所在的范围
using namespace std; // 标准命名空间
int main( int argc, char** argv )
{
    String imageName( "../data/HappyFish.jpg" ); // 定义图片名称对象imageName,这里使用自己的图片路径即可
    if( argc > 1) //命令行参数个数大于1时
    {
        imageName = argv[1]; // 取命令行的第二个参数作为图像路径
    }
    Mat image;
    image = imread( imageName, IMREAD_COLOR ); // 读取文件
    if( image.empty() )                      // 检查图片对象是否是空数据
    {
        cout <<  "Could not open or find the image" << std::endl ;
        return -1;
    }
    namedWindow( "Display window", WINDOW_AUTOSIZE ); // 创建图像显示窗口
    imshow( "Display window", image );                // 在窗口中显示图像
    waitKey(0); // 图像显示的时间,为系统结束前的阻塞时间,如果想要看到图片显示效果,建议此值设置在(3000以上,单位ms)
    return 0;
}

2.2 执行结果

    编译代码(使用CMAKE编译即可,编译方法:Cmake编译opencv项目的编译方法,然后运行可执行文件,将图像路径作为参数。如果你在Windows上,可执行文件当然也会包含一个exe扩展名。当然确保图像文件靠近你的程序文件。编译完成后,执行程序:

./Demo demo.jpg # 这里我的项目叫Demo,图片名称demo,文件类型jpg

    快来动手试试看吧!有问题可以私聊哦。文章来源地址https://www.toymoban.com/news/detail-452801.html

到了这里,关于【C++的OpenCV】第三课-OpenCV图像加载和显示的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 第三课:C++实现PDF去水印

    目录 1.功能概述与实现方法 2.代码实现 3.代码使用方法 4.PDF加水印原理和方法 4.1.使用“优速水印工厂”给pdf加水印 4.2.使用Acrobat XI软件给pdf加水印 4.3.使用优米处理器给pdf加水印 4.4.使用云朵办公给pdf加水印 4.5.使用livePDF给pdf加水印 PDF去水印是一项非常复杂的任务,需要一定

    2024年02月09日
    浏览(27)
  • 重生学c++系列第三课类和对象(上)

        好的我们重生c++系列的前两期已经介绍完了c++祖师爷针对C语言补充的几个新功能,现在我们进入c++的真正课题学习—— 类与对象:      C语言是面向过程的,关注的是过程,分析出求解问题的步骤,通过函数调用逐步解决问题。     比如说我们洗菜做饭,C语言关注的是

    2024年02月14日
    浏览(36)
  • 数字图像处理第三章 学习笔记附部分例子代码(C++ & opencv)

    本系列博客参考书为, 数字图像处理第三版-冈萨雷斯 第三版教材中图片下载地址: book images downloads vs2019配置opencv可以查看:VS2019 Opencv4.5.4配置教程 后续剧情: 数字图像处理 第四章 频率域滤波 学习笔记 数字图像处理 第六章 彩色图像处理 学习笔记 数字图像处理 第七章 小

    2024年02月03日
    浏览(39)
  • OpenCV4(C++)—— 视频和摄像头的加载、显示与保存

      视频或摄像头的加载是使用 cv::VideoCapture 类。(这个类和 ifstream 类比较相似,视频或摄像头的加载和文本文件操作是大致相同。主要步骤:(1)加载(打开)视频或视像头。(2) 判断加载是否成功。 (3)读取内容。(4)关闭。) 注意:   (1)VideoCapture类变量同时

    2024年02月06日
    浏览(27)
  • Baumer工业相机堡盟工业相机如何使用OpenCV实现相机图像的显示(C++)

    ​ Baumer工业相机堡盟相机是一种高性能、高质量的工业相机,可用于各种应用场景,如物体检测、计数和识别、运动分析和图像处理。 Baumer的万兆网相机拥有出色的图像处理性能,可以实时传输高分辨率图像。此外,该相机还具有快速数据传输、低功耗、易于集成以及高度

    2024年01月20日
    浏览(29)
  • C++ 程序使用 OpenCV 生成两个黑色的灰度图像,并添加随机特征点,然后将这两个图像合并为一张图像并显示

    生成灰度图像 :程序创建了两个大小为 240x320 像素的黑色灰度图像,分别命名为 imLeft 和 imRight 。 生成随机特征点 : 使用 generateRandomKeyPoints 函数在这两个图像上生成指定数量(在这个例子中是100个)的随机特征点。 这些特征点存储在 std::vectorcv::KeyPoint 类型的 mvKeys 和 mvK

    2024年02月20日
    浏览(28)
  • Baumer工业相机堡盟工业相机如何使用BGAPISDK和OpenCV设置图像进行比例显示(C++)

    Baumer工业相机堡盟相机是一种高性能、高质量的工业相机,可用于各种应用场景,如物体检测、计数和识别、运动分析和图像处理。 Baumer的万兆网相机拥有出色的图像处理性能,可以实时传输高分辨率图像。此外,该相机还具有快速数据传输、低功耗、易于集成以及高度可扩

    2024年02月10日
    浏览(32)
  • Kafka第三课

    Flume 由三部分 Source Channel Sink 可以通过配置拦截器和Channel选择器,来实现对数据的分流, 可以通过对channel的2个存储容量的的设置,来实现对流速的控制 Kafka 同样由三大部分组成 生产者 服务器 消费者 生产者负责发送数据给服务器 服务器存储数据 消费者通过从服务器取数据 但

    2024年02月13日
    浏览(25)
  • Spark第三课

    shuffle 1.打乱顺序 2.重新组合 1.分区的规则 默认与MapReduce的规则一致,都是按照哈希值取余进行分配. 一个分区可以多个组,一个组的数据必须一个分区 2. 分组的分区导致数据倾斜怎么解决? 扩容 让分区变多 修改分区规则 3.HashMap扩容为什么必须是2的倍数? 当不是2的倍数时, 好多

    2024年02月11日
    浏览(28)
  • MyBatis第三课

    目录 回顾  #和$区别 #(预编译SQL)和$(即时SQL,它是进行的字符串拼接)的区别,其中之一就是预编译SQL和即时SQL的区别 原因: 两者的共同点 MaBits可以看作是Java程序和Mysql的沟通桥梁,底层还是(jdbc) 访问数据库还得是Mysql 多表查询(慢) 1.通常情况下,数据库集群是很多

    2024年01月20日
    浏览(28)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包