OpenCv矩阵操作函数源代码
- 格式:doc
- 大小:159.00 KB
- 文档页数:38
opencv计算平移和旋转的矩阵opencv中,计算平移和旋转的矩阵可以使用`cv::getRotationMatrix2D()`和`cv::warpAffine()`函数。
下面是一个示例代码:```cpp#include<iostream>#include<opencv2/opencv.hpp>#include<math.h>using namespace std;using namespace cv;int main(){string path = R"(circle.png)";cv::Mat Img = imread(path, IMREAD_GRAYSCALE);cv::threshold(Img, Img, 200, 255, 0);cv::Mat M = cv::Mat::zeros(2, 3, CV_32FC1);double scale = 1; // 缩放因子,1 表示不进行缩放double angle = 60.0 / 180.0 * CV_PI; // 旋转角度,正值表示逆时针旋转 cv::Point2f center = cv::Point2f(img.cols / 2.0, img.rows / 2.0); // 图像旋转的中心位置double a = 0; // 水平平移量double b = 100; // 竖直平移量// 取得旋转矩阵M = cv::getRotationMatrix2D(center, angle, 1);// 图像尺寸扩张(默认扩张方式)cv::warpAffine(Img, img, M, cv::Size(img.cols, img.rows));// 用固定颜色填充扩张的边界cv::Scalar borderColor = Scalar(255, 255, 255);// 复制边缘填充cv::warpAffine(img, img, M, img.size() + cv::Size(500, 1000), 1, BORDER_REPLICATE, borderColor);return 0;}```在上述代码中,首先使用`cv::getRotationMatrix2D()`函数获取旋转矩阵`M`,然后使用`cv::warpAffine。
用c++实现矩阵的基本操作全文共四篇示例,供读者参考第一篇示例:C++是一种功能强大的编程语言,被广泛应用于各种领域,包括矩阵计算。
在本文中,我们将探讨如何使用C++实现矩阵的基本操作,包括矩阵的创建、矩阵的加法、矩阵的乘法等。
1. 矩阵的定义和初始化在C++中,我们可以使用二维数组来表示矩阵。
我们可以定义一个4x3的矩阵如下:```cppint matrix[4][3];```我们还可以使用vector<vector<int>>来表示矩阵,这样可以更方便地处理二维数组:```cppvector<vector<int>> matrix(4, vector<int>(3));```在定义矩阵后,我们需要对矩阵进行初始化。
我们可以通过循环遍历的方法对矩阵进行初始化,例如:```cppfor (int i = 0; i < 4; i++) {for (int j = 0; j < 3; j++) {matrix[i][j] = i + j;}}```2. 矩阵的加法矩阵的加法是矩阵运算中最基本的操作之一。
我们可以通过循环遍历的方法实现两个矩阵的加法。
假设我们有两个相同大小的矩阵matrix1和matrix2,我们可以按照如下方式进行加法操作:矩阵的转置是将矩阵的行和列进行交换的操作。
我们可以通过如下方式实现矩阵的转置:```cppvector<vector<int>> transpose(vector<vector<int>> matrix) {int m = matrix.size();int n = matrix[0].size();vector<vector<int>> result(n, vector<int>(m));for (int i = 0; i < m; i++) {for (int j = 0; j < n; j++) {result[j][i] = matrix[i][j];}}return result;}```矩阵的求逆是一个复杂的操作,需要使用高级的数学知识和算法。
imread 读图namedWindow 产生一个被命名的窗口imshow 显示图像using namespace 全局的命名空间,可以避免导致全局命名冲突问题。
cv表示opencv的命名空间std是标准输入输出的命名空间waitKey 程序运行等待时间ms为单位#include<opencv2/highgui/highgui.hpp> 包含输入输出操作#include<iostream> VC的标准输入输出cout << 输出cin>> 输入均以endl结尾#include<string> 字符串库cvtColor 彩色图像变灰度图像imwrite 写出图像F9设置断点F5调试运行后点击变量中的+显示数据结构argv[1]的定位方式为:在工程属性中,命令行参数添加路径,例如:#include<opencv2/core/core.hpp> 定义的基本构建块库Mat 基本图像容器,是一个矩阵类。
用法:Mat A; //定义矩阵Mat B(A);//复制A矩阵数据给BMat D(A,Rect(10, 10, 100, 100)); //将A矩阵的一个区域给DMat F = A.clone();//复制A矩阵数据给FMat M(2,2,CV_8UC3,Scalar(0,0,255));//创建一个矩阵,2×2大小,数据结构为CV_[每个数据占用BIT][Signed or Unsigned][Type Prefix]C[取前几个数或书写几遍] Scalar数据向量。
Signed有符号:8位数据范围为:-128~127Unsigned无符号:8位数据范围为:0~255Mat::eye(4, 4,CV_64F) //单位矩阵Mat::ones(2, 2,CV_32F) //全1矩阵Mat::zeros(3,3,CV_8UC1) //全0矩阵Mat C = (Mat_<double>(3,3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);//常规矩阵定义randu(R,Scalar::all(0),Scalar::all(255));//任意矩阵的生成Point2f P(5, 1);//定义二维点Point3f P3f(2, 6, 7); //定义三维点vector<float> v;//定义浮点数向量vector<Point2f> vPoints(20);//定义点坐标(二维数据)向量uchar就是uint8加注const 不能改变参数值;sizeof 读取大小I.channels(); //图像维数I.rows; //图像的行数I.cols;//图像的列数I.depth();//图像的深度对于图像的点式处理:uchar* p;//定义一个uint8图像for(i = 0;i < nRows; ++i){p = I.ptr<uchar>(i); //将每一行的向量赋给pfor (j = 0;j < nCols; ++j){p[j] = table[p[j]];//对每一行的向量,每一列的元素进行赋值,table是变换好的数组}}或者:uchar* p = I.data;//将图像的数据空间给pfor( unsigned int i =0;i < ncol*nrows; ++i)*p++ = table[*p];//*p中存储了图像的数据,一个一个赋值或者:LUT(I,lookUpTable,J); //效率最高的读图方式Mat lookUpTable(1, 256,CV_8U);uchar * p2 = lookUpTable.data;for( int i = 0;i < 256; ++i)p2[i] = table[i];图像的RGB分离:const int channels = I.channels();switch(channels){case 1:{MatIterator_<uchar> it,end;//灰度图像的变换for(it = I.begin<uchar>(),end = I.end<uchar>();it != end; ++it)*it = table[*it];break;}case 3:{MatIterator_<Vec3b> it,end;//RGB图像的变换for(it = I.begin<Vec3b>(),end = I.end<Vec3b>();it != end; ++it)//<Vec3b>指三列向量,即三个通道分量{(*it)[0] = table[(*it)[0]];//B分量(*it)[1] = table[(*it)[1]]; //G分量(*it)[2] = table[(*it)[2]]; //R分量}}}或者:case 3:{Mat_<Vec3b> _I = I;for( int i = 0;i < I.rows; ++i)for( int j = 0;j < I.cols; ++j){_I(i,j)[0] = table[_I(i,j)[0]];_I(i,j)[1] = table[_I(i,j)[1]];_I(i,j)[2] = table[_I(i,j)[2]];}I = _I;break;}Mat& ScanImageAndReduceC(Mat& I, const uchar* const table)//看图函数Mat& ScanImageAndReduceIterator(Mat& I, const uchar* const table) //看图函数Mat& ScanImageAndReduceRandomAccess(Mat& I, const uchar* const table) //看图函数模板运算:void Sharpen(const Mat& myImage, Mat& Result) //图像锐化函数CV_Assert(myImage.depth() == CV_8U); //判决图像是否是整型的数据Result.create(myImage.size(),myImage.type());//创建MAT矩阵类型执行算法:for(int j = 1 ;j < myImage.rows-1; ++j){const uchar* previous = myImage.ptr<uchar>(j - 1);const uchar* current = myIma ge.ptr<uchar>(j);const uchar* next = myImage.ptr<uchar>(j + 1);uchar* output = Result.ptr<uchar>(j);for(int i= nChannels;i < nChannels*(myImage.cols-1); ++i){*output++ = saturate_cast<uchar>(5*current[i]-current[i-nChannels] - current[i+nChannels] - previous[i] - next[i]);}}Result.row(0).setTo(Scalar(0));//将0行的像素值设为0或者:Mat kern = (Mat_<char>(3,3) << 0, -1, 0,-1, 5, -1,0, -1, 0);filter2D(I,K,I.depth(),kern);//使用模板滤波锐化图像,该函数所在库为<opencv2/imgproc/imgproc.hpp>图像融合算法:addWeighted(src1,alpha,src2,beta, 0.0,dst);//融合函数,需两幅图像一样大图像的亮度调整算法:相应的代码for( int y = 0;y < image.rows;y++ ){ for( int x = 0;x < image.cols;x++ ){ for( int c = 0;c < 3;c++ ) //三个通道分别运算{new_image.at<Vec3b>(y,x)[c] =saturate_cast<uchar>(alpha*(image.at<Vec3b>(y,x)[c]) + beta);}}}Mat::zeros(image.size(),image.type());//创建0阵image.convertTo(new_image, -1,alpha,beta);//线性图像变换图元:Point pt = Point(10, 8);//点的坐标Scalar(B,G,R) ;//给出像素的颜色值ellipse( img,Point(x,y),Size(x,y), angle,0, 360,Scalar( 255, 0, 0 ),thickness, lineType );//画椭圆,img图像名,point中心点,size大小,angle角度,0,起始点角度,360终点角度,scalar色彩,thickness线宽(-1为全填充),lineType 线型;调用时凡是给定的参数不管,只需给出其他参数,例如Ellipse( atom_image, 90 );给出了图像名和角度,其他量为已知。
opencv 是一个开源计算机视觉库,提供了丰富的图像处理和计算机视觉功能。
本文将介绍 opencv 中的旋转矩阵到 rodrigues 转换的相关知识。
1. 介绍 opencv 中的旋转矩阵和 rodrigues 转换opencv 中的旋转矩阵是一个 3x3 的矩阵,用于表示三维空间中的旋转操作。
而 rodrigues 转换则是将旋转矩阵转换为对应的旋转向量,方便进行旋转操作的表示和计算。
2. 旋转矩阵到 rodrigues 转换的实现方法在 opencv 中,可以使用 cv::Rodrigues 函数来实现旋转矩阵到rodrigues 转换。
该函数的原型为:void Rodrigues(InputArray src, OutputArray dst, OutputArray jacobian= noArray())其中,src 表示输入的旋转矩阵,dst 表示输出的旋转向量,jacobian 表示可选的旋转矩阵的导数,如果不需要可以不传入。
3. 旋转矩阵到 rodrigues 转换的应用场景在计算机视觉和机器人领域,经常需要进行旋转操作的表示和计算。
旋转矩阵到 rodrigues 转换提供了一种便捷的方式来进行旋转操作的表示和计算,广泛应用于相机姿态估计、目标跟踪和三维重建等领域。
4. 实例演示:将旋转矩阵转换为 rodrigues 向量接下来,我们通过一个实例来演示将旋转矩阵转换为 rodrigues 向量的过程。
假设我们有一个旋转矩阵 R,我们可以通过以下代码来实现转换:```cppcv::Mat R = (cv::Mat_<double>(3, 3) <<0.866, -0.5, 0,0.5, 0.866, 0,0, 0, 1);cv::Mat rvec;cv::Rodrigues(R, rvec);```通过以上代码,我们成功将旋转矩阵 R 转换为了 rodrigues 向量 rvec。
C语言实现矩阵计算C语言是一种广泛使用的编程语言,也是实现矩阵计算的一种常用工具。
在C语言中,我们可以使用数组来表示矩阵,并通过循环结构和算术运算符来实现矩阵计算的各种功能。
首先,我们需要实现矩阵的输入和输出功能。
在C语言中,我们可以使用二维数组来表示矩阵。
下面是一个示例代码,用来输入和显示一个矩阵:```c#include <stdio.h>//定义最大矩阵的大小#define MAX_SIZE 100//函数用于输入一个矩阵void inputMatrix(int matrix[MAX_SIZE][MAX_SIZE], int rows, int cols)printf("请输入矩阵元素:\n");for (int i = 0; i < rows; i++)for (int j = 0; j < cols; j++)scanf("%d", &matrix[i][j]);}}//函数用于显示一个矩阵void displayMatrix(int matrix[MAX_SIZE][MAX_SIZE], int rows, int cols)printf("矩阵元素为:\n");for (int i = 0; i < rows; i++)for (int j = 0; j < cols; j++)printf("%d ", matrix[i][j]);}printf("\n");}```上述代码定义了两个函数:`inputMatrix`用于输入一个矩阵,`displayMatrix`用于显示一个矩阵。
我们可以通过调用这两个函数来输入和显示矩阵。
接下来,我们可以实现矩阵的加法、减法和乘法等功能。
以下是一个示例代码,用于实现矩阵的加法:```c//函数用于计算两个矩阵的加法void addMatrix(int matrix1[MAX_SIZE][MAX_SIZE], intmatrix2[MAX_SIZE][MAX_SIZE], int result[MAX_SIZE][MAX_SIZE], int rows, int cols)for (int i = 0; i < rows; i++)for (int j = 0; j < cols; j++)result[i][j] = matrix1[i][j] + matrix2[i][j];}}```上述代码中,我们定义了一个`addMatrix`函数,该函数接受两个输入矩阵和一个结果矩阵,将两个输入矩阵的对应元素相加,并将结果存储在结果矩阵中。
c++ opencv的欧拉角转旋转矩阵下载提示:该文档是本店铺精心编制而成的,希望大家下载后,能够帮助大家解决实际问题。
文档下载后可定制修改,请根据实际需要进行调整和使用,谢谢!本店铺为大家提供各种类型的实用资料,如教育随笔、日记赏析、句子摘抄、古诗大全、经典美文、话题作文、工作总结、词语解析、文案摘录、其他资料等等,想了解不同资料格式和写法,敬请关注!Download tips: This document is carefully compiled by this editor. I hope that after you download it, it can help you solve practical problems. The document can be customized and modified after downloading, please adjust and use it according to actual needs, thank you! In addition, this shop provides you with various types of practical materials, such as educational essays, diary appreciation, sentence excerpts, ancient poems, classic articles, topic composition, work summary, word parsing, copy excerpts, other materials and so on, want to know different data formats and writing methods, please pay attention!欧拉角是描述刚体在空间中旋转姿态的一种方法,通常可以用三个角度来表示。
opencv的warpaffine函数的源代码实现-回复OpenCV是一个强大的计算机视觉库,提供了许多图像处理和计算机视觉算法。
其中,warpAffine函数是OpenCV中的一个重要函数,用于对图像进行仿射变换。
在本文中,我们将一步一步地回答"[opencv的warpaffine函数的源代码实现]" 这个问题,探讨warpAffine函数的实现细节。
首先,我们需要了解仿射变换的概念。
仿射变换是一种平面几何变换,保持了一些线段的相对平行性和长度比例。
它可以描述平面上的旋转、平移、缩放和剪切等几何变换操作。
在OpenCV中,warpAffine函数的原型如下所示:cv2.warpAffine(src, M, dsize[, dst[, flags[, borderMode[, borderValue]]]])其中,参数说明如下:- src: 输入图像,可以是任意维度的数组。
- M: 2x3的仿射变换矩阵。
- dsize: 输出图像的大小,即变换后的图像尺寸。
- dst: 可选参数,输出图像。
- flags: 可选参数,用于确定插值方法。
默认为线性插值。
- borderMode: 可选参数,用于确定边界像素的处理方式。
默认为边界像素的复制。
- borderValue: 可选参数,用于设置边界像素的值。
默认为0。
了解了warpAffine函数的参数,接下来我们将一步一步讨论函数的源代码实现。
首先,我们需要导入相应的库。
pythonimport numpy as np接下来,我们将创建一个函数来实现warpAffine功能。
pythondef warpAffine(src, M, dsize, dst=None, flags=None, borderMode=None, borderValue=None):# 确定输出图像的大小if dst is None:dst = np.zeros(dsize, dtype=src.dtype)else:assert dst.shape == dsize# 提取仿射变换矩阵的参数M = np.float32(M[:2])# 计算输出图像的尺寸rows, cols = dst.shape[:2]# 循环遍历输出图像的每个像素for row in range(rows):for col in range(cols):# 计算输入图像中的对应坐标input_coords = M.dot(np.array([col, row, 1]))x, y = input_coords[:2] / input_coords[2]# 判断坐标是否在输入图像范围内if x >= 0 and x < src.shape[1] and y >= 0 and y < src.shape[0]:# 使用插值方法计算输出图像中的像素值if flags is not None and flags !=cv2.INTER_NEAREST:# 使用双线性插值f_x = int(x)c_x = f_x + 1 if f_x < src.shape[1] - 1 else f_xf_y = int(y)c_y = f_y + 1 if f_y < src.shape[0] - 1 else f_yalpha = x - f_xbeta = y - f_ydst[row, col] = (1 - alpha) * (1 - beta) * src[f_y, f_x] + \(1 - alpha) * beta * src[c_y, f_x] + \alpha * (1 - beta) * src[f_y, c_x] + \alpha * beta * src[c_y, c_x]else:# 使用最近邻插值dst[row, col] = src[int(y), int(x)]# 处理边界像素elif borderMode is not None:if borderMode == cv2.BORDER_CONSTANT:# 使用常数填充边界像素dst[row, col] = borderValueelif borderMode == cv2.BORDER_REPLICATE:# 使用复制边界像素x = min(max(x, 0), src.shape[1] - 1)y = min(max(y, 0), src.shape[0] - 1)dst[row, col] = src[int(y), int(x)]return dst让我们逐行解释一下这段源代码的实现。
OpenCV源码架构讲解1. Core(核心):此模块包含了OpenCV的核心功能,如矩阵操作、数据类型、数组和向量运算等。
该模块提供了基础的数据结构和函数,为其他模块的实现提供支持。
2. Imgproc(图像处理):此模块提供了各种图像处理函数,如滤波、边缘检测、图像变换等。
它包含了大量的图像处理算法,并提供了丰富的工具函数,方便用户进行图像处理操作。
3. Highgui(图形用户界面):该模块提供了图形用户界面相关的函数,如图像显示、鼠标事件处理、键盘事件处理等。
它可以帮助用户在图像处理过程中进行交互操作,方便调试和分析。
4. Video(视频处理):此模块提供了与视频处理相关的函数,如视频捕捉、视频压缩、视频写入等。
它支持从摄像机、文件或其他源中读取视频流,并提供了一系列的视频处理算法。
5. Objdetect(对象检测):该模块提供了对象检测相关的函数,如人脸检测、行人检测等。
它提供了训练好的模型和相应的算法,可以用于识别和跟踪不同种类的对象。
此外,OpenCV还包含了一些辅助模块,如ml(机器学习)、calib3d (相机标定和三维重建)、features2d(特征检测和描述子)、videoio (视频IO)、flann(最近邻)等。
OpenCV的源码采用模块化的结构,使得用户可以灵活地选择所需的模块,以适应不同的应用场景。
每个模块都有自己的命名空间和头文件,以避免命名冲突。
同时,源码还提供了丰富的示例和文档,方便用户使用和理解。
在OpenCV的源码中,各个模块之间存在着一定的依赖关系,需要进行编译和链接才能生成可执行文件。
此外,OpenCV还提供了对Python、Java等语言的接口,使得用户可以在不同的平台上使用OpenCV。
总之,OpenCV的源码架构是基于C++实现的,模块化设计使得用户可以方便地选择所需的功能模块。
各个模块之间存在着一定的依赖关系,通过编译和链接可以生成可执行文件。
minmaxloc opencv代码实例全文共四篇示例,供读者参考第一篇示例:MinMaxLoc是OpenCV中一个常用的函数,用于查找矩阵中的最小值、最大值以及它们对应的位置。
MinMaxLoc函数有多种重载形式,可以根据具体需求选择合适的使用方式。
下面我们通过一个简单的代码示例来展示MinMaxLoc函数的用法。
我们需要在代码中引入OpenCV库。
```cpp#include <opencv2/opencv.hpp>```接下来,我们创建一个简单的示例函数,该函数会生成一个随机的矩阵,并使用MinMaxLoc函数找到矩阵中的最小值、最大值以及它们的位置。
```cppvoid minMaxLocExample(){// 生成一个3x3的随机矩阵cv::Mat matrix = cv::Mat::ones(3, 3, CV_8UC1);cv::randu(matrix, cv::Scalar(0), cv::Scalar(255));// 打印矩阵内容std::cout << "Matrix:" << std::endl;std::cout << matrix << std::endl;MinMaxLoc函数通常用于在图像处理中定位图像中的最亮点和最暗点,或者在特征匹配算法中用于找到最相似的特征点。
需要注意的是,MinMaxLoc函数在处理多通道矩阵时需要指定通道索引。
还可以通过使用掩模来限定MinMaxLoc函数的搜索范围。
第二篇示例:MinMaxLoc是OpenCV库中的一个函数,用于查找矩阵或图像中的最小值或最大值,并返回它们的位置。
这一功能在图像处理和计算机视觉中非常有用,可以帮助我们找到图像中的特定区域或物体。
在本文中,我们将介绍如何在OpenCV中使用MinMaxLoc函数,以及如何实现一个简单的示例来演示其用法。
/* //////////////////////////////////////////////////////////////////////// CvMat, CvMatND, CvSparceMat and IplImage support functions// (creation, deletion, copying, retrieving and setting elements etc.)//// */#include "_cxcore.h"static struct{Cv_iplCreateImageHeader createHeader;Cv_iplAllocateImageData allocateData;Cv_iplDeallocate deallocate;Cv_iplCreateROI createROI;Cv_iplCloneImage cloneImage;}CvIPL;// Makes the library use native IPL image allocatorsCV_IMPL voidcvSetIPLAllocators( Cv_iplCreateImageHeader createHeader,Cv_iplAllocateImageData allocateData,Cv_iplDeallocate deallocate,Cv_iplCreateROI createROI,Cv_iplCloneImage cloneImage ){CV_FUNCNAME( "cvSetIPLAllocators" );__BEGIN__;if( !createHeader || !allocateData || !deallocate || !createROI || !cloneImage ){if( createHeader || allocateData || deallocate || createROI || cloneImage ) CV_ERROR( CV_StsBadArg, "Either all the pointers should be null or ""they all should be non-null" );}CvIPL.createHeader = createHeader;CvIPL.allocateData = allocateData;CvIPL.deallocate = deallocate;CvIPL.createROI = createROI;CvIPL.cloneImage = cloneImage;__END__;}/****************************************************************************** **********\* CvMat creation and basic operations *\****************************************************************************** **********/// Creates CvMat and underlying dataCV_IMPL CvMat*cvCreateMat( int height, int width, int type ){CvMat* arr = 0;CV_FUNCNAME( "cvCreateMat" );__BEGIN__;CV_CALL( arr = cvCreateMatHeader( height, width, type ));CV_CALL( cvCreateData( arr ));__END__;if( cvGetErrStatus() < 0 )cvReleaseMat( &arr );return arr;}static void icvCheckHuge( CvMat* arr ){if( (int64)arr->step*arr->rows > INT_MAX )arr->type &= ~CV_MA T_CONT_FLAG;}// Creates CvMat header onlyCV_IMPL CvMat*cvCreateMatHeader( int rows, int cols, int type ){CvMat* arr = 0;CV_FUNCNAME( "cvCreateMatHeader" );__BEGIN__;int min_step;type = CV_MA T_TYPE(type);if( rows <= 0 || cols <= 0 )CV_ERROR( CV_StsBadSize, "Non-positive width or height" );min_step = CV_ELEM_SIZE(type)*cols;if( min_step <= 0 )CV_ERROR( CV_StsUnsupportedFormat, "Invalid matrix type" );CV_CALL( arr = (CvMat*)cvAlloc( sizeof(*arr)));arr->step = rows == 1 ? 0 : cvAlign(min_step, CV_DEFAULT_MA T_ROW_ALIGN);arr->type = CV_MA T_MAGIC_V AL | type |(arr->step == 0 || arr->step == min_step ? CV_MA T_CONT_FLAG : 0);arr->rows = rows;arr->cols = cols;arr->data.ptr = 0;arr->refcount = 0;arr->hdr_refcount = 1;icvCheckHuge( arr );__END__;if( cvGetErrStatus() < 0 )cvReleaseMat( &arr );return arr;}// Initializes CvMat header, allocated by the userCV_IMPL CvMat*cvInitMatHeader( CvMat* arr, int rows, int cols,int type, void* data, int step ){CV_FUNCNAME( "cvInitMatHeader" );__BEGIN__;int mask, pix_size, min_step;if( !arr )CV_ERROR_FROM_CODE( CV_StsNullPtr );if( (unsigned)CV_MA T_DEPTH(type) > CV_DEPTH_MAX ) CV_ERROR_FROM_CODE( CV_BadNumChannels );if( rows <= 0 || cols <= 0 )CV_ERROR( CV_StsBadSize, "Non-positive cols or rows" );type = CV_MA T_TYPE( type );arr->type = type | CV_MA T_MAGIC_V AL;arr->rows = rows;arr->cols = cols;arr->data.ptr = (uchar*)data;arr->refcount = 0;arr->hdr_refcount = 0;mask = (arr->rows <= 1) - 1;pix_size = CV_ELEM_SIZE(type);min_step = arr->cols*pix_size & mask;if( step != CV_AUTOSTEP && step != 0 ){if( step < min_step )CV_ERROR_FROM_CODE( CV_BadStep );arr->step = step & mask;}else{arr->step = min_step;}arr->type = CV_MA T_MAGIC_V AL | type |(arr->step == min_step ? CV_MA T_CONT_FLAG : 0);icvCheckHuge( arr );__END__;return arr;// Deallocates the CvMat structure and underlying dataCV_IMPL voidcvReleaseMat( CvMat** array ){CV_FUNCNAME( "cvReleaseMat" );__BEGIN__;if( !array )CV_ERROR_FROM_CODE( CV_HeaderIsNull );if( *array ){CvMat* arr = *array;if( !CV_IS_MA T_HDR(arr) && !CV_IS_MA TND_HDR(arr) )CV_ERROR_FROM_CODE( CV_StsBadFlag );*array = 0;cvDecRefData( arr );cvFree( &arr );}__END__;}// Creates a copy of matrixCV_IMPL CvMat*cvCloneMat( const CvMat* src ){CvMat* dst = 0;CV_FUNCNAME( "cvCloneMat" );__BEGIN__;if( !CV_IS_MA T_HDR( src ))CV_ERROR( CV_StsBadArg, "Bad CvMat header" );CV_CALL( dst = cvCreateMatHeader( src->rows, src->cols, src->type ));if( src->data.ptr ){CV_CALL( cvCreateData( dst ));CV_CALL( cvCopy( src, dst ));}__END__;return dst;}/****************************************************************************** **********\* CvMatND creation and basic operations *\****************************************************************************** **********/CV_IMPL CvMatND*cvInitMatNDHeader( CvMatND* mat, int dims, const int* sizes,int type, void* data ){CvMatND* result = 0;CV_FUNCNAME( "cvInitMatNDHeader" );__BEGIN__;type = CV_MA T_TYPE(type);int i;int64 step = CV_ELEM_SIZE(type);if( !mat )CV_ERROR( CV_StsNullPtr, "NULL matrix header pointer" );if( step == 0 )CV_ERROR( CV_StsUnsupportedFormat, "invalid array data type" );if( !sizes )CV_ERROR( CV_StsNullPtr, "NULL <sizes> pointer" );if( dims <= 0 || dims > CV_MAX_DIM )CV_ERROR( CV_StsOutOfRange,"non-positive or too large number of dimensions" );for( i = dims - 1; i >= 0; i-- ){if( sizes[i] <= 0 )CV_ERROR( CV_StsBadSize, "one of dimesion sizes is non-positive" );mat->dim[i].size = sizes[i];if( step > INT_MAX )CV_ERROR( CV_StsOutOfRange, "The array is too big" );mat->dim[i].step = (int)step;step *= sizes[i];}mat->type = CV_MA TND_MAGIC_V AL | (step <= INT_MAX ? CV_MA T_CONT_FLAG : 0) | type;mat->dims = dims;mat->data.ptr = (uchar*)data;mat->refcount = 0;mat->hdr_refcount = 0;result = mat;__END__;if( cvGetErrStatus() < 0 && mat ){mat->type = 0;mat->data.ptr = 0;}return result;}// Creates CvMatND and underlying dataCV_IMPL CvMatND*cvCreateMatND( int dims, const int* sizes, int type ){CvMatND* arr = 0;CV_FUNCNAME( "cvCreateMatND" );__BEGIN__;CV_CALL( arr = cvCreateMatNDHeader( dims, sizes, type ));CV_CALL( cvCreateData( arr ));__END__;if( cvGetErrStatus() < 0 )cvReleaseMatND( &arr );return arr;}// Creates CvMatND header onlyCV_IMPL CvMatND*cvCreateMatNDHeader( int dims, const int* sizes, int type ){CvMatND* arr = 0;CV_FUNCNAME( "cvCreateMatNDHeader" );__BEGIN__;if( dims <= 0 || dims > CV_MAX_DIM )CV_ERROR( CV_StsOutOfRange,"non-positive or too large number of dimensions" );CV_CALL( arr = (CvMatND*)cvAlloc( sizeof(*arr) ));CV_CALL( cvInitMatNDHeader( arr, dims, sizes, type, 0 ));arr->hdr_refcount = 1;__END__;if( cvGetErrStatus() < 0 )cvReleaseMatND( &arr );return arr;}// Creates a copy of nD arrayCV_IMPL CvMatND*cvCloneMatND( const CvMatND* src ){CvMatND* dst = 0;CV_FUNCNAME( "cvCloneMatND" );__BEGIN__;int i, *sizes;if( !CV_IS_MA TND_HDR( src ))CV_ERROR( CV_StsBadArg, "Bad CvMatND header" );sizes = (int*)alloca( src->dims*sizeof(sizes[0]) );for( i = 0; i < src->dims; i++ )sizes[i] = src->dim[i].size;CV_CALL( dst = cvCreateMatNDHeader( src->dims, sizes, src->type ));if( src->data.ptr ){CV_CALL( cvCreateData( dst ));CV_CALL( cvCopy( src, dst ));}__END__;return dst;}static CvMatND*cvGetMatND( const CvArr* arr, CvMatND* matnd, int* coi ){CvMatND* result = 0;CV_FUNCNAME( "cvGetMatND" );__BEGIN__;if( coi )*coi = 0;if( !matnd || !arr )CV_ERROR( CV_StsNullPtr, "NULL array pointer is passed" );if( CV_IS_MA TND_HDR(arr)){if( !((CvMatND*)arr)->data.ptr )CV_ERROR( CV_StsNullPtr, "The matrix has NULL data pointer" );result = (CvMatND*)arr;}else{CvMat stub, *mat = (CvMat*)arr;if( CV_IS_IMAGE_HDR( mat ))CV_CALL( mat = cvGetMat( mat, &stub, coi ));if( !CV_IS_MA T_HDR( mat ))CV_ERROR( CV_StsBadArg, "Unrecognized or unsupported array type" );if( !mat->data.ptr )CV_ERROR( CV_StsNullPtr, "Input array has NULL data pointer" );matnd->data.ptr = mat->data.ptr;matnd->refcount = 0;matnd->hdr_refcount = 0;matnd->type = mat->type;matnd->dims = 2;matnd->dim[0].size = mat->rows;matnd->dim[0].step = mat->step;matnd->dim[1].size = mat->cols;matnd->dim[1].step = CV_ELEM_SIZE(mat->type);result = matnd;}__END__;return result;}// returns number of dimensions to iterate./*Checks whether <count> arrays have equal type, sizes (mask is optional arraythat needs to have the same size, but 8uC1 or 8sC1 type).Returns number of dimensions to iterate through:0 means that all arrays are continuous,1 means that all arrays are vectors of continuous arrays etc.and the size of largest common continuous part of the arrays*/CV_IMPL intcvInitNArrayIterator( int count, CvArr** arrs,const CvArr* mask, CvMatND* stubs,CvNArrayIterator* iterator, int flags ){int dims = -1;CV_FUNCNAME( "cvInitArrayOp" );__BEGIN__;int i, j, size, dim0 = -1;int64 step;CvMatND* hdr0 = 0;if( count < 1 || count > CV_MAX_ARR )CV_ERROR( CV_StsOutOfRange, "Incorrect number of arrays" );if( !arrs || !stubs )CV_ERROR( CV_StsNullPtr, "Some of required array pointers is NULL" );if( !iterator )CV_ERROR( CV_StsNullPtr, "Iterator pointer is NULL" );for( i = 0; i <= count; i++ ){const CvArr* arr = i < count ? arrs[i] : mask;CvMatND* hdr;if( !arr ){if( i < count )CV_ERROR( CV_StsNullPtr, "Some of required array pointers is NULL" );break;}if( CV_IS_MA TND( arr ))hdr = (CvMatND*)arr;else{int coi = 0;CV_CALL( hdr = cvGetMatND( arr, stubs + i, &coi ));if( coi != 0 )CV_ERROR( CV_BadCOI, "COI set is not allowed here" );}iterator->hdr[i] = hdr;if( i > 0 ){if( hdr->dims != hdr0->dims )CV_ERROR( CV_StsUnmatchedSizes,"Number of dimensions is the same for all arrays" );if( i < count ){switch( flags & (CV_NO_DEPTH_CHECK|CV_NO_CN_CHECK)){case 0:if( !CV_ARE_TYPES_EQ( hdr, hdr0 ))CV_ERROR( CV_StsUnmatchedFormats,"Data type is not the same for all arrays" );break;case CV_NO_DEPTH_CHECK:if( !CV_ARE_CNS_EQ( hdr, hdr0 ))CV_ERROR( CV_StsUnmatchedFormats,"Number of channels is not the same for all arrays" );break;case CV_NO_CN_CHECK:if( !CV_ARE_CNS_EQ( hdr, hdr0 ))CV_ERROR( CV_StsUnmatchedFormats,"Depth is not the same for all arrays" );break;}}else{if( !CV_IS_MASK_ARR( hdr ))CV_ERROR( CV_StsBadMask, "Mask should have 8uC1 or 8sC1 data type" );}if( !(flags & CV_NO_SIZE_CHECK) ){for( j = 0; j < hdr->dims; j++ )if( hdr->dim[j].size != hdr0->dim[j].size )CV_ERROR( CV_StsUnmatchedSizes,"Dimension sizes are the same for all arrays" );}}elsehdr0 = hdr;step = CV_ELEM_SIZE(hdr->type);for( j = hdr->dims - 1; j > dim0; j-- ){if( step != hdr->dim[j].step )break;step *= hdr->dim[j].size;}if( j == dim0 && step > INT_MAX )j++;if( j > dim0 )dim0 = j;iterator->hdr[i] = (CvMatND*)hdr;iterator->ptr[i] = (uchar*)hdr->data.ptr;}size = 1;for( j = hdr0->dims - 1; j > dim0; j-- )size *= hdr0->dim[j].size;dims = dim0 + 1;iterator->dims = dims;iterator->count = count;iterator->size = cvSize(size,1);for( i = 0; i < dims; i++ )iterator->stack[i] = hdr0->dim[i].size;__END__;return dims;}// returns zero value if iteration is finished, non-zero otherwiseCV_IMPL int cvNextNArraySlice( CvNArrayIterator* iterator ){assert( iterator != 0 );int i, dims, size = 0;for( dims = iterator->dims; dims > 0; dims-- ){for( i = 0; i < iterator->count; i++ )iterator->ptr[i] += iterator->hdr[i]->dim[dims-1].step;if( --iterator->stack[dims-1] > 0 )break;size = iterator->hdr[0]->dim[dims-1].size;for( i = 0; i < iterator->count; i++ )iterator->ptr[i] -= (size_t)size*iterator->hdr[i]->dim[dims-1].step;iterator->stack[dims-1] = size;}return dims > 0;}/****************************************************************************** **********\* CvSparseMat creation and basic operations *\****************************************************************************** **********/// Creates CvMatND and underlying dataCV_IMPL CvSparseMat*cvCreateSparseMat( int dims, const int* sizes, int type ){CvSparseMat* arr = 0;CV_FUNCNAME( "cvCreateSparseMat" );__BEGIN__;type = CV_MA T_TYPE( type );int pix_size1 = CV_ELEM_SIZE1(type);int pix_size = pix_size1*CV_MA T_CN(type);int i, size;CvMemStorage* storage;if( pix_size == 0 )CV_ERROR( CV_StsUnsupportedFormat, "invalid array data type" );if( dims <= 0 || dims > CV_MAX_DIM_HEAP )CV_ERROR( CV_StsOutOfRange, "bad number of dimensions" );if( !sizes )CV_ERROR( CV_StsNullPtr, "NULL <sizes> pointer" );for( i = 0; i < dims; i++ ){if( sizes[i] <= 0 )CV_ERROR( CV_StsBadSize, "one of dimesion sizes is non-positive" );}CV_CALL( arr = (CvSparseMat*)cvAlloc(sizeof(*arr)+MAX(0,dims-CV_MAX_DIM)*sizeof(arr->size[0])));arr->type = CV_SPARSE_MA T_MAGIC_V AL | type;arr->dims = dims;arr->refcount = 0;arr->hdr_refcount = 1;memcpy( arr->size, sizes, dims*sizeof(sizes[0]));arr->valoffset = (int)cvAlign(sizeof(CvSparseNode), pix_size1);arr->idxoffset = (int)cvAlign(arr->valoffset + pix_size, sizeof(int));size = (int)cvAlign(arr->idxoffset + dims*sizeof(int), sizeof(CvSetElem));CV_CALL( storage = cvCreateMemStorage( CV_SPARSE_MA T_BLOCK ));CV_CALL( arr->heap = cvCreateSet( 0, sizeof(CvSet), size, storage ));arr->hashsize = CV_SPARSE_HASH_SIZE0;size = arr->hashsize*sizeof(arr->hashtable[0]);CV_CALL( arr->hashtable = (void**)cvAlloc( size ));memset( arr->hashtable, 0, size );__END__;if( cvGetErrStatus() < 0 )cvReleaseSparseMat( &arr );return arr;}// Creates CvMatND and underlying dataCV_IMPL voidcvReleaseSparseMat( CvSparseMat** array ){CV_FUNCNAME( "cvReleaseSparseMat" );__BEGIN__;if( !array )CV_ERROR_FROM_CODE( CV_HeaderIsNull );if( *array ){CvSparseMat* arr = *array;if( !CV_IS_SPARSE_MA T_HDR(arr) )CV_ERROR_FROM_CODE( CV_StsBadFlag );*array = 0;cvReleaseMemStorage( &arr->heap->storage );cvFree( &arr->hashtable );cvFree( &arr );}__END__;}// Creates CvMatND and underlying dataCV_IMPL CvSparseMat*cvCloneSparseMat( const CvSparseMat* src ){CvSparseMat* dst = 0;CV_FUNCNAME( "cvCloneSparseMat" );__BEGIN__;if( !CV_IS_SPARSE_MA T_HDR(src) )CV_ERROR( CV_StsBadArg, "Invalid sparse array header" );CV_CALL( dst = cvCreateSparseMat( src->dims, src->size, src->type ));CV_CALL( cvCopy( src, dst ));__END__;if( cvGetErrStatus() < 0 )cvReleaseSparseMat( &dst );return dst;}CvSparseNode*cvInitSparseMatIterator( const CvSparseMat* mat, CvSparseMatIterator* iterator ) {CvSparseNode* node = 0;CV_FUNCNAME( "cvInitSparseMatIterator" );__BEGIN__;int idx;if( !CV_IS_SPARSE_MA T( mat ))CV_ERROR( CV_StsBadArg, "Invalid sparse matrix header" );if( !iterator )CV_ERROR( CV_StsNullPtr, "NULL iterator pointer" );iterator->mat = (CvSparseMat*)mat;iterator->node = 0;for( idx = 0; idx < mat->hashsize; idx++ )if( mat->hashtable[idx] ){node = iterator->node = (CvSparseNode*)mat->hashtable[idx];break;}iterator->curidx = idx;__END__;return node;}#define ICV_SPARSE_MA T_HASH_MULTIPLIER 33static uchar*icvGetNodePtr( CvSparseMat* mat, const int* idx, int* _type,int create_node, unsigned* precalc_hashval ){uchar* ptr = 0;CV_FUNCNAME( "icvGetNodePtr" );__BEGIN__;int i, tabidx;unsigned hashval = 0;CvSparseNode *node;assert( CV_IS_SPARSE_MA T( mat ));if( !precalc_hashval ){for( i = 0; i < mat->dims; i++ ){int t = idx[i];if( (unsigned)t >= (unsigned)mat->size[i] )CV_ERROR( CV_StsOutOfRange, "One of indices is out of range" );hashval = hashval*ICV_SPARSE_MA T_HASH_MULTIPLIER + t;}}else{hashval = *precalc_hashval;}tabidx = hashval & (mat->hashsize - 1);hashval &= INT_MAX;for( node = (CvSparseNode*)mat->hashtable[tabidx];node != 0; node = node->next ){if( node->hashval == hashval ){int* nodeidx = CV_NODE_IDX(mat,node);for( i = 0; i < mat->dims; i++ )if( idx[i] != nodeidx[i] )break;if( i == mat->dims ){ptr = (uchar*)CV_NODE_V AL(mat,node);break;}}}if( !ptr && create_node ){if( mat->heap->active_count >= mat->hashsize*CV_SPARSE_HASH_RA TIO ) {void** newtable;int newsize = MAX( mat->hashsize*2, CV_SPARSE_HASH_SIZE0);int newrawsize = newsize*sizeof(newtable[0]);CvSparseMatIterator iterator;assert( (newsize & (newsize - 1)) == 0 );// resize hash tableCV_CALL( newtable = (void**)cvAlloc( newrawsize ));memset( newtable, 0, newrawsize );node = cvInitSparseMatIterator( mat, &iterator );while( node ){CvSparseNode* next = cvGetNextSparseNode( &iterator );int newidx = node->hashval & (newsize - 1);node->next = (CvSparseNode*)newtable[newidx];newtable[newidx] = node;node = next;}cvFree( &mat->hashtable );mat->hashtable = newtable;mat->hashsize = newsize;tabidx = hashval & (newsize - 1);}node = (CvSparseNode*)cvSetNew( mat->heap );node->hashval = hashval;node->next = (CvSparseNode*)mat->hashtable[tabidx];mat->hashtable[tabidx] = node;CV_MEMCPY_INT( CV_NODE_IDX(mat,node), idx, mat->dims );ptr = (uchar*)CV_NODE_V AL(mat,node);if( create_node > 0 )CV_ZERO_CHAR( ptr, CV_ELEM_SIZE(mat->type));}if( _type )*_type = CV_MA T_TYPE(mat->type);__END__;return ptr;}static voidicvDeleteNode( CvSparseMat* mat, const int* idx, unsigned* precalc_hashval ){CV_FUNCNAME( "icvDeleteNode" );__BEGIN__;int i, tabidx;unsigned hashval = 0;CvSparseNode *node, *prev = 0;assert( CV_IS_SPARSE_MA T( mat ));if( !precalc_hashval ){for( i = 0; i < mat->dims; i++ ){int t = idx[i];if( (unsigned)t >= (unsigned)mat->size[i] )CV_ERROR( CV_StsOutOfRange, "One of indices is out of range" );hashval = hashval*ICV_SPARSE_MA T_HASH_MULTIPLIER + t;}}else{hashval = *precalc_hashval;}tabidx = hashval & (mat->hashsize - 1);hashval &= INT_MAX;for( node = (CvSparseNode*)mat->hashtable[tabidx];node != 0; prev = node, node = node->next ){if( node->hashval == hashval ){int* nodeidx = CV_NODE_IDX(mat,node);for( i = 0; i < mat->dims; i++ )if( idx[i] != nodeidx[i] )break;if( i == mat->dims )break;}}if( node ){if( prev )prev->next = node->next;elsemat->hashtable[tabidx] = node->next;cvSetRemoveByPtr( mat->heap, node );}__END__;}/****************************************************************************** **********\* Common for multiple array types operations *\****************************************************************************** **********/// Allocates underlying array dataCV_IMPL voidcvCreateData( CvArr* arr ){CV_FUNCNAME( "cvCreateData" );__BEGIN__;if( CV_IS_MA T_HDR( arr )){size_t step, total_size;CvMat* mat = (CvMat*)arr;step = mat->step;if( mat->data.ptr != 0 )CV_ERROR( CV_StsError, "Data is already allocated" );if( step == 0 )step = CV_ELEM_SIZE(mat->type)*mat->cols;total_size = step*mat->rows + sizeof(int) + CV_MALLOC_ALIGN;CV_CALL( mat->refcount = (int*)cvAlloc( (size_t)total_size ));mat->data.ptr = (uchar*)cvAlignPtr( mat->refcount + 1, CV_MALLOC_ALIGN );*mat->refcount = 1;}else if( CV_IS_IMAGE_HDR(arr)){IplImage* img = (IplImage*)arr;if( img->imageData != 0 )CV_ERROR( CV_StsError, "Data is already allocated" );if( !CvIPL.allocateData ){CV_CALL( img->imageData = img->imageDataOrigin =(char*)cvAlloc( (size_t)img->imageSize ));}else{int depth = img->depth;int width = img->width;if( img->depth == IPL_DEPTH_32F || img->nChannels == 64 ){img->width *= img->depth == IPL_DEPTH_32F ? sizeof(float) :sizeof(double);img->depth = IPL_DEPTH_8U;}CvIPL.allocateData( img, 0, 0 );img->width = width;img->depth = depth;}}else if( CV_IS_MA TND_HDR( arr )){CvMatND* mat = (CvMatND*)arr;int i;size_t total_size = CV_ELEM_SIZE(mat->type);if( mat->data.ptr != 0 )CV_ERROR( CV_StsError, "Data is already allocated" );if( CV_IS_MA T_CONT( mat->type )){total_size = (size_t)mat->dim[0].size*(mat->dim[0].step != 0 ?mat->dim[0].step : total_size);}else{for( i = mat->dims - 1; i >= 0; i-- ){size_t size = (size_t)mat->dim[i].step*mat->dim[i].size;if( total_size < size )total_size = size;}}CV_CALL( mat->refcount = (int*)cvAlloc( total_size +sizeof(int) + CV_MALLOC_ALIGN ));mat->data.ptr = (uchar*)cvAlignPtr( mat->refcount + 1, CV_MALLOC_ALIGN );*mat->refcount = 1;}else{CV_ERROR( CV_StsBadArg, "unrecognized or unsupported array type" );}__END__;}// Assigns external data to arrayCV_IMPL voidcvSetData( CvArr* arr, void* data, int step ){CV_FUNCNAME( "cvSetData" );__BEGIN__;int pix_size, min_step;if( CV_IS_MA T_HDR(arr) || CV_IS_MA TND_HDR(arr) )cvReleaseData( arr );if( CV_IS_MA T_HDR( arr )){CvMat* mat = (CvMat*)arr;int type = CV_MA T_TYPE(mat->type);pix_size = CV_ELEM_SIZE(type);min_step = mat->cols*pix_size & ((mat->rows <= 1) - 1);if( step != CV_AUTOSTEP ){if( step < min_step && data != 0 )CV_ERROR_FROM_CODE( CV_BadStep );mat->step = step & ((mat->rows <= 1) - 1);}else{mat->step = min_step;}mat->data.ptr = (uchar*)data;mat->type = CV_MA T_MAGIC_V AL | type |(mat->step==min_step ? CV_MA T_CONT_FLAG : 0);icvCheckHuge( mat );}else if( CV_IS_IMAGE_HDR( arr )){IplImage* img = (IplImage*)arr;pix_size = ((img->depth & 255) >> 3)*img->nChannels;min_step = img->width*pix_size;if( step != CV_AUTOSTEP && img->height > 1 ){if( step < min_step && data != 0 )CV_ERROR_FROM_CODE( CV_BadStep );img->widthStep = step;}else{img->widthStep = min_step;}img->imageSize = img->widthStep * img->height;img->imageData = img->imageDataOrigin = (char*)data;if( (((int)(size_t)data | step) & 7) == 0 &&cvAlign(img->width * pix_size, 8) == step ){img->align = 8;}else{img->align = 4;}}else if( CV_IS_MA TND_HDR( arr )){CvMatND* mat = (CvMatND*)arr;int i;int64 cur_step;if( step != CV_AUTOSTEP )CV_ERROR( CV_BadStep,"For multidimensional array only CV_AUTOSTEP is allowed here" );mat->data.ptr = (uchar*)data;cur_step = CV_ELEM_SIZE(mat->type);for( i = mat->dims - 1; i >= 0; i-- ){if( cur_step > INT_MAX )CV_ERROR( CV_StsOutOfRange, "The array is too big" );mat->dim[i].step = (int)cur_step;cur_step *= mat->dim[i].size;}}else{CV_ERROR( CV_StsBadArg, "unrecognized or unsupported array type" );}__END__;}// Deallocates array's dataCV_IMPL voidcvReleaseData( CvArr* arr ){CV_FUNCNAME( "cvReleaseData" );__BEGIN__;if( CV_IS_MA T_HDR( arr ) || CV_IS_MA TND_HDR( arr )){CvMat* mat = (CvMat*)arr;cvDecRefData( mat );}else if( CV_IS_IMAGE_HDR( arr )){IplImage* img = (IplImage*)arr;if( !CvIPL.deallocate ){char* ptr = img->imageDataOrigin;img->imageData = img->imageDataOrigin = 0;cvFree( &ptr );}else{CvIPL.deallocate( img, IPL_IMAGE_DA TA );}}else{CV_ERROR( CV_StsBadArg, "unrecognized or unsupported array type" );}__END__;}// Retrieves essential information about image ROI or CvMat dataCV_IMPL voidcvGetRawData( const CvArr* arr, uchar** data, int* step, CvSize* roi_size ){CV_FUNCNAME( "cvGetRawData" );__BEGIN__;if( CV_IS_MA T( arr )){CvMat *mat = (CvMat*)arr;if( step )*step = mat->step;if( data )*data = mat->data.ptr;if( roi_size )*roi_size = cvGetMatSize( mat );}else if( CV_IS_IMAGE( arr )){IplImage* img = (IplImage*)arr;if( step )*step = img->widthStep;if( data )CV_CALL( *data = cvPtr2D( img, 0, 0 ));if( roi_size ){if( img->roi ){*roi_size = cvSize( img->roi->width, img->roi->height );}else{*roi_size = cvSize( img->width, img->height );}}}else if( CV_IS_MA TND( arr )){CvMatND* mat = (CvMatND*)arr;if( !CV_IS_MA T_CONT( mat->type ))CV_ERROR( CV_StsBadArg, "Only continuous nD arrays are supported here" );if( data )*data = mat->data.ptr;if( roi_size || step ){int i, size1 = mat->dim[0].size, size2 = 1;if( mat->dims > 2 )for( i = 1; i < mat->dims; i++ )size1 *= mat->dim[i].size;elsesize2 = mat->dim[1].size;if( roi_size ){roi_size->width = size2;roi_size->height = size1;}if( step )*step = size1 == 1 ? 0 : mat->dim[0].step;}}else{CV_ERROR( CV_StsBadArg, "unrecognized or unsupported array type" );}__END__;}。