【循序渐进地学好OpenCV&4】使用2.0的API显示图片以及OpenCV的自动化内存管理

1.0 显示图片和2.0显示图片的比较

   在[【循序渐进地学好OpenCV&2】显示图片——OpenCV的“起手式”](http://blog.csdn.net/zgljl2012/article/details/48306299)这篇文章里,我们使用了OpenCV 1.0的API实现了从磁盘读取文件并显示,下面是代码:
#incldue "cv.h"
#include "highgui.h"

int main(int argc, char** argv)
{
    IplImage* img = cvLoadImage(argv[1]);
    cvNamedWindow("Example1", CV_WINDOW_AUTOSIZE);
    cvShowImage("Example1", img);
    cvWaitKey(0);
    cvReleaseImage(&img);
    cvDestroyWindow("Example1");
}
   从上面我们可以看出这是明显的C风格的代码,首先是让指针指向一块分配好的内存数据,然后释放内存,如里面的cvReleaseImage。

但在2.0的API里,我们就可以不用这么写了,因为Open CV2.0版本已经可以实现自动化的内存管理了。

   下面我们使用2.0的API实现一下显示图片:
#include "highgui.h"
#include "cv.h"
using namespace cv;

int main() {
 char* name = "fruits.jpg";
 char* window = "显示图片";
 // 将图片读入一个Mat
 Mat mat = imread(name);
 // 创建一个窗口
 namedWindow(window);
 // 显示图片
 imshow(window, mat);
 // 等待一个点击键盘事件
 waitKey(0);
 return 0;
}
   效果图就不贴了,当然成功了。代码的逻辑和1.0差不多,只是少了释放内存的代码,因为2.0 的OpenCV已经实现自动化内存管理里

OpenCV 2.0的自动化内存管理

   OpenCV对所有的内存实施自动化管理。首先,std::vector,Mat和其他的数据结构有它们自己的析构函数在需要的时候来负责释放底层的内存缓冲区。这意味着析构函数不是总是释放缓存。
   以Mat为例,它是一个类,里面包含两个数据部分,矩阵头和一个指向存储所有像素值的矩阵的指针。矩阵头的大小是常数值,而矩阵的大小就与图像的大小有关,一般都会比矩阵头大上几个数量级。在OpenCV中,要进行大量的图像处理,因此也常常要在函数中传递Mat,这个时候,如果每次传递都将图像矩阵占据的内存一块拷贝一份的话,就会减慢处理速度;所以,除非有特殊要求,否则不应该传递图像数据。
   所以,在我们拷贝Mat时OpenCV不会在给图像矩阵分配新内存了,而是给Mat创建了一个指向它的指针。并引用了计数机制,每添加一个Mat指向同一块图像矩阵的引用,计数加1;释放后计数减1。当计数为0时,表明没有指向它的指针,就释放这块内存。所以,OpenCV2.0能自动管理内存。

下面看例子:

void mat() {
 // 创建一个8M的大矩阵
 Mat A(1000, 1000, CV_64F);
 // 创建另一个相同的矩阵头
 // 这是一个瞬时的操作, 因为忽略了矩阵的大小.
 Mat B = A;
 // 创建一个矩阵头,只包含了A的第三行; 同样没有数据被拷贝
 Mat C = B.row(3);
 // clone可以拷贝矩阵本身,下面是创建了一个矩阵副本
 Mat D = B.clone();
 // copyTo也可以拷贝矩阵本身,但因为A、B、C指向的都是同一块矩阵数据
 // 所以这是将原矩阵数据的第5行拷贝到了第3行
 B.row(5).copyTo(C);
 // 现在让A和D共享数据; 但原A的矩阵还被B和C引用着
 A = D;
 // 清空B (即让它不引用内存),
 // 原A矩阵现在就只剩下C还引用着,尽管C只是一行数据
 B.release();
 // 最后,复制一块C指向的内存,让C指向它的新内存;这样,原A矩阵数据就被释放掉了,
 // 因为这个时候,它没有被任何变量引用
 C = C.clone();
}

Ptr介绍

上面的Mat是OpenCV实现了自动化内存管理,所以用起来很方便。但是对那些高等级的类和用户定义的类要实现自动化内存管理该怎么办呢?OpenCV也为这些类提供了与C++STL标准库相似的Ptr<>模板类。只需要用它来代替原来的指针即可:

T* ptr = new T(...);
//替换为:
Ptr<T> ptr = new T(...);

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-05 17:20:52

【循序渐进地学好OpenCV&4】使用2.0的API显示图片以及OpenCV的自动化内存管理的相关文章

OpenCV系列1-简单高效:MFC显示图片、播放视频

先看图: 拉伸显示 居中显示 原始大小显示 显示视频: 实现图片显示,只需要两句话: 只需要包含一个h文件: 调整显示方式: 下面是CvImgCtrl.h的源代码,复制保存下来即可用,或者也可以下载demo,不要积分 控件采用的是双缓冲绘图,显示效率很高,不会闪烁,支持视频.图片的显示 /************************************************************************/ /* OpenCV MFC图像显示控件 v1.0 /* 该控件

OpenCV 2.2版本号以上显示图片到 MFC 的 Picture Control 控件中

OpenCV 2.2 以及后面的版本号取消掉了 CvvImage.h 和CvvImage.cpp 两个文件,直接导致了苦逼的程序猿无法调用里面的显示函数来将图片显示到 MFC 的 Picture Control 控件中.为此,网上非常多人表示仅仅要将那两个文件人为的提取出来然后放到project里面就解决这个问题了,也提供了两个文件的下载,可是这麻烦不说.还会导致一些奇奇怪怪的报错(至少本人是这种,非常崩溃!).所以在了解了一些gdi画图之后结合网上的代码写了例如以下的函数,仅仅需调用就能够将O

ubuntu 16.04 安装 opencv +contrib (3.2.0) + python 3.5

环境: - ubuntu 16.04 - OpenCV + contrib 3.2.0 (文中附下载链接) - Python 3.5 基于其他环境的配置应该大同小异. 没时间解释了,直接上车. 更新下系统: sudo apt-get update sudo apt-get upgrade 安装依赖项: sudo apt-get install build-essential cmake pkg-config sudo apt-get install libjpeg8-dev libtiff5-d

OpenCV:基于MFC的视频播放器和图片读取器

实例工程包下载[OpenCV:基于MFC的视频播放器和图片读取器] 一.实现的功能 1.打开本地视频进行读取.播放.暂停.停止控制 2.图片打开功能分为两种:可使用"打开图片"按钮打开本地图片,或者点击comobox里面设定的图片列表选择并显示图片 二.编译环境 OS:Win8.1 x64 IDE:  Visual Studio 2013 OpenCV: 2.4.8 三.主要思路 1.视频的滑动条控制: ①主窗体的OnHScroll()响应函数负责响应slider滑动条的变化,这样就轻

[学习OpenCV攻略][011][显示图片]

学习资料: http://www.opencv.org.cn/opencvdoc/2.3.2/html/doc/tutorials/tutorials.html   包含头文件 core.hpp:包含了基本的定义和库 highgui.hpp:包含了基本的输入输出操作 #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> 创建一个矩阵对象来存储和载入图像数据 Mat image; imread函

【OpenCV练习】简单显示图片的代码

今天依照网上的教程尝试了一下最基本的图片显示. 首先想说一下编译时出现的问题,开始时在编译时会出现无法识别cvReleaseImage的情况,是因为没有在配置中包含相应的core的库文件. 加进去就解决这个问题了. 另一个问题是在编译通过以后提示程序拒绝访问,经网上查找好像和英雄联盟有关..貌似是LOL关闭了什么调试功能,总之重启一下电脑就好了. 最后放上相应代码: #include <iostream> //#include <opencv/cv.h> //#include &l

Opencv入门-第一回-梦牵机器视觉翼,初识Opencv域(安装Opencv)

各位看官,您是不是瞅着Opencv进来的?(你这不是废话吗>_>) 这Opencv(开源计算机视觉库)啊,说来话长,最初是上个世纪末(1999年)由Intel建立起来的.近十多年人工智能这匹黑马突然出现,带动各行各业的发展,特别是机器视觉! 各位看官就慢慢跟随着鄙人的脚步,进入Opencv这片具有巨大发展潜能的地方吧! Opencv有两宝--开放源码.完全免费. 俗话说,"工欲善其事,必先利其器",开始我们至少要有一把武器啊!怎么获得呢?下面是获取武器的步骤,看官看好了!

OpenCV 2.2版本以上显示图片到 MFC 的 Picture Control 控件中

OpenCV 2.2 以及后面的版本取消掉了 CvvImage.h 和CvvImage.cpp 两个文件,直接导致了苦逼的程序员无法调用里面的显示函数来将图片显示到 MFC 的 Picture Control 控件中.为此,网上很多人表示只要将那两个文件人为的提取出来然后放到工程里面就解决问题了,也提供了两个文件的下载,但是这麻烦不说,还会导致一些奇奇怪怪的报错(至少本人是这样的,很崩溃!).所以在了解了一些gdi绘图之后结合网上的代码写了如下的函数,只需调用就可以将OpenCV的图片显示在上面

调用opencv相关函数,从视频流中提取出图片序列

/************************ @HJ 2017/3/30 参考http://blog.sina.com.cn/s/blog_4b0020f301010qcz.html修改的代码 @主要调用opencv相关函数,从视频流中提取出图片序列 @需要注意的问题: cvReleaseImage(&pImg)释放内存出错的两种情况:具体可以参考http://www.cnblogs.com/grandyang/p/4615036.html 1)从摄像头获取的图片不能被修改和释放,所以如果