【OpenCV】Learning OpenCV3 第四章笔记

【OpenCV】Learning OpenCV3 第四章笔记

第四章 动态和可变存储

接下来将介绍大规模数组类型,其中最重要的是cv::Mat,这可被视作OpenCV c++实现的核心。cv::Mat用来表示任意维的密集(dense)数组,这里的密集(dense)表示Mat中每个值都被存储在内存中(即便是0),其反义是稀疏(sparse)数组(仅存储非0变量),在OpenCV中是cv::SparseMat

cv::Mat:N维密集数组

cv::Mat可存储任意维数组,且以行为主序存储,每个矩阵包含了

变量名flagsdimsrowscolsdatarefercount
含义数组的一些量维数行数列数(dims>2则invalid)指向数据存储内存的指针记录被cv::Ptr<>引用的指针数

cv::Mat中的每个元素不一定要是一个值,也可以是多个值

创建一个数组

cv::Mat m;
m.create(3,10,CV_32FC3); // 32-bit floating-point three-channel array
m.setTo(cv::Scalar(1.0f,0.0f,-1.0f));
cout << m << endl;


cv::Mat m2(3,10,CV_32FC3, cv::Scalar(1.0f,0.0f,-1.0f)); // equivalent

本书中最重要的一句话
需要认识到cv::Matcv::Mat.data的分离性,cv::Mat.data才是对数据的指向而非cv::Mat,当我们对cv::Mat赋值时,如m=n,此时m中的data指针就会指向ndata指向的区域,而原先data指向的区域(如果是最后一个引用的话),则会自动销毁,同事m中的dimcol等变量也会自动变得与n一致,注意到它们共享了data所指向区域

cv::Mat各种用法,见自74页起的表格

单独获取数组元素

两种方法,通过位置,或通过迭代

  • 通过at<>()
    cv::Mat m = cv::Mat::eye(10, 10, 32FC1); // cv::Mat m = cv::Mat::eye(10, 10, 32FC2);
    print(
    	"Element (3,3) is %f\n",
    	m.at<float>(3,3) // m.at<cv::Vec2f>(3,3)[0]
    )
    
    在模板中指定类型为数组中的类型,并选择位置,注释中给出的是multichannel的数组,书p79表4-6列出了大部分accessor function
  • 使用c风格的指针

数组迭代器:NAryMatIterator

通过内存连续的一个个plane来迭代N维数组,而非传统的逐个元素,详见书p82

通过块来获取元素

获取一个数组的子区域,比如cv::Mat.row(int i)cv::Mat.col(int j)等方法,注意这些方法并没有复制数据,而仅仅给了一个指针,更复杂的方法包括cv::Mat.rowRange(cv::Range(i0,i1))cv::Mat.diag(int offset)cv::Mat(cv::Rect)等等

矩阵表达式

一些关于cv::Mat的运算符重载+-*/以及elementwise的计算m1>m2~m0等,详见书p87表格4-8

饱和投射

对于某个数据类型比如uchar,当出现数据溢出的时候,可以通过cv::saturate_cast来以边缘值代替溢出值

unchar& Vxy = m0.at<uchar>(y,x);
Vxy = cv::saturate_cast<uchar>((Vxy-128)*2+128);

出现溢出时,输出为0

其他

m1=m0.clone()等其他方法p88表格4-9

稀疏数组cv:SparseMat

cv::Mat使用数组存储,而cv::SparseMat使用哈希表存储,哈希表是自动维护的,详见书p90-93

使用模板

使用cv::Mat_<>而非cv::Mat创建数组可以简化代码,比如

cv::Mat m(10,10,CV_32FC2);
m.at<Vec2f>(i0,i1) = cv::Vec2f(x,y);
cv::Mat_<Vec2f> m(10,10);
m.at(i0,i1) = cv::Vec2f(x,y);
//or...
m(i0,i1)=cv::Vec2f(x,y)

在使用at时,无须再指定数组中的元素类型了
建议使用这种模板的形式创建矩阵,这样可以使得一些问题在编译时被检测出来

总结

本章主要介绍了cv::Mat的一些用法

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值