OpenCV Mat读取和显示图片

一、从文件读取图像并显示

1. 程序

在基于VS2013搭建OpenCV开发环境这篇文章的最后给出了一个简单的Demo,这个例子跟本篇使用的例子是一样的。打开C++ IDE并创建一个新的项目,新建一个源文件,粘贴下面的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <opencv2\highgui\highgui.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main( int argc,  const char ** argv)
{
     Mat img = imread( "earth.jpg" , CV_LOAD_IMAGE_UNCHANGED);
     if (img.empty())
     {
         cout <<  "图像加载失败!" << endl;
         //system("pause");
         return -1;
     }
     //创建一个名字为MyWindow的窗口
     namedWindow( "MyWindow" , CV_WINDOW_AUTOSIZE);
     //在MyWindow的窗中中显示存储在img中的图片
     imshow( "MyWindow" , img);
     //等待直到有键按下
     waitKey(0);
     //销毁MyWindow的窗口
     destroyWindow( "MyWindow" );
     return 0;
}

在运行程序之前,将图片文件(earth.jpg)放到C++文件所在的目录。运行程序,如下图所示:

20140326201318

2. 解释

下面我来解释一下这个程序。

1
#include <opencv2\highgui\highgui.hpp>

imread(), namedWindow(), imshow() 和 waitKey() 函数都声明在这个头文件中,所以笔记得包含它。

上面的程序中还是用了Mat数据结构,它在”opencv2/core/core.hpp”中声明的,那为什么没有包含它呢?这是因为在”opencv2/highgui/highgui.hpp”头文件中已经包含了core.hpp头文件,所以不用在我们的程序再次包含了。

1
using namespace cv;

“opencv2/core/core.hpp” 和 “opencv2/highgui/highgui.hpp中所有的数据结构和函数都声明在cv命名空间,所以,必须在我们程序的头部使用它,否则就要在每个OpenCV的函数和数据结构前面都要加上”cv::”(例如:cv::Mat,cv::imread()等等)。

1
Mat img = imread( "earth.jpg" , CV_LOAD_IMAGE_UNCHANGED);

Mat是在矩阵中存储图片的数据结构,它声明在 “opencv2/core/core.hpp”头文件中。
imread()是声明在 “opencv2/highgui/highgui.hpp”的函数,它从文件加载一个图片并存储在Mat数据结构中。

imread()函数的声明如下:

1
CV_EXPORTS_W Mat imread(  const string& filename,  int flags=1 );

它的参数:

    • filename —— 文件的位置。如果只提供文件名,那么文件应该和C++文件在同一目录,否则必须提供图片的全路径。
    • flags —— 有5个可能的输入。
      • CV_LOAD_IMAGE_UNCHANGED – 在每个通道中,每个像素的位深为8 bit,通道数(颜色)保持不变。
      • CV_LOAD_IMAGE_GRAYSCALE – 位深=8 bit 通道数=1(颜色变灰)
      • CV_LOAD_IMAGE_COLOR -位深=?, 通道数=3
      • CV_LOAD_IMAGE_ANYDEPTH – 位深不变 ,通道数=?
      • CV_LOAD_IMAGE_ANYCOLOR – 位深=?, 通道数不变

      上面的值还可以组合使用,比如:
      CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR – 位深不变,通道数比便
      CV_LOAD_IMAGE_COLOR | CV_LOAD_IMAGE_ANYDEPTH – 位深不变,通道数=3

如果你不确定使用哪个,就是用CV_LOAD_IMAGE_COLOR 。

要理解位深和通道的概念,应该熟悉图像处理的理论知识,所以下面讨论一点这方面的内容。

所有的数字图像都是由像素组成的,所有的像素都有值。一个像素的最小值为0,表示黑色。像素的值变大,它的亮度也会增强。每个像素分配的比特的固定数值是255(十进制),也就是说每个像素分配8个bit。所以一个像素的最大值为255(二进制为11111111)。

那么什么是位深呢?位深就是为每个像素分配的比特。如果比特是8,每个像素的值可以是0-255。如果是4,每个像素的值可是0-15(二进制中为1111)。

下面是一个8 bit位深的图片的简单模型。每个小矩形表示一个像素。所以每个矩形包含一个0-255的值。

GrayscaleImage

这张图像的一些属性:

  • 8 bit位深
  • 一个通道(所以这是一个灰度图像)
  • 高为4px
  • 宽为5px
  • 分辨率为4×5

这是一个灰度图像(黑白图像),因为该图像没有颜色内容。像素的值越高,图像就会越亮。像素值越低,图像就会越暗。

