OpenCv矩阵操作函数源代码

合集下载

opencv计算平移和旋转的矩阵

opencv计算平移和旋转的矩阵

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++实现矩阵的基本操作全文共四篇示例,供读者参考第一篇示例: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;}```矩阵的求逆是一个复杂的操作,需要使用高级的数学知识和算法。

opencv函数

opencv函数

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 旋转矩阵到rodrigues转换

opencv 旋转矩阵到rodrigues转换

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。

OpenCv矩阵操作函数大全

OpenCv矩阵操作函数大全
void cvMulTransposed(const CvArr* src, CvArr* dst, int order, constCvArr* delta=NULL, doublescale=1.0);//(src-delta)乘以它的转置再乘以scale
逆矩阵
double cvInvert(const CvArr* src,CvArr*dst,int method=CV_LU);//求原矩阵的逆矩阵,默认使用高斯消去法
要求三个矩阵都是浮点类型,10×10以下该方法有效,20×20以上的矩阵不能计算出结果,为节约计算量,eps通常设为DBL_EPSILON(10^-15)
如果给定的矩阵是对称正定矩阵,那么考虑使用cvSVD();
协方差
void cvCalcCovarMatrix(const CvArr**vects, int count, CvArr* cov_mat, CvArr* avg, intflags);//给定一组大小和类型相同的向量,向量的个数,计算标记,输出协方差正阵和每个向量的平均值矩阵
数组比较
void cvCmp(const CvArr* src1, constCvArr* src2, CvArr* dst, int cmp_op);//两矩阵比较运算
CV_CMP_EQ -src1(I) 是否相等
CV_CMP_GT -src1(I) 是否大于
CV_CMP_GE -src1(I) 是否大于等于
指数
void cvExp(const CvArr* src, CvArr*dst);//dst(I)=EXP(src(I))
对数
void cvLog(const CvArr* src, CvArr*dst);//

C语言实现矩阵计算

C语言实现矩阵计算

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的欧拉角转旋转矩阵

c++ opencv的欧拉角转旋转矩阵

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的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让我们逐行解释一下这段源代码的实现。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

/* //////////////////////////////////////////////////////////////////////// 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__;}。

相关文档
最新文档