在opencv提取矩阵中的元素方法

CV_MAT_ELEM_PTR与CV_MAT_ELEM的用法

从CvMat矩阵中得到一个元素最简单的方法就是利用CV_MAT_ELEM宏,这个宏包含4个参数,分别是传入矩阵,待提取的元素的类型,行数和列数。

        而CV_MAT_ELEM_PTR宏包含3个参数,分别是传入矩阵,行数和列数,返回指定元素的指针。与CV_MAT_ELEM相比,后者在解引用之前将其转换成适当的数据类型,可以同时实现读取和设置元素的功能。

#include "stdafx.h"

#include <opencv2\opencv.hpp>  
#include <iostream>
#include <opencv\cv.hpp>
#include "cv.h"
#include "highgui.h"
#include <cstring>
#include <fstream>  
#include <iterator>  
#include <vector> 
using namespace cv;
int _tmain(int argc, _TCHAR* argv[])
{
	CvMat* mat = cvCreateMat(3, 3, CV_8UC1);    //创建无符号char型单通道3*3矩阵 
	*((char*)CV_MAT_ELEM_PTR(*mat, 0, 0)) = 1;
	//CV_MAT_ELEM_PTR宏获取mat矩阵第0行第0列元素的指针后,将其转换成char*,解引用后再赋值1
	*((char*)CV_MAT_ELEM_PTR(*mat, 0, 1)) = 2;
	*((char*)CV_MAT_ELEM_PTR(*mat, 0, 2)) = 3;
	*((char*)CV_MAT_ELEM_PTR(*mat, 1, 0)) = 4;
	*((char*)CV_MAT_ELEM_PTR(*mat, 1, 1)) = 5;
	*((char*)CV_MAT_ELEM_PTR(*mat, 1, 2)) = 6;
	*((char*)CV_MAT_ELEM_PTR(*mat, 2, 0)) = 7;
	*((char*)CV_MAT_ELEM_PTR(*mat, 2, 1)) = 8;
	*((char*)CV_MAT_ELEM_PTR(*mat, 2, 2)) = 9;

	int var;
	var = CV_MAT_ELEM(*mat, char, 0, 1);//CV_MAT_ELEM宏获取mat矩阵第0行第0列元素
	//cout << "var=" << endl << var << endl;
	printf("var=%d",var);

	system("pause");
	return 0;

}
CV_MAT_ELEM_PTR宏与CV_MAT_ELEM区别是:

后者在指针解引用之前将转化成指定的类型,如果同时需要读取数据和设置数据,可以直接调用前者,但这种情况下,必须自己将指针转化为恰当的类型。
(仅使用访问一维或两维)


CvMat和IplImage元素函数:

cvGet*D和cvPtr*D:

double cvGetReal1D(const CvArr* arr,int idx0) 
double cvGetReal2D(const CvArr* arr,int idx0,int idx1) 

double cvGetReal3D(const CvArr* arr,int idx0,int idx1,int idx2

double cvGetRealND(const CvArr* arr,int *idx) 


CvScalar cvGet1D(const CvArr* arr,int idx0) 
CvScalar cvGet2D(const CvArr* arr, int idx0,int idx1) 

CvScalar cvGet3D(const CvArr* arr, int idx0,int idx1,int idx2

double cvGetND(const CvArr* arr,int *idx) 

 其中CvScalar是一个三个double组成结构体,表示一个像素。

cvGet*D因返回的有CvScalar类型,所以有很大的空间浪费,最好用cvPtr*D

cvPtr*D:

在多通道矩阵中,通道是连续的,即rgbrgbrgbrgb。。。。所以,在使用指向该数据类型的指针移动到下一通道时,只需增加1.

如果想访问下一个像素等,我们要增加一定的偏移量。

技巧:

矩阵数组的step元素,step是矩阵中行的长度,单位是字节。仅靠cols或者wideth是无法在矩阵的不同行之间移动指针的,出于效率的考虑,矩阵或者图像的内存的分配都是4个字节的整数倍。即三个字节的宽度也是4个字节,最后一个被忽略。所以,对应的有整型int或浮点型float的指针指向的数据区域我们将让step/4与指针相加来移到下一行,对于双精度型double的,我们让step/8与指针相加。

CvMat和IplImage元素设定值的函数:

void cvSetReal1D(CvArr*arr,int idx0,double value)

void cvSetReal2D(CvArr*arr,int idx0,int idx1,double value)

void cvSetReal3D(CvArr*arr,int idx0,int idx1,int idx2,double value)

void cvSetRealND(CvArr*arr,int idx0,double value)

void cvSetReal1D(CvArr*arr,int *idx,double value)


void cvSet1D(CvArr*arr,int idx0,CvScaler value)

void cvSet2D(CvArr*arr,int idx0,int idx1,CvScaler value)

void cvSet3D(CvArr*arr,int idx0,int idx1,int idx2,CvScaler value)

void cvSetND(CvArr*arr,int *idx,CvScaler value)

为了方便,也可以使用cvmSet()和cvmGet()用于处理浮点型单通道矩阵。

double cvmGet(const CvMat *mat,int row,int col)

void  cvmSet(const CvMat *mat,int row,int col,double value)=====void cvSetReal2D

相关文章

相关标签/搜索