下面是一个彩色图像的简单模型。彩色图像至少包含3个平面:Red,Green和Blue。使用这3种颜色的特定组合可以创建任何颜色。所有的像素都是这3种颜色值的组合。(255,0,0)表示pure red。(0,255,0)表示pure green。(255,0,255)表示pure violate。它的位深为24,因为每个像素为8×3 bit (每个通道8 bit)。

ColorImage

这张图像的一些属性:

  • 位深24 bit
  • 3个通道(所以是彩色图像)
  • 高4px
  • 宽5px
  • 分辨率为4×5

上面的模型,左上角的像素是(23,231,46)。它会显示为呈绿色的颜色,因为green值(231)比red(23)和blue(46)都大。

1
if (img.empty())

如果imread()函数加载图像失败,’img’不会加载任何数据,因此,img.empty()应该返回true。检查是否成功加载,如果没有则退出程序是一个好的做法,否则当调用imshow()函数时,程序就会崩溃。

1
bool Mat::empty()

如果Mat::data==NULL或Mat::total()==0,这个函数返回true。

1
system ( "pause" );

如果使用Visual Studio,这行注释的注释最好取消,因为它会暂停程序,知道用户按下任意键。如果不取消注释,程序会立即退出,用户也就不会看到错误信息了。

1
void namedWindow( const string& winname,  int flags = WINDOW_AUTOSIZE);

这个函数创建一个窗口。它的参数如下:

  • winname——窗口的名字。这个名字会显示在窗口的标题栏上。
  • flags——决定窗口的尺寸。有如下选项:
    • WINDOW_AUTOSIZE – 用户不能改变图像的尺寸,图像显示为它的原有尺寸
    • CV_WINDOW_NORMAL – 调整窗口图像的尺寸可以改变
1
void imshow( const string& winname, InputArray mat);

这个函数在指定名字的窗口中显示存储在mat中的图像。如果窗口使用WINDOW_AUTOSIZE创建的,图像会显示为它的原始尺寸,否则图像会调整到窗口的尺寸大小。

它的参数:

  • winname -窗口的名字。这个名字是namedWindow()函数创建窗口时使用的
  • mat – 存储图像数据的Mat对象
1
int waitKey( int delay = 0)

waitKey()函数通过指定delay(毫秒)等待按键的时间。如果delay是0或负数,它会永久等待。如果任意键被按下,这个函数就会返回按下键的ASCII值,程序继续执行。如果指定的时间没有按下键,它返回-1,程序继续执行。

1
void destroyWindow( const string& winname)

这个函数关闭名字为winname的打开的窗口并释放关联的内存。这个函数对这个程序来说不是必须的,因为当程序退出,操作系统通常会关闭所有打开的窗口并释放关联的内存。

3. 总结

当运行程序,图像”earth.jpg”被加载到Mat类型的变量”img”。然后一个名字为”MyWindow”的窗口打开,接着”img”被加载到窗口中。窗口和图像一起显示,直到按下任意键。

二、创建一个空图像并显示

这个程序和前一个非常像,唯一的不同就是这个程序创建了一个空图像,而不是从文件中加载已存在的图像。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <opencv2\highgui\highgui.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main( int argc,  const char ** argv)
{
     Mat img(500, 1000, CV_8UC3, Scalar(0, 0, 100));  //创建一个图像 ( 3个通道, 8 bit位深, 高500, 宽1000, (0, 0, 100) 分别分配给 Blue, Green and Red. )
     if (img.empty())
     {
         cout <<  "图像不能加载!" << endl;
         //system("pause");
         return -1;
     }
     namedWindow( "MyWindow" , CV_WINDOW_AUTOSIZE);
     imshow( "MyWindow" , img);
     waitKey(0);
     destroyWindow( "MyWindow" );
     return 0;
}

运行结果如下图:

20140326235345

OpenCV的新函数

1
Mat::Mat( int rows,  int cols,  int type,  const Scalar& s);

这是Mat的一个构造函数。它使用Scalar对象给定的值初始化Mat对象。

它的参数:

  • rows – 2维矩阵的行数 (图像的高度像素)
  • cols – 2维矩阵的列数 ( 图像的宽度像素)
  • type – 指定图像的位深,数据类型和通道数。我提供 CV_8UC3 ,指定3个通道的8 bit无符号整数,下面是这个参数一些可能的输入值:
    • CV_8UC1 – 单通道8 bit无符号整数
    • CV_8UC3 – 3通道8 bit为无符号整数
    • CV_64FC1 – 单通道64 bit 浮点数
      如果想详细了解这方面的内容,请参见OpenCV数据结构之Mat一文的“阵列的数据类型”部分。
    • s – 使用s给定的值初始化矩阵的每个元素。在上面的程序中,给定Scalar(0,0,100),因此,它使用0初始化第一个通道(Blue),0初始化第二个通道(Green),100初始化第三个通道(Red)。所以,最终的图像是red。

