与 OpenCV 1 同时使用

与 OpenCV 1 同时使用
目的

       对于OpenCV的开发团队来说,持续稳定地提高代码库非常重要。我们一直在思考如何在使其易用的同时保持灵活性。新的C++接口即为此而来。尽管如此,向下兼容仍然十分重要。我们并不想打断你基于早期OpenCV库的开发。因此,我们添加了一些函数来处理这种情况。在以下内容中你将学到:
    相比第一个版本,第二版的OpenCV在用法上有何改变
    如何在一幅图像中加入高斯噪声
    什么事查找表及如何使用

概述

        在用新版本之前,你首先需要学习一些新的图像数据结构:Mat - 基本图像容器,它取代了旧的CvMat 和 IplImage 。转换到新函数非常容易,你仅需记住几条新的原则。

        OpenCV 2 接受按需定制。所有函数不再装入一个单一的库中。我们会提供许多模块,每个模块都包含了与其功能相关的数据结构和函数。这样一来,如果你仅仅需要使用OpenCV的一部分功能,你就不需要把整个巨大的OpenCV库都装入你的程序中。使用时,你仅需要包含用到的头文件,比如:
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
        所有OpenCV用到的东西都被放入名字空间 cv 中以避免与其他库的数据结构和函数名称的命名冲突。因此,在使用OpenCV库中的任何定义和函数时,你必须在名称之前冠以cv:: ,或者在包含头文件后,加上以下指令:
using namespace cv;  // 新的C++接口API都在此名字空间中,需要导入。
        因为所有库中函数都已在此名字空间中,所以无需加 cv 作为前缀。据此所有新的C++兼容函数都无此前缀,并且遵循驼峰命名准则。也就是第一个字母为小写(除非是单个单词作为函数名,如 Canny)并且后续单词首字母大写(如copyMakeBorder ).

       接下来,请记住你需要将所有用到的模块链接到你的程序中。如果你在Windows下开发且用到了 动态链接库(DLL) ,你还需要将OpenCV对应动态链接库的路径加入程序执行路径中。

        关于Windows下开发的更多信息请阅读How to build applications with OpenCV inside the Microsoft Visual Studio ;对于Linux用户,可参考Using OpenCV with Eclipse (plugin CDT) 中的实例及说明。

       你可以使用 IplImage 或 CvMat 操作符来转换 Mat 对象。在C接口中,你习惯于使用指针,但此处将不再需要。在C++接口中,我们大多数情况下都是用Mat 对象。此对象可通过简单的赋值操作转换为 IplImage 和 CvMat 。示例如下:
Mat I;
IplImage pI = I;
CvMat    mI = I;
       现在,如果你想获取指针,转换就变得麻烦一点。编译器将不能自动识别你的意图,所以你需要明确指出你的目的。可以通过调用 IplImage 和CvMat 操作符来获取他们的指针。我们可以用 & 符号获取其指针如下:
Mat I;
IplImage* pI     = &I.operator IplImage();
CvMat* mI        =  &I.operator CvMat();
       来自C接口最大的抱怨是它将所有内存管理工作交给你来做。你需要知道何时可以安全释放不再使用的对象,并且确定在程序结束之前释放它,否则就会造成讨厌的内存泄露。为了绕开这一问题,OpenCV引进了一种智能指针。它将自动释放不再使用的对象。使用时,指针将被声明为Ptr 模板的特化:
Ptr<IplImage> piI = &I.operator IplImage();
      将C接口的数据结构转换为 Mat 时,可将其作为构造函数的参数传入,例如:
Mat K(piL), L;
L = Mat(pI);


