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
相关阅读
作为一个程序员出生的Matlab学习者,不能定义函数那简直是受不了!! 最重要的一点! 定义函数的时候,很多时候都会很迷的一般,使用不了
1.1 MATLAB图像处理基本操作 本文中对于大多数的操作,是对数字图像处理领域中最为著名的“lena”图片进行操作的。原图如下(Figur
原文contour矩阵的等高线图全页折叠语法contour(Z)contour(Z,n)contour(Z,v)contour(X,Y,Z)contour(X,Y,Z,n)contour(X,Y,Z,v)con
javascript:;与javascript:void(0)的理解
void运算符 简介: void 是 javascript 的操作符,意思是:只执行表达式,但没有返回值。该表达式会被计算但是不会在当前文档处装入任何
有这样一幅图, 我们想获取其中的连通区域,可以使用以下代码: src_img_name = 'blue_sky_white_clound_002594.jpg';img = imread(src