总结

在这个程序中,我创建了一个高500,宽1000,有3个通道的图像。每个通道的每个像素分配8 bit的无符号整数(每个像素 8×3=24 bit),每个像素使用(0,0,100)指定值。这意味着,第一个通道总是0,第二个通道也总是0,第三个通道总是100,因此,最终看到的是一个red的图像。

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

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

相关文章

opencv读取图片通道以及显示

使用cv2读取的图像的通道到是BGR通道&#xff0c;所以测试模型之前需要做BGR转RGB的操作。 imgcv2.imread(515.jpg) cv2.imshow("aa",img) cv2.waitKey(-1)显示结果&#xff1a; 显示结果是正常的。如果转为RGB后&#xff1f; import matplotlib.pyplot as plt im…

023期计算机开机号,大乐透2020023期开机号分析,历届023期开奖号码、及走势图...

大乐透2020023开机号 04 07 19 26 340211 前区分析&#xff1a; 和值&#xff1a;90 奇偶&#xff1a;2:3偶-奇-奇-偶-偶 前区推荐&#xff1a;03-05-11-13-16-26-27-28-32-35 后区推荐&#xff1a;03-04-10-11 (开机号码并非开奖号码&#xff0c;以上个人观点、仅供参考) 历史…

Compose Desktop打包后运行java.lang.ClassNotFoundException的巨坑

作业要用mysql&#xff0c;引入了一个jar包&#xff0c;放在lib目录下面&#xff0c;结果调试正常运行&#xff0c;一打包运行就各种出错&#xff0c;搞了一个多小时&#xff0c;配置了半天&#xff0c;最后chatgpt一行代码帮我解决了&#xff0c;光在项目结构里面配置引用库不…

Cause: org.apache.ibatis.executor.result.ResultMapException: Error attempting to get column

Cause: org.apache.ibatis.executor.result.ResultMapException: Error attempting to get column 为了搞这个问题&#xff0c;卡了一个多小时&#xff0c;问chatgpt弄了半天&#xff0c;用上typeHandler发现版本有问题&#xff0c;也没有深究&#xff0c;退回原来版本看了半天…

[2021] 完美解决Unable to find image ‘hello-world:latest‘ locally 问题

安装Docker出现的问题 相信大家查询了很多的回答里面都是需要修改阿里镜像源&#xff0c;但是修改之后却无用。这是因为阿里那个源对于每个人来说都需要专属源。详细的内容可以参考菜鸟教程里的回答&#xff1a;菜鸟教程更换镜像源 接下来就简单的完成这个这个更换源的操作&a…

Jetson NX Xavier 编译opencv4.4(cuda版)

目录 *序言00|系统信息01|下载安装Jtop02|卸载自带的opencv2.1 为什么要卸载自带的opencv2.2 卸载默认的方法2.3 安装依赖库 03|Nvidia预构建opencv-cuda4.5参考资料 *序言 大部分人在解决问题的时候&#xff0c;百度输入的关键词不够准确&#xff0c;展示出来的页面多数是跟自…

小白学C语言数据结构之图

定义 由点集和边集形成的一个东西.. 比如 A ——————————B | | | | | | C——————————D 当然C和B也有可能有连接 A和D也有可能有连接 邻接表法 A&#xff1a;B(可以在括号里封装一个AB间的距离&#xff09;&#xff0c;C B&#xff1a;C&#xff0c;D C&#…

网络漏洞,我把全校学生信息都搞出来了!

因公众号更改推送规则&#xff0c;请点“在看”并加“星标”第一时间获取精彩技术分享 点击关注#互联网架构师公众号&#xff0c;领取架构师全套资料 都在这里 0、2T架构师学习资料干货分 上一篇&#xff1a;ChatGPT研究框架&#xff08;80页PPT&#xff0c;附下载&#xff09;…

比尔·盖茨:AI将为每人创造一个私人助手 科技市场面临洗牌?

自ChatGPT爆火以后&#xff0c;硅谷大厂们开启了生成式AI“军备竞赛”&#xff0c;都在争相推出能生成文字或影像的人工智能工具&#xff0c;科技圈或将迎来大变局。 在这场变局中&#xff0c;微软似乎已拔得头筹。微软首席执行官表示&#xff0c;“搜索引擎迎来了新时代”&…

我们学习到底是为了什么,到底什么才是我们真正想要的