实例学习


       现在,你已经学习了最基本的知识。这里你将会看到一个混合使用C接口和C++接口的例子。你也可以在可以再OpenCV的代码库中的sample目录中找到此文件samples/cpp/tutorial_code/core/interoperability_with_OpenCV_1/interoperability_with_OpenCV_1.cpp 。为了进一步帮助你认清其中区别,程序支持两种模式:C和C++混合,以及纯C++。如果你宏定义了DEMO_MIXED_API_USE ,程序将按第一种模式编译。程序的功能是划分颜色平面,对其进行改动并最终将其重新合并。
       在此,你可一看到新的结构再无指针问题,哪怕使用旧的函数,并在最后结束时将结果转换为 Mat 对象。

    // convert image to YUV color space. The output image will be created automatically.Mat I_YUV;cvtColor(I, I_YUV, CV_BGR2YCrCb);vector<Mat> planes;    // Use the STL's vector structure to store multiple Mat objectssplit(I_YUV, planes);  // split the image into separate color planes (Y U V)
       因为我们打算搞乱图像的亮度通道,所以首先将图像由默认的RGB颜色空间转为YUV颜色空间,然后将其划分为独立颜色平面(Y,U,V)。第一个例子中,我们对每一个平面用OpenCV中三个主要图像扫描算法(C []操作符,迭代,单独元素访问)中的一个进行处理。在第二个例子中,我们给图像添加一些高斯噪声,然后依据一些准则融合所有通道。
      运用扫描算法的代码如下: 

    // Method 1. process Y plane using an iteratorMatIterator_<uchar> it = planes[0].begin<uchar>(), it_end = planes[0].end<uchar>();for(; it != it_end; ++it){double v = *it * 1.7 + rand()%21 - 10;*it = saturate_cast<uchar>(v*v/255);}for( int y = 0; y < I_YUV.rows; y++ ){// Method 2. process the first chroma plane using pre-stored row pointer.uchar* Uptr = planes[1].ptr<uchar>(y);for( int x = 0; x < I_YUV.cols; x++ ){Uptr[x] = saturate_cast<uchar>((Uptr[x]-128)/2 + 128);// Method 3. process the second chroma plane using individual element accessuchar& Vxy = planes[2].at<uchar>(y, x);Vxy =        saturate_cast<uchar>((Vxy-128)/2 + 128);}}
       此处可看到,我们可以以三种方式遍历图像的所有像素:迭代器,C指针和单独元素访问方式你可在 OpenCV如何扫描图像、利用查找表和计时 中获得更深入的了解。从旧的函数名转换新版本非常容易,仅需要删除 cv 前缀,并且使用 Mat 数据结构。下面的例子中使用了加权加法:
    Mat noisyI(I.size(), CV_8U);           // Create a matrix of the specified size and type// Fills the matrix with normally distributed random values (around number with deviation off).// There is also randu() for uniformly distributed random number generationrandn(noisyI, Scalar::all(128), Scalar::all(20));// blur the noisyI a bit, kernel size is 3x3 and both sigma's are set to 0.5GaussianBlur(noisyI, noisyI, Size(3, 3), 0.5, 0.5);const double brightness_gain = 0;const double contrast_gain = 1.7;#ifdef DEMO_MIXED_API_USE// To pass the new matrices to the functions that only work with IplImage or CvMat do:// step 1) Convert the headers (tip: data will not be copied).// step 2) call the function   (tip: to pass a pointer do not forget unary "&" to form pointers)IplImage cv_planes_0 = planes[0], cv_noise = noisyI;    cvAddWeighted(&cv_planes_0, contrast_gain, &cv_noise, 1, -128 + brightness_gain, &cv_planes_0);
#elseaddWeighted(planes[0], contrast_gain, noisyI, 1, -128 + brightness_gain, planes[0]);
#endifconst double color_scale = 0.5;// Mat::convertTo() replaces cvConvertScale.// One must explicitly specify the output matrix type (we keep it intact - planes[1].type())planes[1].convertTo(planes[1], planes[1].type(), color_scale, 128*(1-color_scale));// alternative form of cv::convertScale if we know the datatype at compile time ("uchar" here).// This expression will not create any temporary arrays ( so should be almost as fast as above)planes[2] = Mat_<uchar>(planes[2]*color_scale + 128*(1-color_scale));// Mat::mul replaces cvMul(). Again, no temporary arrays are created in case of simple expressions.planes[0] = planes[0].mul(planes[0], 1./255);

       正如你所见,变量 planes 也是 Mat 类型的。无论如何,将 Mat 转换为 IplImage 都可通过简单的赋值操作符自动实现。
 merge(planes, I_YUV);                // now merge the results backcvtColor(I_YUV, I, CV_YCrCb2BGR);  // and produce the output RGB imagenamedWindow("image with grain", CV_WINDOW_AUTOSIZE);   // use this to create images#ifdef DEMO_MIXED_API_USE// this is to demonstrate that I and IplI really share the data - the result of the above// processing is stored in I and thus in IplI too.cvShowImage("image with grain", IplI);
