DoubleLi

qq: 517712484 wx: ldbgliet

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  4737 随笔 :: 2 文章 :: 542 评论 :: 1614万 阅读
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

* 未经许可,谢绝转载!请尊重原创! 【OpenCV】关于Mat_类的一个问题 *
对于Mat_类,就从文档里面复制点内容做个简单的介绍吧。
The class Mat_<Tp> is a “thin” template wrapper on top of the Mat class. It does not have any extra data fields.While Mat is sufficient in most cases, Mat can be more convenient if you use a lot of element access operations and if you know matrix type at the compilation time.
这个类其实就是Mat的一个子类,平时我自己主要用来操作当数据已知且量较小时的输入,见下面的例子。
这次在看以前写的代码的时候,不经意间发现了下面代码中要展示的问题,这也是本文要说的。

#include <iostream>
#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

int main()
{
    // 方式一
    Mat matrix1 = (Mat_<int>(2, 3) << 0, 1, 2,
                                      3, 4, 5);
    cout << matrix1 << endl << endl;

    // 方式二
    Mat matrix2 = *(Mat_<int>(2, 3) << 0, 1, 2,
                                       3, 4, 5);
    cout << matrix2 << endl;

    return 0;
}

在我的代码中几乎都是用的第一种方式,除了有一行代码用的是第二种方式。其实我也没弄明白当时咋个就加了个*。
上面的两种方式产生的结果完全相同。大家可以自己试一下结果。
为什么会产生上面的问题?根本原因就是操作符重载了。下面直接从源码中给出解释。

// 下面的代码源自OpenCV2.4.9
// 上面例子中的操作基本都是由MatCommaInitializer_类来完成的
template<typename _Tp> class MatCommaInitializer_
{
public:
    //! the constructor, created by "matrix << firstValue" operator, where matrix is cv::Mat
    MatCommaInitializer_(Mat_<_Tp>* _m);
    //! the operator that takes the next value and put it to the matrix
    template<typename T2> MatCommaInitializer_<_Tp>& operator , (T2 v);
    //! another form of conversion operator
    Mat_<_Tp> operator *() const;
    operator Mat_<_Tp>() const;
protected:
    MatIterator_<_Tp> it;
};

// 对应例子中的方式一
template<typename _Tp> inline MatCommaInitializer_<_Tp>::operator Mat_<_Tp>() const
{
    CV_DbgAssert( this->it == ((const Mat_<_Tp>*)this->it.m)->end() );
    return Mat_<_Tp>(*this->it.m);
}

// 对应例子中的方式二
template<typename _Tp> inline Mat_<_Tp> MatCommaInitializer_<_Tp>::operator *() const
{
    CV_DbgAssert( this->it == ((const Mat_<_Tp>*)this->it.m)->end() );
    return Mat_<_Tp>(*this->it.m);
}

从上面的代码可以看出,这两种重载其实做了完全一模一样的事情。
相信绝大部分人在用到Mat_这个类的时候都会使用第一种方式,既然偶然的机会让我碰到了这个问题,还是在此做个记录,希望可以帮到大家。
对上第二种方式,在OpenCV3.0.0中已经不复存在了,还是看源码吧。

// 下面的代码源自OpenCV3.0.0
// MatCommaInitializer_
template<typename _Tp> class MatCommaInitializer_
{
public:
    //! the constructor, created by "matrix << firstValue" operator, where matrix is cv::Mat
    MatCommaInitializer_(Mat_<_Tp>* _m);
    //! the operator that takes the next value and put it to the matrix
    template<typename T2> MatCommaInitializer_<_Tp>& operator , (T2 v);
    //! another form of conversion operator
    operator Mat_<_Tp>() const;
protected:
    MatIterator_<_Tp> it;
};

// 对应例子中的第一种方式,第二种方式已经被删除
template<typename _Tp> inline
MatCommaInitializer_<_Tp>::operator Mat_<_Tp>() const
{
    CV_DbgAssert( this->it == ((const Mat_<_Tp>*)this->it.m)->end() );
    return Mat_<_Tp>(*this->it.m);
}

从上面OpenCV3.0.0中的源码可以看出,对*的重载已经被删除了。
* 未经许可,谢绝转载!请尊重原创! 【OpenCV】关于Mat_类的一个问题 *

 
posted on   DoubleLi  阅读(38)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
历史上的今天:
2018-03-28 ONVIF、RTSP/RTP、FFMPEG的开发实录
2018-03-28 ffmpeg摄像头采集h264编码RTP发送
2018-03-28 ffmpeg综合应用示例(一)——摄像头直播
2018-03-28 利用ffmpeg一步一步编程实现摄像头采集编码推流直播系统
2018-03-28 ffmpeg超详细综合教程——摄像头直播
2018-03-28 最简单的基于FFmpeg的AVDevice例子(读取摄像头)
2018-03-28 如何用FFmpeg API采集摄像头视频和麦克风音频,并实现录制文件的功能
点击右上角即可分享
微信分享提示