mat分析dump分析_OpenCV中如何获取Mat类型中的步长stride及分析 C++实现

点击上方↑↑↑“OpenCV学堂”关注我

作者博客: https://blog.csdn.net/yl_best

问题需求:获取Mat stride

如题,需要使用到Mat类型的步长stride。

先从本地读取一张图片,单步进去看到srcImage的属性如下图,有stride,也有width,height,channels等

0edb1f618628409fac842ee5a2f0c027.png

我们可以通过srcImage.cols或者srcImage.size().width来获取图片的宽度,

通过srcImage.channels()来获取通道数量,

通过srcImage.type()来获取图片类型

但是怎么获取图片的stride呢?

这两种方式

srcImage.stride
or
srcImage.stride()

都是不对的,编译器会报错

"Error:class "cv::Mat" has no member "stride",怎么办?

官方资料解释

去OpenCV头文件里只找到这一段话:【位于mat.hpp里】

So, the data layout in Mat is fully compatible with CvMat, IplImage, and CvMatND types from OpenCV

1.x. It is also compatible with the majority of dense array types from the standard toolkits and

SDKs, such as Numpy (ndarray), Win32 (independent device bitmaps), and others, that is, with any

array that uses *steps* (or *strides*) to compute the position of a pixel. Due to this

compatibility, it is possible to make a Mat header for user-allocated data and process it in-place

using OpenCV functions.

看起来stride就是step,那如何获取step?

如何获取stride

代码很简单,就这样一句话srcImage.step

98116e12f6616e2599e98ed623f526db.png

深入分析

MatStep类型的结构体

但是如果F5单步进去看,会发现step其实是一个MatStep类型的结构体,如下:

这个结构体有两个成员,size_t * p和size_t buf[2].

struct CV_EXPORTS MatStep
{
    MatStep();
    explicit MatStep(size_t s);
    const size_t& operator[](int i) const;
    size_t& operator[](int i);
    operator size_t() const;
    MatStep& operator = (size_t s);

    size_t* p;
    size_t buf[2];
protected:
    MatStep& operator = (const MatStep&);
};

MatStep的构造函数

再单步进MatStep的构造函数如下:

inline
MatStep::MatStep()
{
    p = buf; p[0] = p[1] = 0;
}

inline
MatStep::MatStep(size_t s)
{
    p = buf; p[0] = s; p[1] = 0;
}

发现p指向buf,buf代表数组的首地址,二者指向的位置是一样的。在我的电脑上,都指向同一个地址0x00f5fdc4。继续单步,按F11 Step into,编译器就会带我们进入到以下这个函数

隐式类型转换的操作符重载函数

inline MatStep::operator size_t() const{
    CV_DbgAssert( p == buf );
    return buf[0];
}

重点来了。。这个结构体重载了size_t的隐式类型转换,所以我们用srcImage.step就可以直接获取stride了。

运算符重载的知识

此处再回忆下运算符重载的知识

operator它有两种用法,

  • operator overloading(操作符重载)

  • operator casting(操作符隐式转换)

操作符重载:类型T operator 操作符 (参数)【举例:size_t& operator[] (int i)重载了[],参数是int i, 返回size_t &】操作符隐式转换:operator 类型T ()  【这里用的是这一种】

可以参考

《C++技巧之operator操作符》

都是很基本的东西,欢迎大家指正。

完整版代码

#include 
#include 
using namespace cv;  //包含cv命名空间
using namespace std;

int main(int argc, char ** argv){
Mat srcImage;
// 【1】读入一张图片,载入图像
srcImage = imread("F:/images/lena.jpg");     //在程序中打开一张图片
//Because of pop_back() and resize() methods `M.total() == 0` does not imply that `M.data == NULL`.
//if (!srcImage.data)   
if (srcImage.empty())
{
printf("could not load image...\n");
return -1;
}
cout <"srcImage.step is " <endl;
cout <"srcImage.step[0] is " <0] <endl;
unsigned int  x = srcImage.step;
char input_title[] = "input image";
namedWindow(input_title, CV_WINDOW_AUTOSIZE);
// 【2】显示载入的图片
imshow(input_title, srcImage);

// 【3】等待任意按键按下
waitKey(0);
return 0;
}
0f1bdb7618347ac7e75eb294f92f0c95.png 0f1bdb7618347ac7e75eb294f92f0c95.png

往期精选

告诉大家你 在看

  • OpenCV中高效的像素遍历方法,写出工程级像素遍历代码

  • 基于感知损失的实时风格迁移与超分辨率重建

  • 攻略|Tesseract5+VS2017+win10源码编译

ffdefdc8626f94e1b888d7a4a7411a11.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值