本博客所用OpenCV版本为2.4.3,运行环境为Visual Studio2012。

学习OpenCV是一个比较漫长的过程,希望我能够坚持!

(一)从Mat讲起

Mat是OpenCV中用于存放图像的数据结构。我们知道,图像在计算机中是以数组的形式存放的。Mat正是描述的这样一种数据结构。通过调用相关方法,我们能够实现对图像的输入输出以及一些操作。同时,Mat又不止可以作为图像容器,它也可以作为一种比较纯粹的描述矩阵这种数学对象的结构。它比C中的IplImage好的地方在于,由于它的“计数器”机制,我们不需要对它进行手动的内存回收,从而避免了常常困扰C/C++程序员的“内存泄露”问题。

让我们先来看看如何使用Mat来进行图像的输入输出。能够看到程序按照自己所想输出图片还是一件比较令人高兴的事情吧!

下面我将直接贴出代码,再进行解释。

#include <iostream>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/core/core.hpp>
//#include <opencv/cv.hpp>
using namespace std;
using namespace cv;int main()
{string namePic="pic.jpg";//Part 1  Read and Load Image/************************************************************************//* 下面的代码显示了如何用imread函数进行图像读取操作                                                                     *//************************************************************************/Mat Img_Color=imread (namePic,CV_LOAD_IMAGE_COLOR);     //生成了彩色图Mat Img_Gray=imread (namePic,CV_LOAD_IMAGE_GRAYSCALE);   //生成了灰度图/************************************************************************//* 下面的代码显示了如何用imshow函数进行图像的显示                                                                     *//************************************************************************/imshow ("彩色小女孩",Img_Color);imshow ("灰度小女孩",Img_Gray);waitKey();return 0;
}

现在看一下程序运行结果吧:

下面我们来解释一下代码:

头文件包含中除了C++标准库iostream以外,我们还使用到了highgui.cpp和core.cpp。其中前者包含了对图像进行IO操作要用到的一些类和宏的定义,后者包含了一些核心内容。

代码中图像的读入操作是使用函数imread()实现的。imread()函数的原型如下:

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

可以看到,返回值是一个Mat对象,第一个参数为字符串型,表示源图像的名称(如果不在源文件目录下,应该写成绝对路径),第二个参数决定了读入图像的颜色格式。上例代码中所出现的CV_LOAD_IMAGE_COLOR和CV_LOAD_IMAGE_GRAYSCALE分别表示读入彩色图像和灰度图像。

代码中图像的输出操作使用了函数imshow()实现。imshow()函数的原型如下:

void imshow(const string& winname, InputArray mat)

可以看到,第一个参数为字符串型,定义了窗口的名称,第二个参数为Mat,表明要显示的图片。

如果用过MATLAB,就会发现这两个函数和MATLAB中的图像输入输出函数名是完全一样的。而在阅读OpenCV 的tutorial文档时,也会发现不少与MATLAB相似的地方,比如在OpenCV中产生单位阵就可以调用Mat::eye()实现,是不是和MATLAB很相似呢??

至于代码最后的WaitKey函数,是为了防止代码运行结果一闪而过而加上去的。函数原型如下:

int waitKey(int delay=0)

参数代表程序运行至此停留的毫秒数,缺省值为0.代表forever。但是要注意,这里的延时并不是很准确,而是根据系统当前运行的任务多少而有变化,只是说至少会延迟delay毫秒时间。

Mat的数据结构包含了两部分数据,一部分是矩阵头,表明了矩阵的基本信息。另一部分就是用于存储图像的矩阵数组了。由于图像一般都很很大,所以对矩阵数组这部分内存进行频繁的读写复制操作是很费时间的。为了克服这个问题,OpenCV允许两个Mat对象有不同的矩阵头,却包含同一块矩阵数据。这样,在复制操作的时候,就避开了对大块内存空间的读写,节省了时间。比如下面的几种赋值方式,它们都只是复制了Mat A的矩阵头,同时复制了指向图像矩阵的内存的指针,但是却没有复制矩阵:

Mat C=A;      //利用等号
Mat E(A);      //利用Mat的构造函数

如果想要用矩形截取图像的一部分呢??我们可以使用如下的构造函数:

Mat B=Mat(A,Rect(0,0,100,100));      //截取A的100*100的矩形区域

那么如果我们处于某种需要,确实要复制矩阵呢??我们可以使用Mat类实例提供的clone方法和copyto方法。如下所示:

Mat G;
A.copyto(G);
Mat H=A.clone();

当然了,我们刚开始介绍Mat的时候就已经说过,Mat不仅可以视为一个图像的容器,还可以作为一个矩阵这样的数学对象。下面我们就来看一下如何生成这样的Mat对象实例。

首先,我们可以使用Mat的构造函数,通过查阅文档可以知道,Mat的构造函数可谓是多种多样,下面举的例子只是其中之一,更多内容还是应该访问网页http://docs.opencv.org/modules/core/doc/basic_structures.html#Mat来获得。

Mat B(20,20,CV_8UC1,Scalar(1));

这样,就建立了一个20*20,并且矩阵全部元素都是1的矩阵。

其次,我们可以使用Create函数。如下所示:

