1. 程式人生 > >二維影象中Mat::setp、Mat::step1理解

二維影象中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;
}
四、程式執行結果