#elseimshow("image with grain", I); // the new MATLAB style function show

       新的 imshow highgui函数可接受 Mat 和 IplImage 数据结构。 编译并运行例程,如果输入以下第一幅图像,程序将输出以下第二幅或者第三幅图像。


OpenCV源代码库中源文件:samples/cpp/tutorial_code/core/interoperability_with_OpenCV_1/interoperability_with_OpenCV_1.cpp 。



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

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

相关文章

第五周 Leetcode 99. Recover Binary Search Tree (HARD)

Leetcode99 给定一个 二叉搜索树&#xff0c;其中两个节点被交换&#xff0c;写一个程序恢复这颗BST. 只想到了时间复杂度O&#xff08;n&#xff09;空间复杂度O&#xff08;h&#xff09; h为树高的解法&#xff0c;还没想到空间O(1&#xff09;的解法。 交换的情况只有两种&…

Fedora15安装NVIDIA显卡驱动全过程

Fedora安装N卡驱动全过程 Fedora安装NVIDIA显卡全过程&#xff0c;经过自己亲自安装 折腾了一个上午&#xff0c;搞定了N卡驱动安装&#xff0c;现将安装步骤整理如下&#xff1a; 1、首先访问Nvidia官网下载最新的Linux驱动&#xff1a;http://www.nvidia.cn/Download/index…

板邓:wordpress自定义登录页面实现用户登录

首先检查用户是否已经登录&#xff0c;如果已经登录就返回info目录下的页面。 <?phpglobal $current_user;$loginuserid $current_user->ID;if($loginuserid){//如果已经登录header("Location:".get_bloginfo(url)."/info/"); exit;} 如果用户未登…

机器学习(machine learning)之AdaBoost算法

转自&#xff1a;http://blog.csdn.net/haidao2009/article/details/7514787 浅谈 Adaboost 算法 机器学习是利用一些方法来使机器实现人的学习行为&#xff0c;以便获取新的知识或技能&#xff0c;重新组织已有的知识结构使之不断改善自身的性能。 AdaBoost全名“adaptive B…

交换两个整形变量的数值

课堂问题一: #include<stdio.h>void swap(int *p,int *q) {int *m;printf("m%d\n",m);printf("%s\n",*m);*m*p;*p*q;*q*m; } int main(){int a,b;scanf("%d,%d",&a,&b);swap(&a,&b);printf("a%d b%d\n",a,b);re…

使用CodeFirst创建并更新数据库

本文主要介绍如何使用CodeFirst模式来新建并更新数据库 在使用Entity Framwork的三种方式&#xff08;ModelFist、DBFirst、CodeFirst&#xff09;中&#xff0c;CodeFirst方式书写的代码最为干净。 至于CodeFist方式的详细优缺点请各位读者自行搜索&#xff0c;这里不多赘述。…

fedora 15怎么修改运行级别?

inittab改了已经在fedora15中&#xff0c;你vim它就可以看到更改说明&#xff0c;就是说都改到/etc/systemd/system/default.target这里了&#xff0c;就是缺省的设置。如果你要改变缺省值就把对应的runlevel移动过去覆盖了。 To 3 字符 [root15 system]# rm -rf /etc/systemd…

浅析人脸检测之Haar分类器方法

由于工作需要&#xff0c;我开始研究人脸检测部分的算法&#xff0c;这期间断断续续地学习Haar分类器的训练以及检测过程&#xff0c;在这里根据各种论文、网络资源的查阅和对代码的理解做一个简单的总结。我试图概括性的给出算法的起源、全貌以及细节的来龙去脉&#xff0c;但…

利用微软平台生成报表,线性图,柱形图

说来惭愧,以前的工作中一直借助第三方dll进行报表制作,比如线性图,柱形图. 因为现在工作的这家公司不允许随便引入第三方dll,听同事说起可以建rdl类型文件进行引入到winform窗体中,窗体上使用reportViewer控件进行关联展示.下面是我今天摸索3个小时的结果分享. 第一步. 首先找到…