Mat B;
B.create (10,10,CV_8UC3);

不过要注意的是,这样方法不能同时对B矩阵元素进行初始化操作,就像这个样子:

或者,我们可以使用MATLAB风格的代码进行赋值:

Mat E = Mat::eye(4, 4, CV_64F);  //生成单位阵
Mat E=Mat::ones(2, 2, CV_32F);  //生成全1阵
Mat E=Mat::zeros(2, 2, CV_8UC1);//生成0矩阵

获取某个矩阵的一行或者一列可以采取下面的方式:

Mat RowClone = C.row(1).clone();

关于Mat这种数据结构的简单介绍就到这里,更多的还是应该去查阅相关手册文档,才能得到更加完整的认识。

转载于:https://www.cnblogs.com/xmfbit/p/3872191.html

学习OpenCV(一)从Mat讲起相关推荐

  1. 【从零学习OpenCV 4】Mat类构造与赋值

    本文首发于"小白学视觉"微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社所有,禁止转载,侵权必究! 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4入门 ...

  2. 【从零学习OpenCV 4】Mat类介绍

    本文首发于"小白学视觉"微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社所有,禁止转载,侵权必究! 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4入门 ...

  3. opencv4 c++ 提取图片中的白色区域_修正!【从零学习OpenCV 4】分割图像——分水岭法...

    点击上方"小白学视觉",选择"星标"公众号重磅干货,第一时间送达 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4入门书籍<OpenCV 4开 ...

  4. cv2.error: opencv(4.4.0)_【从零学习OpenCV 4】图像金字塔

    点击上方"小白学视觉",选择"星标"公众号 重磅干货,第一时间送达 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4入门书籍<从零学习Open ...

  5. 基于c++版本的opencv操作(Mat类)

    图像的基本操作(一) 前言 一.Mat类? 1.c++版本代码 添加链接描述 前言 一.Mat类? 1.c++版本代码 1.1 at()函数 1.2 使用迭代器 2.代码结果展示 2.1 at()函数 ...

  6. 【从零学习OpenCV 4】4种读取Mat类元素的的方法

    本文首发于"小白学视觉"微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社所有,禁止转载,侵权必究! 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4入门 ...

  7. 《学习opencv》笔记——基本数据结构,CvMat,矩阵訪问

        老板让让做一个东东.输入端要用到opencv顺便就来学习一下.买了本书<学习opencv>翻来一看,opencv1.0,去官网上一看.opencv2.49,瞬间有种蛋碎的赶脚.看着 ...

  8. 跟着小琼琼学习opencv~

    楼楼最近整理笔记,发现了自己学习Opencv时候的码的代码和简单介绍,现贴上来~主调用方法在最下方.转载请注明出处~ #include <opencv2\xfeatures2d\nonfree. ...

  9. 【走进OpenCV】学习Opencv不得不掌握的操作

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 小白导读 学习计算机视觉最重要的能力应该就是编程了,为了帮助小伙伴 ...

最新文章

  1. python画五角星-Python第八课 绘制五角星1.0
  2. 【Java】Servlet 工作原理解析
  3. 获取DataTable字段唯一值(DISTINCT)
  4. mvc中html对象的方法吗,在MVC中使用jQuery模板进行HTML编码的Json对象
  5. 信安教程第二版-第26章大数据安全需求分析与安全保护工程
  6. 32位linux进程线程在内存中的样子
  7. 基于JAVA+SpringMVC+MYSQL的校园宿舍管理系统
  8. mysql ndb 测试_Mysql性能2:基于JDBC的MySQL NDB性能测试结果
  9. 2021年文山州一中高考成绩查询,云南文山第一中学2021年录取分数线
  10. Pow(x, n) leetcode
  11. 【CPLEX】Java调用CPLEX的一些小笔记
  12. 服务器自带软件怎么样卸载,如何安装和卸载远程服务器管理工具
  13. Ubuntu Android开发环境配置
  14. 信道估计之MMSE算法
  15. 关于AutoCAD软件的PDF打印机的问题
  16. Invalid MEX-file '/xxx/lk.mexa64': /xxx/anaconda3/lib/./libharfbuzz.so.0: undefined symbol: FT_Done_
  17. 桌面出现2个计算机,在一个电脑屏幕上如何同时显示两个word
  18. 算法的时间复杂度与空间复杂度介绍
  19. Windos下安装nexus私服(nexus-2.12.0-01)
  20. 用Python实现斯皮尔曼等级相关性检验

热门文章

  1. autoconfig oracle,ORACLE EBS 执行autoconfig time out
  2. pcie转sata3硬盘不启动_没有地方塞硬盘?你或许需要这款扩展卡
  3. a标签跳页传参,以及截取URL参数
  4. xhtml和css概述
  5. C++中使用Json的方法
  6. QT cannot open output file debug\OpencvTest.exe: Permission denied
  7. 20 个 jQuery 超酷视觉效果构建教程推荐
  8. 某云数据中心网络解决方案(分享二十一)
  9. 【解决线程安全问题:通过Lock锁对象】
  10. C#/.NET基于Topshelf创建Windows服务的守护程序作为服务启动的客户端桌面程序不显示UI界面的问题分析和解决方案