专栏首页贾志刚-OpenCV学堂OpenCV中如何获取Mat类型中的步长stride及分析 C++实现

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

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

问题需求:获取Mat stride

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

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

我们可以通过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

深入分析

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 <opencv2/highgui/highgui.hpp>
#include <iostream>
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 " << srcImage.step << endl;
cout << "srcImage.step[0] is " << srcImage.step[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;
}

本文分享自微信公众号 - OpenCV学堂(CVSCHOOL)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-07-03

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 婴儿的出生为你解惑构造函数和构造代码块

    今天回想这几天走过的Java路程,发现漏了一个点,就是构造代码块,我绞尽脑汁,也没想起来它的作用,我骗不了我自己,就搜相关资料,重新学习,在学习的过程中发现...

    泰斗贤若如
  • IDEA为新手专业打造

    泰斗贤若如
  • Java虚拟机(一):JVM简介

    Java虚拟机(JVM)是由Java虚拟机规范定义的,其上运行的是字节码指令集。这种字节码指令集包含一个字节的操作码(opcode),零至多个操作数(opran...

    朝雨忆轻尘
  • Node上传文件(1)

    说到上传下载功能可能大多数人都不会陌生,平时我们接触具有很多类似功能的软件,那么一个基本的上传功能需要有着什么样的处理逻辑呢?上传功能当然不可能...

    逆月翎
  • 一个简单的在线考试系统

    程序源代码
  • Java虚拟机(七):JVM调优案列

       什么是jvm调优呢?jvm调优就是根据gc日志分析jvm内存分配、回收的情况来调整各区域内存比例或者gc回收的策略;更深一层就是根据dump出来的内存结构...

    朝雨忆轻尘
  • 开源ERP

    华夏ERP基于SpringBoot框架,立志为中小企业提供开源好用的ERP软件,目前专注进销存+财务功能。主要模块有零售管理、采购管理、销售管理、仓库管理、财务...

    程序源代码
  • Upsource实现Intellij IDEA上的Code Review

    https://www.jetbrains.com/upsource/download 下载后解压

    十毛
  • Java匹马行天下之JavaSE核心技术——注解

    注解(Annotation)相当于一种标记,在程序中加入注解就等于为程序打上某种标记,没有加,则等于没有任何标记,以后,javac编译器、开发工具和其他程序...

    泰斗贤若如
  • 首发 | OpenVINO开发配套视频教程发布了

    前面写过一系列的OpenVINO相关的技术文章,很多人希望出一套配到的视频教程,经过快两个月的各种煎熬与努力,OpenVINO开发视频教程终于发布了,首先来看看...

    OpenCV学堂

扫码关注云+社区

领取腾讯云代金券