我的opencv慢慢学习小笔记(一)

Mat imageIO;临近放寒假,下周回家,这两天没事先开始慢慢学一些opencv的知识,第一篇小笔记开始:

结合师兄的opencv的书跟自己搜来的知识,总结以下知识点:

1.回顾了一下C++中的命名空间的问题,主要作用是工程中,防止多人定义相同的类,导致的编译的问题,使用命名空间

namespace ns1 //声明命名空间ns1
{ class Student //在命名空间nsl内声明Student类
{ public:
Student(int n,string nam,int a)
{ num=n;name=nam;age=a;}
void get_data();
private:
int num;
string name;
int age; };

namespace ns2//声明命名空间ns2
{ class Student
{ public:
Student(int n,string nam,char s)
{ num=n;name=nam;sex=s;}
void get_data();
private:
int num;
string name;
char sex; };


 


将类的定义放在命名空间以后,声明对象的时候使用  ns1::Student stud1 这样的方式就可以避免问题,当然访问的时候还是访问stud1.age。

然后可以用using namespace .. 说明函数使用的命名空间,免去每次都ns1::的麻烦。

2.命名空间结束后,opencv中记着要使用using namespace cv,然后就可以使用类Mat了。

opencv的安装过程最后成功,记录在了扣扣空间里。在此贴上昨天写的第一个测试例程,注意下头文件跟命名空间即可。

虚拟机里面整的复制比较麻烦,贴个图。

imread函数:

imread(const string& filename, intflags=1 );

两个参数,第一个是文件路径,记着"",linux下面注意下绝对路径与相对路径就行,我都试过没啥问题,相对路径如上,绝对路径 /home/king/test/timg.jpeg

第二个参数是读取格式,可以缺省1就表示读了RGB图,三通道的8比特数据的图像,鉴于之前在matlab仿真的时候对RGB图等知识补过,这里就不想提了。

读取格式还可以有其他参数可读取原来大小的数据,是相应的枚举类型的参数。

对我此次有用的来说,还可以参数是0,读取灰度图。

参数缺省读取。或者读取灰度图

 

3.另外在看浅墨大大的教程代码

http://blog.csdn.net/poem_qianmo/article/details/21176257

的时候发现的

 

  1.        Mat  imageGreenChannel;  
  2.    
  3.        //【1】重新读入图片  
  4.        logoImage=imread("dota_logo.jpg",0);  
  5.        srcImage=imread("dota_jugg.jpg");  
  6.    
  7.        if(!logoImage.data ) { printf("Oh,no,读取logoImage错误~!\n"); return false; }  
  8.        if(!srcImage.data ) { printf("Oh,no,读取srcImage错误~!\n"); return false; }  
  9.    
  10.        //【2】将一个三通道图像转换成三个单通道图像  
  11.        split(srcImage,channels);//分离色彩通道  
  12.    
  13.        //【3】将原图的绿色通道的引用返回给imageBlueChannel,注意是引用,相当于两者等价,修改其中一个另一个跟着变  
  14.        imageGreenChannel=channels.at(1);

这里的13行的返回的是引用,不能理解,查了引用的很多知识,vector的at方法,没搞明白,后来找到Mat的at方法的介绍

 

https://www.cnblogs.com/adong7639/p/4360225.html

 

关于Mat ,首先要知道的是你不必再手动地(1)为其开辟空间(2)在不需要时立即将空间释放。但手动地做还是可以的:大多数OpenCV函数仍会手动地为输出数据开辟空间。当传递一个已经存在的Mat 对象时,开辟好的矩阵空间会被重用。也就是说,我们每次都使用大小正好的内存来完成任务。

基本上讲 Mat 是一个类,由两个数据部分组成:矩阵头(包含矩阵尺寸,存储方法,存储地址等信息)和一个指向存储所有像素值的矩阵(根据所选存储方法的不同矩阵可以是不 同的维数)的指针。矩阵头的尺寸是常数值,但矩阵本身的尺寸会依图像的不同而不同,通常比矩阵头的尺寸大数个数量级。因此,当在程序中传递图像并创建拷贝 时,大的开销是由矩阵造成的,而不是信息头。OpenCV是一个图像处理库,囊括了大量的图像处理函数,为了解决问题通常要使用库中的多个函数,因此在函 数中传递图像是家常便饭。同时不要忘了我们正在讨论的是计算量很大的图像处理算法,因此,除非万不得已,我们不应该拷贝 的图像,因为这会降低程序速度。

为了搞定这个问题,OpenCV使用引用计数机制。其思路是让每个 Mat 对象有自己的信息头,但共享同一个矩阵。这通过让矩阵指针指向同一地址而实现。而拷贝构造函数则 只拷贝信息头和矩阵指针 ,而不拷贝矩阵。

1

2

3

4

5

6

Mat A, C;                                 // 只创建信息头部分

A = imread(argv[1], CV_LOAD_IMAGE_COLOR); // 这里为矩阵开辟内存

 

Mat B(A);                                 // 使用拷贝构造函数

 

C = A;                                    // 赋值运算符

以上代码中的所有Mat对象最终都指向同一个也是唯一一个数据矩阵。虽然它们的信息头不同,但通过任何一个对象所做的改变也会影响其它对象。实际 上,不同的对象只是访问相同数据的不同途径而已。

 

这里的介绍终于让我了然。。。在找到这个之前我对浅墨大大说的引用还比较怀疑,故自己找到元素访问的方法:

http://lib.csdn.net/article/opencv/33144

试了试是不是引用。

Mat imageIO;

vector<Mat> channels;
split(image,channels);
imageIO = channels.at(0);
imshow("channel1",channels.at(0));
for(int i=0;i<imageIO.rows;i++)
{
for(int j=0;j<imageIO.cols;j++)
{
imageIO.at<uchar>(i,j)=0;
}
}
//imageIO=0;
imshow("imageIO",imageIO);
imshow("channel1 gaibian yihou ",channels.at(0));

 

确认了是引用,然后后来找到了解答在上面。

这部分有用的是at方法的引用于Mat里面元素的遍历。

4.是对3通道的Mat的分离,上面代码有涉及,使用split函数

 

C++: void split(const Mat& src, Mat*mvbegin);
C++: void split(InputArray m,OutputArrayOfArrays mv);

 

 

 

 

关于变量介绍:

 

 

  • 第一个参数,InputArray类型的m或者const Mat&类型的src,填我们需要进行分离的多通道数组。
  • 第二个参数,OutputArrayOfArrays类型的mv,填函数的输出数组或者输出的vector容器。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值