opencv编程入门技巧

最近在项目中负责图像处理模块的编程工作,主要分为两个板块,一是视频图像去雾,二是可视、红外图像融合。为了提升开发效率,遂开始学习并使用opencv图像类库,效果很好的说~因为平台是vc6.0,比较老,加之对opencv的运用是入门级,所以选择使用opencv1.0版。下面提出几个我使用时遇到的问题及解决方法,同是opencv入门的同志可以略作参考。

1、         两个重要结构体类型。IplImage、CvMat。

(下文中变量,mat开头为矩阵CvMat类型,im开头为图像IplImage类型)

其中IplImage主要用来读入图像和存储处理结果的图像并显示。而CvMat作为矩阵类,主要用于过程中的数据处理。

推荐的建立方式如下:

IplImage* imResult=cvCreateImage(cvGetSize(matRes),8,3);

其中第一个参数需要cvSize类型(matRes为矩阵),8表示颜色深度,3表示通道(若建立灰度图像,3改成1)。

CvMat *   src=cvCreateMat(matV->height,matV->width,CV_32FC3);

三个参数分别是矩阵行数、列数、以及数据类型。数据类型请自己查看相关文献,这里的CV_32FC3表示float   3通道,若是灰度图像,改为CV_32FC1。

二者的相互转换方法如下:

IplImage——》CvMat

CvMat*   matRes=cvCreateMat(matV->height,matV->width,CV_32FC3);

cvConvert(imRes,matRes)

CvMat——》IplImage

IplImage* imRes=cvCreateImage(cvGetSize(matRes),8,3);

cvGetImage(matRes,imRes);

2、            CvMat的数据读取和写入

这个很重要,因为一直要用。方法似乎也好几种,可以用opencv的函数接口,也可以用指针。用指针寻址快,效率高,但是容易出错,况且我们平时编程似乎对程序时间消耗没有太大的刚性需求,所以这里讨论一下用现成函数接口的方法。注意cvmGet,cvmSet只能读取写入float和double类型数据,所以定义矩阵时最后的参数需设置为CV_32FC。

对灰度图像,一般用cvmGet和cvmSet

cvmGet(matRes,i,j);

cvmSet(matRes,i,j,tempres);

注意的是上面的i都是行坐标,是图像的height坐标轴。

对3通道彩色图像,一般使用cvGet2D,cvSet2D

cvGet2D(imRes,i,j),这样得到的是一个cvScalar的数据结构,里面存了该像素位置的rgb三个分量。得到三个分量各分量值的方法是

cvScalar s= cvGet2D(imRes,i,j);

int b=s.val[0];

int g=s.val[1];

int r=s.val[2]

注意,存储顺序是b,g,r。

用cvSet2D一样,先建立cvScalar s,对s的三个分量赋值,再用cvSet2D写入矩阵。

3、            内存泄露的解决方法

我在程序运行过程中碰到了严重的内存泄露问题,程序跑20来秒,我的内存就被占用光了,程序崩溃。下面说几条解决方法:

首先,因为CvMat类型是图像处理的中间环节,所以在得到处理结果并转化为IplImage后,对所有的CvMat类型进行清理,方法是

cvReleaseMat(&matRes);

一些图像内存也需要释放:

cvReleaseImage(&imRes);

另外,有时需要将一个矩阵内容拷贝到另一个矩阵,opencv提供了两种方法,cvCopy和cvCloneMat。此时需要慎重,使用cvCloneMat时,会开辟新的存储空间,而cvCopy不会。所以拷贝矩阵时,可使用以下两种方法:

CvMat *src=cvCreateMat(matV->height,matV->width,CV_32FC3);

cvCopy(matV,src);//将前者拷贝到后者

CvMat *src= cvCloneMat(matV);

再者,使用cvGetRows,cvGetCols时也需要注意,他们也会开辟新的内存空间,所以在之前需要释放目标矩阵的数据区域,如

CvMat * matRes=cvCreateMat(height,width,CV_32FC3);

cvRealeaseData(matRes);

cvGetRows(mat,matRes,0,height);

CvMat *matRes=cvCreateMatHeader(height,width,CV_32FC3);

cvGetRows(mat,matRes,0,height);

4、            再写几个小问题

矩阵的三个维度合为一个三维矩阵方法

cvMerge(matRes1,matRes2,matRes3,NULL,matRes);

将三维矩阵拆成三个一维似乎没有现成函数接口,自己写循环实现吧。

矩阵的加减乘除运算,这个也用得很多的,写在这里。

矩阵-矩阵操作:

CvMat *Ma, *Mb, *Mc;

cvAdd(Ma, Mb, Mc); //Ma+Mb -> Mc

cvSub(Ma, Mb, Mc);//Ma-Mb -> Mc

cvMatMul(Ma, Mb, Mc); //Ma*Mb -> Mc

按元素的矩阵操作:

CvMat *Ma, *Mb, *Mc;

cvMul(Ma, Mb, Mc);// Ma.*Mb -> Mc

cvDiv(Ma, Mb, Mc);// Ma./Mb -> Mc

cvAddS(Ma, cvScalar(-10.0), Mc);// Ma.-10 -> Mc(这个比较好用)

在整个开发过程中,似乎也就遇到这几个问题,在此记录下来,以供大家参考。哈哈,第一篇博文完成啦,开心~

