二维图像中Mat::setp、Mat::step1理解

一、前言

       Mat中的step为构成图像的层次,考虑到Mat多应用于二维图像,本文讨论二维图像step的含义和应用。二维图像数据存储示意图如下:

                                                

       如上图所示,该二维图像大小为5*6,图中元素I位于第2行第4列,该元素可具有多个通道,可为1、2、3、4;常见通道数为1或3,相应为灰度图像或RGB图像,RGB图像的通道排列为B分量、G分量、R分量。
二、Mat::setp、Mat::step1
       对于二维图像, setp、step1均为2维,意义为:
setp[0]: 线的数据量大小,单位为字节
setp[1]: 点的数据量大小,单位为字节
step1(0): 线的通道数量
step1(1): 点的通道数量

       上述线、点为构成二维图像数据的层次,例如第2行第4列元素,线、点序号为1、3。

三、示例
       以下对分别对8UC3类型、16UC3类型二维数据进行测试说明

//main.cpp
#include <iostream>

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

using namespace cv;
using namespace std;
int M = 5;
int N  = 6;


int main()
{
	int n = M*N*3;
	uchar * data8UC3 = new uchar[n];
	short * data16UC3 = new short[n];

	for (int i = 0; i < n; ++i){
		data8UC3[i] = i;
		data16UC3[i] = i;
	}
	Mat mat8UC3(M, N, CV_8UC3, data8UC3);
	Mat mat16UC3(M, N, CV_16UC3, data16UC3);

	cout << "*************************8UC3类型二维数据**************************\n";
	cout << "step[0]:" << mat8UC3.step[0]   //18,线大小,单位字节,8UC3,则每个通道数据只需1字节
		<< "\nstep[1]:" << mat8UC3.step[1]      //3,点大小,单位字节
		<< "\nstep1(0):" << mat8UC3.step1(0)   //18, 线的通道数
		<< "\nstep1(1):" << mat8UC3.step1(1);  // 3,点的通道数

	cout << "\n\ncout直接输出矩阵:\n" << mat8UC3<< "\n";

	cout << "\nm.addr(i,j) = m.data + step[0]*i + step[1]*j方式输出矩阵:\n";

	uchar *p8UC3 = mat8UC3.data;
	for (int i = 0; i < M; ++i){
		for (int j = 0; j < N; ++j){
		std:cout << (int)*(p8UC3 + mat8UC3.step[0] * i + mat8UC3.step[1] * j + 0) << " "
			<< (int)*(p8UC3 + mat8UC3.step[0] * i + mat8UC3.step[1] * j + 1) << " "
			<< (int)*(p8UC3 + mat8UC3.step[0] * i + mat8UC3.step[1] * j + 2) << " ";
		}

		std::cout << "\n";
	}

	cout << "\n*************************16UC3类型二维数据**************************\n";
	cout << "step[0]:" << mat16UC3.step[0]    //36,线大小,单位字节,16UC3,则每个通道数据只需2字节
		<< "\nstep[1]:" << mat16UC3.step[1]    //6,点大小,单位字节
		<< "\nstep1(0):" << mat16UC3.step1(0)   //18, 线的通道数
		<< "\nstep1(1):" << mat16UC3.step1(1);  // 3,点的通道数

	cout << "\n\ncout直接输出矩阵:\n" << mat16UC3 << "\n";

	cout << "\nm.addr(i,j) = m.data + step1(0)*i + step1(1)*j方式输出矩阵:\n";

	short *p16UC3 = (short*)mat16UC3.data;
	for (int i = 0; i < M; ++i){
		for (int j = 0; j < N; ++j){
			cout << (int)*(p16UC3 + mat16UC3.step1(0) * i + mat16UC3.step1(1) * j + 0) << " "
				<< (int)*(p16UC3 + mat16UC3.step1(0) * i + mat16UC3.step1(1) * j + 1) << " "
				<< (int)*(p16UC3 + mat16UC3.step1(0) * i + mat16UC3.step1(1) * j + 2) << " ";
		}

		std::cout << "\n";
	}


	delete data8UC3;
	delete data16UC3;
	return 0;
}
四、程序运行结果

                                             

       可见单个通道的数据量不为1字节时,由Mat::data指针访问数据,必须使用step1(0)、step1(1),更细致了解访问Mat中的每个像素值可看这篇博文http://blog.csdn.net/xiaowei_cqu/article/details/19839019

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值