Linux ffmpeg的安装编译过程

Linux ffmpeg的安装编译过程 1、下载ffmpeg。    在网上搜索一下,或者到官方网站下载2、解压   tar命令解压3、配置  ./configure --enable-shared --prefix/usr/local/ffmpeg  其中&#xff1a;--enable-shared 是允许其编译产生动态库&#xff0c;在以后的编程中…

opencv 模板匹配(cvMatchTemplate)

opencv 模板匹配(cvMatchTemplate) 模板匹配是通过在输入图像上滑动模板图像块对实际的图像块和输入图像进行匹配&#xff0c;并且可以利用函数cvMinMaxLoc()找到最佳匹配的位置。例如在工业应用中&#xff0c;可以锁定图像中零部件的位置&#xff0c;并根据具体的位置&…

爬虫系统Lucene分词

思路&#xff1a;查询数据库中信息&#xff0c;查询出id和name把那么进行分词存入文件 package com.open1111.index; import java.io.IOException;import java.nio.file.Paths;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet; impor…

[BZOJ1880] [Sdoi2009] Elaxia的路线 (SPFA 拓扑排序)

Description 最近&#xff0c;Elaxia和w**的关系特别好&#xff0c;他们很想整天在一起&#xff0c;但是大学的学习太紧张了&#xff0c;他们 必须合理地安排两个人在一起的时间。Elaxia和w**每天都要奔波于宿舍和实验室之间&#xff0c;他们 希望在节约时间的前提下&#xff0…

ffmpeg的编译大全

ffmpeg的编译大全 最近互联网视频共享的网站很火&#xff0c;公司也想搞类似的网站&#xff0c;初步是用fmsffmpeg形式 fms负责在线录制&#xff0c;播放&#xff0c;ffmpeg则在后台处理上传的资源转换成一定的格式。 为了让ffmpeg支持的格式尽量多&#xff0c;所以特把我的编译…

用OPENCV视觉解数独

用OPENCV视觉解数独 2010-06-29 看到增强视觉网站上介绍老外用视觉解SUDOKU(http://www.cvchina.info/2011/05/29/video-sudoku-solver/)&#xff0c;觉得应该不难&#xff0c;于是用OPENCV和训练好的数字分类器&#xff0c;也试着做一个&#xff0c;纯属娱乐 基本思路如下&…

集成ffmpeg/x264:ERROR: libx264 not found的问题

集成ffmpeg/x264:ERROR: libx264 not found的问题--拔剑集成ffmpeg/x264碰到如下问题&#xff1a; ERROR: libx264 not found察看config.log,详细信息如下&#xff1a;check_lib x264.h x264_encoder_encode -lx264check_header x264.hcheck_cppBEGIN/tmp/ffconf.isuazGlg.c1 …

[ActionScript 3.0] AS3.0 下雨及涟漪效果

帧代码&#xff1a; stage.frameRate 80;function init(x1:Number,y1:Number) {var mc:MovieClipnew MovieClip();addChild(mc);mc.x x1;mc.y y1;mc.graphics.lineStyle(0.5,0xbbffff,0.6);mc.graphics.drawEllipse(-1,-0.3,2,0.6);mc.addEventListener(Event.ENTER_FRAME,f…

JS Math.round()方法原理

请先测试代码&#xff1a; 1 <!doctype html>2 <html lang"en">3 4 <head>5 <meta charset"UTF-8" />6 <title>Math.round方法</title>7 <style type"text/css">8 …

一个通用Makefile的编写

我们在 LinuxLinux Linux是一套免费使用和自由传播的操作系统&#xff0c;它主要用于基于Intel系列CPU的计算机上。这个系统是由全世界各地的成千上万的程序员设计和实现的&#xff0c;其目的是建立不受任何商品化软件的版权制约的、全世界都能自由使用的Unix兼容产品。 环境下…

Cache替换算法:LRU与LFU的区别

LFU&#xff08;Least Frequently Used&#xff09;最近最少使用算法。它是基于“如果一个数据在最近一段时间内使用次数很少&#xff0c;那么在将来一段时间内被使用的可能性也很小”的思路。LRU&#xff08;Least Recently Used&#xff09;. 注意LFU和LRU算法的不同之处&…