opencv编程入门技巧的更多相关文章

  1. opencv图像处理基础 (《OpenCV编程入门--毛星云》学习笔记一---五章)

    #include <QCoreApplication> #include <opencv2/core/core.hpp> #include <opencv2/highgu ...

  2. OpenCV编程入门目录

    第一部分 快速上手OpenCV 第1 章 邂逅OpenCV 图像处理.计算机视觉与OpenCV OpenCV 概述 起源及发展 应用概述 .2OpenCV 基本架构分析 .3OpenCV3 带来了什么 ...

  3. 【浅墨著作】《OpenCV3编程入门》内容简单介绍&amp;勘误&amp;配套源码下载

    经过近一年的沉淀和总结,<OpenCV3编程入门>一书最终和大家见面了. 近期有为数不少的小伙伴们发邮件给浅墨建议最好在博客里面贴出这本书的文件夹,方便大家更好的了解这本书的内容.事实上近 ...

  4. 完成《Java编程入门》初稿

    Java编程入门 现在的运维工程师不但要懂得集合网络.系统管理而且要和开发人员一起调试系统,社会上也需要"复合性"的运维人员,所以需要做运维的也要懂一些开发,知道软件系统接口的调试 ...

  5. PC游戏编程(入门篇)(前言写的很不错)

    PC游戏编程(入门篇) 第一章 基石 1. 1 BOSS登场--GAF简介 第二章 2D图形程式初体验 2.l 饮水思源--第一个"游戏"程式 2.2 知其所以然一一2D图形学基础 ...

  6. OpenCV 编程简单介绍(矩阵/图像/视频的基本读写操作)

    PS. 因为csdn博客文章长度有限制,本文有部分内容被截掉了.在OpenCV中文站点的wiki上有可读性更好.而且是完整的版本号,欢迎浏览. OpenCV Wiki :<OpenCV 编程简单 ...

  7. 《转载》编程入门指南 v1.4

    编程入门指南 v1.4 Badger · 8 个月前 作者:@萧井陌, @Badger 自由转载-非商用-非衍生-保持署名 | Creative Commons BY-NC-ND 3.0 CoCode ...

  8. OpenCV3编程入门.记录

    ZC:OpenCV3编程入门_毛星云编著_电子工业出版.pdf 1.在看到 PDF.P134(计算数组加权和:addWeighted()函数)的时候,其中讲到“当输出数组的深度为CV_32S时,这个函 ...

  9. 编程入门选什么语言好?C 语言还是Python ?为你解析

    前面我分享过计算机行业已经成了学校选择排名第一,家长和学生都很看好计算机类专业.现在IT行业也越来越火爆,程序员越来越被人看好.面对相比同龄人高薪资的诱惑,人们很难不心动,即使秃头也值得! 那么问题来 ...

随机推荐

  1. ArcEngine下纵断面图的绘制

    我是採用Dev控件中的画图控件来绘制的纵断面图,以下主要来介绍下输电线路选址以及纵断面图的实时绘制的实现流程. 一.关于输电线路的选址,首先要准备好基础地理数据,包含选线区的DOM,DEM,DLG以及 ...

  2. Android安卓安全审计mobiseclab

    关于安卓上的app分析,有非常多的本地化软件能够胜任, 只是,今天给大家介绍一款在线的安全审计,恶意软件(android app)检測和分析工具,mobiseclab, 由于看到国内对此工具的介绍比較 ...

  3. 基于jsoup的Java服务端http(s)代理程序-代理服务器Demo

    亲爱的开发者朋友们,知道百度网址翻译么?他们为何能够翻译源网页呢,iframe可是不能跨域操作的哦,那么可以用代理实现.直接上代码: 本Demo基于MVC写的,灰常简单,copy过去,简单改改就可以用 ...

  4. C# winform调用WebBrowser经典怪问题总结

    原文:C# winform调用WebBrowser经典怪问题总结 最近一直研究网页数据采集,单单采集数据,其实HtmlAgilityPack就足够了. 对HtmlAgilityPack感兴趣的可以到这 ...

  5. 使用Canvas基于手势可以使树秋千

    用Canvas制作能够依据手势摆动的树 依据工作的须要.制作一个摆动的树做为页面的背景.为了添加页面的交互性,我又为背景中的树添加了鼠标(触控)事件,使他可以依据鼠标(触控)做出对应的动作,当手指做上 ...

  6. C语言生成2000w行数据

    最近一直抽空学习shell,脚本语言看多了多多少少有些蛋疼不适,所以捡起以前遇到的一个C语言的问题看看. 原先应该是在C++吧关注的一个帖子,楼主为了测试数据库性能需要如下形式的数据要求: 字符串长度 ...

  7. 编写高效的jQuery代码

    http://www.css88.com/jqapi-1.9/ 编写高效的jQuery代码 最近写了很多的js,虽然效果都实现了,但是总感觉自己写的js在性能上还能有很大的提升.本文我计划总结一些网上 ...

  8. C++中的左值和右值

    左值和右值的定义 在C++中,能够放到赋值操作符=左边的是左值,能够放到赋值操作符右边的是右值.有些变量既能够当左值又能够当右值.进一步来讲,左值为Lvalue,事实上L代表Location,表示在内 ...

  9. EnterpriseLibrary 6.0(微软企业库6.0学习笔记) 之Data Access Block 配置和获取链接字符串

    EnterpriseLibrary 的特点是快速开发,融合了微软工程师多年的经验,现在在微软内部有专门的一个小组在完善EnterpriseLibray,最近的更新时间是April 2013. 相关链接 ...

  10. cocos2d的-X- luaproject的LUA脚本加密

    2014/1/26 更新 近期又发现了一个非常easy的方法,事实上coco2dx已经给我们提供设置loader的方法. 注意:有个局限性,在非android平台下调用pEngine->exec ...