原创 科大云炬 科大云炬 2019-04-26 、 今天看到一句话&#xff0c;感慨颇多:”现在的教育只是一味的强调一定要好好学习&#xff0c;却没有强调为什么要好好学习。 我们学习到底是为了什么&#xff0c;到底什么才是我们真正想要的。一千个读者会产生一千个哈姆雷特学过马哲…

ChatGPT与高等教育变革:价值、影响及未来发展

最近一段时间&#xff0c;ChatGPT吸引了社会各界的目光&#xff0c;它可以撰写会议通知、新闻稿、新年贺信&#xff0c;还可以作诗、写文章&#xff0c;甚至可以撰写学术论文。比尔盖茨、马斯克等知名人物纷纷为此发声&#xff0c;谷歌、百度等知名企业纷纷宣布要提供类似产品。…

用Python剪辑视频?太简单了

人生苦短&#xff0c;快学Python&#xff01; 最近我在网上下载一个视频&#xff0c;结果下载到本地是近百个视频片段&#xff0c;为了方便观看只能将这些片段合并为一个视频整体。 不过我并没有搜到能够处理类似情况的小工具&#xff0c;只是发现剪映等软件可以实现视频合并功…

python小应用之moviepy的视频剪辑制作gif图

对视频动画的编辑可以使用python的moviepy库&#xff0c;官方文档&#xff1a; http://zulko.github.io/moviepy/ 1、进入cmd&#xff0c;pip install moviepy 2、使用代码 #import imageio #imageio.plugins.ffmpeg.download() import moviepy.editor as mpy#视频文件的…

视频剪辑教程自学技巧:关于正确的短视频剪辑流程分享

视频剪辑教程自学技巧&#xff1a;关于正确的短视频剪辑流程分享 短视频的火热程度自然不用说&#xff0c;而这大概也是越来越多的人开始做短视频的原因。不过对于大多数的人来说&#xff0c;学习短视频剪辑&#xff0c;其实都是自学&#xff0c;这就导致很多人可能都还不知道…

做视频剪辑必须学会的几个剪辑软件,你知道哪些?

现在短视频非常火热&#xff0c;身边70%以上的人或多或少都会使用手机APP快速剪辑视频&#xff0c;但是如果大家想要通过视频剪辑变现&#xff0c;或者想要自己的视频出彩&#xff0c;那么掌握系统的剪辑方法、剪辑软件的使用是必不可少的&#xff0c;今天小编就给大家分享几款…

什么剪辑软件好用?视频剪辑这样做

什么剪辑软件好用&#xff1f;随着时代的快速发展&#xff0c;剪辑视频已经成为我们几乎人人必会的技能之一了。无论我们是专业人士还是非专业人士&#xff0c;在日常生活中多多少少都会使用到视频剪辑。很多小伙伴们潜意识里会觉得剪辑视频是一件十分困难的事情&#xff0c;其…

学习做视频剪辑,几分钟教会你剪辑技巧

现在很多人做自媒体&#xff0c;也有很多人想做自媒体。而视频剪辑是做自媒体必不可少的&#xff0c;所有我闪在分享视频之前&#xff0c;都会比如剔除一些多余的部分&#xff0c;或者是在视频画面添加图片等等&#xff0c;以此呈现更好的效果。但还是有许多的小伙伴不知道该怎…

百度发布「AI大底座」:一口气把10年AI技术积累打包了

鱼羊 发自 凹非寺量子位 | 公众号 QbitAI 技术创新的节点性时刻&#xff0c;往往是以基建变革的形式展现。 现在&#xff0c;中国AI头号玩家百度&#xff0c;再次明确复现了这一规律&#xff1a; AI大底座&#xff0c;已正式对外推出。 就在刚刚结束的百度AI开发者大会上&#…

打谱软件告诉你:编曲和作曲哪个难?

从各位学习打谱软件作曲大师的朋友反馈来看&#xff0c;我必须这麽说&#xff0c;编曲要能端上台面&#xff0c;一定比作曲难&#xff0c;但要作出一首好曲也绝对是不容易。 以进入的门槛来说&#xff0c;编曲当然是需要比较高的门槛&#xff0c;除了要懂乐理&#xff0c;各种…

guitar pro8.1免费的吉他学习辅助软件

从名字上看就知道这是一款针对吉他谱开发的软件&#xff0c;相信大多数吉他爱好者都用过或者听过这款软件。可以通过鼠标和键盘的操作对吉他谱的内容进行输入&#xff0c;支持四线谱&#xff0c;五线谱、六线谱等曲谱的制作。软件涵盖了几乎所有的吉他演奏技巧符号&#xff0c;…