OpenCV 2.4.12.0 文档翻译:数组操作,Operations on Arrays
计算矩阵中每个元素的绝对值。
C++: MatExpr abs ( const Mat& m )
C++: MatExpr abs ( const MatExpr& e )
参数: |
m – 矩阵。 e – 矩阵表达式。 |
abs 是一个元函数,它会被展开为 absdiff() 或 convertScaleAbs() 的形式:
•. C = abs(A-B) ,等价于 absdiff(A, B, C)
•. C = abs(A) ,等价于 absdiff(A, Scalar::all(0), C)
•. C = Mat_<Vec<uchar,n> >(abs(A*alpha + beta)) ,等价于 convertScaleAbs(A, C, alpha, beta)
输出矩阵, 其尺寸和类型都与输入矩阵一致。不过,最后一种情况是例外,在那种情况下, C 的类型是 depth=CV_8U 。
参考
针对两个数组,或者一个数组与一个标量组合的情况,逐个元素地计算其绝对值之差。
C++: void absdiff ( InputArray src1 , InputArray src2 , OutputArray dst )
参数: |
src1 – 第一个输入数组,或是一个标量。 src2 – 第二个输入数组,或是一个标量。 src – 单个输入数组。 value – 标量值。 dst – 输出数组,与输入数组的尺寸和类型相同。 |
absdiff 这个函数,计算的是:
•.对于两个具有相同尺寸和类型的数组,计算的是它们之间的差的绝对值:
•. 如果第二 个数组是使用 Scalar 来构造的,或者,其元素个数与 src1 中的通道个数相同,则,计算出数组与标量之间的差的绝对值:
•. 如果第一 个数组是使用 Scalar 来构造的,或者,其元素个数与 src2 中的通道个数相同,则,计算出标量与数组之间的差的绝对值:
其中 , I ,是对于数组元素的多维索引。对于 多通道的数组,每个通道都会独立处理。
注意
如果数组 的位深为 CV_32S ,则,不会进行饱和 度 计算(Saturation)。 在数值溢出的情况下,妳还可能会得到负数的结果值。
参考
计算两个数组或数组与标量之间逐个元素的和。
C++: void add ( InputArray src1 , InputArray src2 , OutputArray dst , InputArray mask =noArray(), int dtype =-1 )
参数: |
src1 – 第一个输入数组,或是一个标量。 src2 – 第二个输入数组,或是一个标量。 src – 单个输入数组。 value – 标量值。 dst – 输出数组,其尺寸和通道个数,与输入数组一致;位深按照 dtype 或 src1 / src2 定义。 mask – 可选的操作掩码——8位的单通道数组,指定的是输出数组中要发生改变的那些元素。 dtype – 可选的参数,指定输出数组的位深(参考下文的说明)。 |
add 这个函数,计算的是:
•.如果两个输入数组都具有相同的尺寸和通道个数,则计算两个数组的和:
•. 如果 src2 是使用 Scalar 来构造的,或者其元素个数与 src1.channels() 相等,则,计算数组与标量之间的和:
•. 如果 src1 是使用 Scalar 来构造的,或者其元素个数与 src2.channels() 相等,则,计算标量与数组之间的和:
其中 , I ,是对于数组元素的多维索引。对于 多通道的数组,每个通道都会独立处理。
以上列出的第一个函数,可以使用矩阵表达式来替换:
dst = src1 + src2;
dst += src1; // 等价 于 add(dst, src1, dst);
输入数组 和输出数组,可以拥有相同的位深,也可以拥有不同的位深。例如, 妳可以将一个 16 位的无符号数组与一个 8 位有符号数组相加,并将结果储存在一个 32 位的浮点数数组中。输出数组 的位深,由 dtype 参数决定。 在上面的第二和第三种情况中,当然也包括第一种情况中,如果 src1.depth() == src2.depth() ,则, dtype 可被设置为默认值 -1 。 在这种情况下,输出数组的位深与输入数组的位深相同,即, src1 、 src2 或与二者都相同。
注意
如果数组 的位深为 CV_32S ,则,不会进行饱和 度 计算(Saturation)。 在数值溢出的情况下,妳还可能会得到符号错误的结果值。
参考
subtract() 、 addWeighted() 、 scaleAdd() 、 Mat::convertTo() 、 矩阵表达式
计算两个数组之间的加权和。
C++: void addWeighted ( InputArray src1 , double alpha , InputArray src2 , double beta , double gamma , OutputArray dst , int dtype =-1 )
参数: |
src1 – 第一个输入数组。 alpha – 第一个数组中元素的权重。 src2 – 第二个输入数组,其尺寸和通道个数与 src1 一致。 beta – 第二个数组中元素的权重。 dst – 输出数组,其尺寸和通道个数与输入数组一致。 gamma – 要向每个和值上增加的标量值。 dtype – 可选参数,表示输出数组的位深;如果两个输入数组的位深相同,则, dtype 可被设置为 -1 ,这样就等价于 src1.depth() 。 |
addWeighted 这个函数,按照如下公式计算两个数组之间的加权和:
其中 , I ,是对于数组元素的多维索引。对于 多通道的数组,每个通道都会独立处理。
这个函数,可使用矩阵表达式代替:
dst = src1*alpha + src2*beta + gamma;
注意
如果数组 的位深为 CV_32S ,则,不会进行饱和 度 计算(Saturation)。 在数值溢出的情况下,妳还可能会得到符号错误的结果值。
参考
add() 、 subtract() 、 scaleAdd() 、 Mat::convertTo() 、 矩阵表达式
计算二维向量的长度和角度。
C++: void cartToPolar ( InputArray x , InputArray y , OutputArray magnitude , OutputArray angle , bool angleInDegrees =false )
参数: |
x – x坐标组成的数组;它必须是一个单精度浮点数或双精度浮点数数组。 y – y坐标组成的数组;它的尺寸和类型必须与 x 一致。 magnitude – 长度值组成的输出数组,其尺寸和类型与 x 一致。 angle – 角度值组成的输出数组,其尺寸和类型与 x 一致;角度单位是弧度(范围从0到2*Pi)或度(0到360度)。 angleInDegrees – 标记位,表示的是,角度应当以弧度(默认值)还是以度为单位。 angle_in_degrees – 标记位,表示的是,角度应当以弧度还是以度为单位(用于C语法)。 |
cartToPolar 这个函数,会计算每个二维向量(x(I),y(I))的长度、角度:
角度的精度为大约0.3度。对于点(0,0),角度被设置为0。
参考
对数组中非零的元素进行计数。
C++: int countNonZero ( InputArray src )
参数: |
src – 单通道的数组。 |
这个函数,返回的是, src 中非零元素的个数:
参考
mean() 、 meanStdDev() 、 norm() 、 minMaxLoc() 、 calcCovarMatrix()
对一维或二维数组,计算其正向或反向的离散余弦变换。
C++: void dct ( InputArray src , OutputArray dst , int flags =0 )
参数: |
src – 输入的浮点数数组。 dst – 输出数组,其尺寸和类型与 src 一致。 flags – 由以下值组成的变换标记位: DCT_INVERSE 进行一次反向的一维或二维变换。默认是正向变换。 DCT_ROWS 对于输入矩阵中的每一行,进行一次反向或正向变换。利用这个标记位,可以同时对多个向量进行变换,并且,可用来降低在进行三维及更高维变换过 程中的开销(有些时候,这种开销比变换本身的计算量还大数倍)。 |
dct 这个函数,对于一维或二维浮点数数组,进行一次反向或正向的离散余弦变换(DCT):
•. 对于 有 N 个元素的一维向量,其正向余弦变换为:
其中
并且
•. 对于有 N 个元素的一维向量,其反向余弦变换为:
(由于C (N) 是一个正交矩阵,所以C (N) ˙ (C (N) ) T =I)
•. 对于一个 M x N 的矩阵,正向的二维余弦变换为:
•. 对于 一个 M x N 的矩阵,反向的二维余弦变换为:
这个函数,会根据标志位和输入数组的尺寸来选择对应的操作模式:
•. 如果 (flags & DCT_INVERSE) == 0 ,则,这个函数进行一次正向的一维或二维变换。否则, 就进行反向的一维或二维变换。
•. 如果 (flags & DCT_ROWS) != 0 ,则,这个函数针对每一行进行一次一维变换。
•.如果该数组是单个列或单个行,则,这个函数进行一维变换。
•.如果以上条件都不成立,则,这个函数进行二维变换。
注意
目前 , dct支持偶数尺寸 的数组 (2, 4, 6 ...) 。出于数 据 分析 和逼近的目的,妳可以在必要的情况下向数组中填充空白元素。
并且 , 此函数的性能,与数组的尺寸有狠大关系,并且并非是单调相关的 (参考 getOptimalDFTSize() ) 。 在目前的实现中,对于一个尺寸为 N 的向量的离散余弦变换,是通过对于 一个尺寸为 N/2 的向量的离散傅立叶变换(DFT)来计算的。因此 ,最佳的离散余弦变换尺寸, N1 >= N ,可这样计算:
size_t getOptimalDCTSize(size_t N) { return 2 *getOptimalDFTSize((N+ 1)/ 2); }
N1 = getOptimalDCTSize(N);
参考
对于一维或二维的浮点数数组,进行一次正向或反向的离散傅立叶变换。
C++: void dft ( InputArray src , OutputArray dst , int flags =0, int nonzeroRows =0 )
参数: |
src – 输入数组,可以是实数数组,也可以是复数数组。 dst – 输出数组,其尺寸和类型取决于 flags 。 flags – 变换标志位,代表着以下值的组合: DFT_INVERSE 进行一次反向的一维或二维变换,而不是默认的正向变换。 DFT_SCALE 对结果进行缩放:将它除以数组元素的个数。一般情况下,这个标志位是与 DFT_INVERSE 配套使用的。 DFT_ROWS 针对输入矩阵中的每一行,进行一次正向或反向变换;利用这个标记位,可以同时对多个向量进行变换,并且,可用来降低在进行三维及更高维变换过程中的开销(有些时候,这种开销比变换本身的计算量还大数倍)。 DFT_COMPLEX_OUTPUT 对一维或二维实数数组进行一次正向变换;尽管其结果是一个复数数组,但是,它具有复共轭对称性(complex-conjugate symmetry (CCS, 参考下文的函数说明以了解细节)),因而,这样的一个数组,可以紧缩存储到一个与输入数组尺寸相同的实数数组中去,这是最快的选项,同时也是此函数的默认行为;然而,妳可能确实想要得到一个完整的复数数组(这样可以更简单地进行光谱分析等等操作)——那么,传入这个标志位,就可以让此函数产生一个完整尺寸的复数输出数组。 DFT_REAL_OUTPUT 对一维或二维复数数组进行一次反向变换;其结果,一般是一个具有相同尺寸的复数数组,然而,如果输入数组本身具有复共轭对称性(例如,它是带 DFT_COMPLEX_OUTPUT 标志位的正向变换的结果),那么,其输出是一个实数数组;然,此函数本身并不检查输入数组是否是对称的,为此,妳可以传入这个标志位,使得函数假设输入数组具有对称性,于是产生一个实数的输出数组(注意,如果输入数组被紧缩存储为一个实数数组,并且对它执行反向变换,则,此函数会将输入数组当成是一个被紧缩存储的复共轭对称数组,因而其输入内容也是一个实数数组)。 nonzeroRows – 如果这个参数被设置为非零的值,则,此函数会假设只有(在未设置 DFT_INVERSE 的情况下)输入数组中的前 nonzeroRows 行或(在已设置 DFT_INVERSE 的情况下)输出数组中的前 nonzeroRows 行才包含非零值,于是,此函数就能够更有效率地处理剩下的那些行,以节省一些时间;这个技巧,在使用离散傅立叶变换(DFT)计算数组的互相关度(cross-correlation)或卷积时非常有用。 |
此函数,会进行下列的某一项动作:
•. 对于具有 N 个元素的一维向量,进行正向的傅立叶变换:
其中,
且,
•. 对于具有 N 个元素的一维向量,进行反向的傅立叶变换:
其中
•. 对于 一个 M x N 的矩阵,进行正向的二维傅立叶变换:
•. 对于 一个 M x N 的矩阵,进行反向的二维傅立叶变换:
对于实数( 单通道 )数据 ,正向傅立叶变换 的输出光谱或反向傅立叶变换的输入光谱,可以 以一种名为复共轭对称( CCS (complex-conjugate-symmetrical))的紧缩格式来表示 。 这种格式,是从英特尔图像处理 库( IPL (Intel* Image Processing Library) )借用来的。下面 是二维复共轭对称光谱 的表示:
对于实数向量的一维变换,输出内容类似上面所示矩阵的第一行。
所以,此函数会依据那些标志位及输入数组的尺寸来选择一个操作模式:
•. 如果设置 了 DFT_ROWS 标志位,或者输入数组只有 一行或一列,则, 此函数会对矩阵中的每一行进行一次一维的正向或反向变换。否则, 它会进行二维变换。
•. 如果输入数组 是实数数组,并且未设置 DFT_INVERSE 标志位, 此函数会进行正向的一维或二维变换:
•. 如果设置 了 DFT_COMPLEX_OUTPUT 标志位,则,输出内容 是一个复数矩阵,其尺寸与输入数组相同。
•. 如果 未设置 DFT_COMPLEX_OUTPUT 标志位,则,输出内容 是一个实数矩阵,其尺寸与输入数组相同。对于二维变换 ,它会使用上文所说的紧缩格式。对于单独 的一维变换, 其结果类似于上文所展示矩阵中的第一行。对于多 组一维变换 (使用 了 DFT_ROWS 标志 位 ) ,输出矩阵中的每一行都类似于上文所展示矩阵的第一行。
•. 如果输入数组 是复数数组,并且, DFT_INVERSE 和 DFT_REAL_OUTPUT 标志位都未设置,则,输出内容 是一个复数数组,其尺寸与输入数组相同。取决 于 DFT_INVERSE 和 DFT_ROWS 标志位的情况,此函数会针对整个输入数组或输入数组中的每一行,进行一次正向或反向的一维或二维变换。
•. 如果设置 了 DFT_INVERSE 标志位并且输入数组是实数数组,或者,输入数组 是复数数组但是设置了 DFT_REAL_OUTPUT 标志位, 则,输出内容 是一个实数数组,其尺寸与输入数组相同。取决 于 DFT_INVERSE 和 DFT_ROWS 标志位的情况,此函数会针对整个输入数组或每个单独的输入行,进行一次一维或二维的反向变换。
如果设置 了 DFT_SCALE 标志位,则,会在变换完毕之后进行缩放计算。
与 dct() 不同的是,此函数支持任意尺寸的数组。但是,只有满足 以下条件的数组才能被高效地处理: 其尺寸,可以通过因数分解表示为小素数的 乘 积 (目前 的实现中,支持 2 、 3 和 5) 。 这样的高效离散傅立叶变换尺寸,可以使用 getOptimalDFTSize() 方法来计算。
下面的示例,展示的是,如何针对两个二维实数数组计算出其基于离散傅立叶变换的卷积:
void convolveDFT(InputArray A, InputArray B, OutputArray C)
{
// 必要 的情况下,重新分配输出数组 的空间
C.create(abs(A.rows - B.rows) + 1 , abs(A.cols - B.cols) + 1 , A.type());
Size dftSize;
// 计算离散傅立叶变换 的尺寸
dftSize.width = getOptimalDFTSize(A.cols + B.cols - 1 );
dftSize.height = getOptimalDFTSize(A.rows + B.rows - 1 );
// 分配临时 的缓冲区,并且初始化为 0
Mat tempA(dftSize, A.type(), Scalar :: all( 0 ));
Mat tempB(dftSize, B.type(), Scalar :: all( 0 ));
// 将 A 和 B分别复制 到tempA 和tempB 的左上角
Mat roiA(tempA, Rect( 0 , 0 ,A.cols,A.rows));
A.copyTo(roiA);
Mat roiB(tempB, Rect( 0 , 0 ,B.cols,B.rows));
B.copyTo(roiB);
// 现在 ,对于填充过的A 和B 进行就地变换;
// 利用"nonzeroRows"参数 来加快处理速度
dft(tempA, tempA, 0 , A.rows);
dft(tempB, tempB, 0 , B.rows);
// 对光谱进行乘法计算;
// 这个函数能够狠好地处理紧缩存储的光谱格式
mulSpectrums(tempA, tempB, tempA);
// 将乘积从频率域转换回来。
// 虽然结果 中的所有行都是非零值,
// 但是 ,妳只需要其中的前 C.rows 行,所以 ,
// 传入nonzeroRows == C.rows
dft(tempA, tempA, DFT_INVERSE + DFT_SCALE, C.rows);
// 现在 ,将结果复制回到C 中。
tempA(Rect( 0 , 0 , C.cols, C.rows)).copyTo(C);
// 所有 的临时缓冲区,都会被自动释放。
}
为了对该示例进行优化,考虑以下手段:
•. 由于 向正向变换函数中 传入 了 nonzeroRows != 0 参数 ,并且, A 和 B 都被分别复制到了 tempA 和 tempB 的左上角,所以 ,不需要对 tempA 和 tempB 做整个清零操作。 只需要将各个矩阵中 最右边的( tempA.cols - A.cols ( tempB.cols - B.cols ))列清零即可。
•. 基于离散傅立叶变换 的卷积,并不需要被应用到整个大数组中去,尤其 是,当其中一个数组明显比另一个数组小的时候更是如此。 更高效的处理方式是, 按不同的部分来计算卷积。具体 地, 妳需要将输出数组 C 分割成多个部分。对于每个部分,大致估计 一下需要 A 和 B 中的哪些部分来计算这个输出部分的卷积。如果 C 中的分块太小, 会导致速度降低,因为,会做些重复工作。 在最极端的情况,也就是 C 中的每个分块都是一个像素的情况下, 这个算法会与最笨的卷积方法等价。如果分 块太大,则,临时数组 tempA 和 tempB 都会变得特别大, 这同样会导致速度下降 ,因为 这会降低缓存命中率。 所以,最佳的分块尺寸,是位于中间某个值。
•. 如果 C 中的分块可以并行计算,并且,卷积 也按照不同部分来计算的话,则,这个循环可以拆分 成多线程的。
以上的改进,都已经在 matchTemplate() 和 filter2D() 中实现。因此 ,利用 那两个方法, 妳可以获得比上述理论最佳实现更好的性能。 不过,那两个函数实际上计算的是互相关度,而不是卷积,所以 ,妳需要使用 flip() 来将第二个卷积操作数 B 进行竖向和横向的“翻转”。
参考
dct() 、 getOptimalDFTSize() 、 mulSpectrums() 、 filter2D() 、 matchTemplate() 、 flip() 、 cartToPolar() 、 magnitude() 、 phase()
注意
•.此处有一个使用离散傅立叶变换的示例:opencv_source_code/samples/cpp/dft.cpp
将一个二维数组,围绕着其纵轴、横轴或两个轴翻转。
C++: void flip ( InputArray src , OutputArray dst , int flipCode )
参数: |
src – 输入数组。 dst – 输出数组,其尺寸和类型与 src 一致。 flipCode – 标志位,指定该如何对数组进行翻转;0表示围绕着x轴翻转,正数(例如,1)表示围绕着y轴翻转。负数(例如,-1)表示围绕着两个轴翻转(参考下文的说明以了解对应的公式)。 |
flip 这个函数,将数组以三种不同的方式进行翻转 ( 行和列索引是以 0开始 的 ) :
此函数,可在以下场景中使用:
•. 竖向 地翻转图片 ( flipCode == 0 ) ,用途是, 在左上角为原点和左下角为原点的两种模式间切换。
•. 横向 地翻转图片,接着 ,进行横向 的偏移和绝对差计算, 以检查该图片是否具有纵轴对称性 ( flipCode > 0 ) 。
•. 同时进行横向和竖向的翻转,接着,进行偏移和绝对差计算, 以检查该图片是否具有中心对称性 ( flipCode < 0 ) 。
•. 将点数组的顺序反转 ( flipCode > 0 或 flipCode == 0 ) 。
参考
返回给定的向量尺寸所对应的最佳离散傅立叶变换尺寸。
C++: int getOptimalDFTSize ( int vecsize )
参数: |
vecsize – 向量尺寸。 |
离散傅立叶变换,其性能并非是向量尺寸的单调函数。因此,当妳对两个数组进行卷积计算,以便进行光谱分析的时候,通常,使用零值对输入数据进行填充,以得到一个较大的能够比原始数组进行更快变换的数组。尺寸为2的幂(2, 4, 8, 16, 32, ...)的那些数组处理起来最快。不过呢,尺寸为2、3和5的乘积(例如,300 = 5*5*3*2*2)的那些数组,处理起来也是相当快的。
getOptimalDFTSize 这个函数,返回 的是满足以下条件的最小整数 N :大于等于 vecsize ;并且,对于尺寸 为 N 的向量,其离散傅立叶变换可以高效地处理。目前 的实现中, N = 2 p * 3 q * 5 r ,其中, p 、 q 、 r 是整数。
如果 vecsize 太大(接近 INT_MAX ),此函数会返回一个负数。
此函数不能直接用来估计离散余弦变换的最佳向量尺寸 (因为当前 的离散余弦变换实现中仅支持偶数尺寸的向量 ) ,但是 , 可以狠容易的变通一下, getOptimalDFTSize((vecsize+1)/2)*2 。
参考
dft() 、 dct() 、 idft() 、 idct() 、 mulSpectrums()
针对一维或二维的数组,进行一次反向的离散余弦变换。
C++: void idct ( InputArray src , OutputArray dst , int flags =0 )
参数: |
src – 输入的浮点数单通道数组。 dst – 输出数组,其尺寸和类型与 src 一致。 flags – 操作标志位。 |
idct(src, dst, flags) 等价 于 dct(src, dst, flags | DCT_INVERSE) 。
参考
dct() 、 dft() 、 idft() 、 getOptimalDFTSize()
针对一维或二维的数组,进行一次反向的离散傅立叶变换。
C++: void idft ( InputArray src , OutputArray dst , int flags =0, int nonzeroRows =0 )
参数: |
src – 输入的浮点实数或复数数组。 dst – 输出数组,其尺寸和类型取决于 flags 。 flags – 操作标志位(参考 dft() )。 nonzeroRows – dst 中要处理的行数;其余行中将具有未定义的内容(参考 dft() 说明中的卷积示例)。 |
idft(src, dst, flags) 等价 于 dft(src, dst, flags | DFT_INVERSE) 。
参考 dft() 以了解细节。
注意
dft 和 idft 默认情况下都不会对结果进行缩放。所以 ,妳需要显式地向 dft 和 idft 中的某一个传入 DFT_SCALE ,以使得两个变换可以互相反转。
参考
dft() 、 dct() 、 idct() 、 mulSpectrums() 、 getOptimalDFTSize()
对一个数组进行一次查找表变换。
C++: void LUT ( InputArray src , InputArray lut , OutputArray dst , int interpolation =0 )
参数: |
src – 输入数组,其元素为8位。 lut – 查找表,拥有256个元素;对于多通道的输入数组,查找表应当拥有单个通道(在这种情况下,同一个表被用于所有通道)或与输入数组相同的通道个数。 dst – 输出数组,其尺寸和通道个数与 src 一致,位深与 lut 一致。 |
LUT 这个函数,使用查找 表中的值来填充输出数组。各个条目 的索引,来自于输入数组。 即,这个函数对于 src 中的每个元素进行以下处理:
其中
参考
从多个单通道的数组中,创建出一个多通道的数组。
C++: void merge ( const Mat* mv , size_t count , OutputArray dst )
C++: void merge ( InputArrayOfArrays mv , OutputArray dst )
参数: |
mv – 要合并的输入数组,或矩阵组成的向量; mv 中的所有矩阵都必须具有相同的尺寸和位深。 count – 当 mv 是一个普通C 数组时,由这个参数来指定输入矩阵的个数;它必须大于0。 dst – 输出数组,其尺寸和位深与 mv[0] 一致;通道个数,与输入的矩阵数组中所有通道个数的和相等。 |
merge 这个函数,将多个数组合并到一起,以产生一个多通道的数组。 也就是,输出数组 中,每个元素, 都是输入数组中对应元素连接起来的结果,其中 ,第i 个输入数组中的那些元素,被当作一个具有 mv[i].channels() 个元素的向量。
split() 函数 做的是相反的操作。如果 妳需要将通道以其它更高级的方式进行混合,则应当使用 mixChannels() 。
参考
寻找数组中的全局最小值和全局最大值。
C++: void minMaxIdx ( InputArray src , double* minVal , double* maxVal , int* minIdx =0, int* maxIdx =0, InputArray mask =noArray() )
参数: |
src – 输入的單通道数组。 minVal – 指向所返回的最小值的指针;不需要这个值则传入 NULL 。 maxVal – 指向所返回的最大值的指针;不需要这个值则传入 NULL 。 minIdx – 指向所返回的最小值位置(以n维的形式来表示)的指针;不需要这个值则传入 NULL ;否则的话,它必须指向一个拥有 src.dims 个元素的数组,最小值在各个维度中的坐标,会依次存储到这个数组中。 注意 如果 minIdx 不为 NULL ,则,它必须最少包含 2 个元素 (对于 maxIdx也是如此 ) ,即使 src 是一个单行或单列的矩阵也是如此。 在 OpenCV 中 ,每个数组最少拥有 2 个维度, 也就是说, 单列的矩阵实际是一个 Mx1 矩阵(因而 , minIdx / maxIdx 分别 是 (i1,0) / (i2,0) ) , 而单行的矩阵实际是一个 1xN 矩阵(因而 , minIdx / maxIdx 分别 是 (0,j1) / (0,j2) ) 。 maxIdx – 指向所返回的最大值位置(以n维的形式来表示)的指针。不需要这个值则传入 NULL 。 |
minMaxIdx 这个函数,寻找最小元素和最大元素的值和它们的位置。 对极值的寻找,是在整个数组中进行的,或者,如果 mask 不为空,则会在数组中指定的区域寻找。
这个函数,不适用于多通道的数组。如果 妳想要寻找所有通道 的最小值和最大值,则,应当 先使用 Mat::reshape() 来将该数组解释成 单通道数组。或者 ,妳可以使用 extractImageCOI() 、 mixChannels() 或 split() 来提取指定的通道。
对于稀松矩阵,只会在非零元素中寻找最小值。
寻找数组中的全局最小值和全局最大值。
C++: void minMaxLoc ( InputArray src , double* minVal , double* maxVal =0, Point* minLoc =0, Point* maxLoc =0, InputArray mask =noArray() )
C++: void minMaxLoc ( const SparseMat& a , double* minVal , double* maxVal , int* minIdx =0, int* maxIdx =0 )
参数: |
src – 输入的单通道数组。 minVal – 指向所返回的最小值的指针;不需要这个值则传入 NULL 。 maxVal – 指向所返回的最大值的指针;不需要这个值则传入 NULL 。 minLoc – 指向所返回的最小值位置(以二维的形式来表示)的指针;不需要这个值则传入 NULL 。 maxLoc – 指向所返回的最大值位置(以二维的形式来表示)的指针;不需要这个值则传入 NULL 。 mask – 可选的掩码数组,用来选中一个子数组。 |
minMaxLoc 这个函数,寻找数组元素中 的 最小值和最大值,以及它们的位置。 对极值的寻找,是在整个数组中进行的,或者,如果 mask 不为空,则会在数组中指定的区域寻找。
这个函数,不适用于多通道的数组。如果 妳想要寻找所有通道 的最小值和最大值,则,应当 先使用 Mat::reshape() 来将该数组解释成 单通道数组。或者 ,妳可以使用 extractImageCOI() 、 mixChannels() 或 split() 来提取指定的通道。
参考
max() 、 min() 、 compare() 、 inRange() 、 extractImageCOI() 、 mixChannels() 、 split() 、 Mat::reshape()
将输入数组中的指定通道复制到输出数组中的指定通道。
C++: void mixChannels ( const Mat* src , size_t nsrcs , Mat* dst , size_t ndsts , const int* fromTo , size_t npairs )
C++: void mixChannels ( const vector<Mat>& src , vector<Mat>& dst , const int* fromTo , size_t npairs )
参数: |
src – 输入数组,或由矩阵组成的向量;所有矩阵必须具有相同的尺寸和位深。 nsrcs – src 中矩阵的个数。 dst – 输出数组,或由矩阵组成的向量;所有的矩阵 必须已经 被分配空间 ;它们的尺寸和位深必须与 src[0] 一致。 ndsts – dst 中矩阵的个数。 fromTo – 由索引对组成的数组,指定的是,输入数组中的哪些通道要复制到输出数组的哪些通道中去; fromTo[k*2] 是以0开始的一个索引,对应于 src 中的输入通道, fromTo[k*2+1] 是对应于 dst 中的输出通道的索引;此处会使用连续的通道编号:第一个输入图片的通道,其索引范围是 0 到 src[0].channels()-1 ,第二个输入图片的通道,其索引范围是 src[0].channels() 到 src[0].channels() + src[1].channels()-1 ,如此类推,对于输出图片的通道也采用同样的模式;此处还包含一个特殊情况,如果 fromTo[k*2] 是负数,则,对应的输出通道中,会以零填充。 npairs – fromTo 中索引对的个数。 |
mixChannels 函数 ,提供了一种用来对图片通道进行混合的高级方法。
split() 、 merge() 以及某些形式的 cvtColor() ,它们都是对应于 mixChannels 的部分工作模式。
在下面的示例中,将一个4通道的RGBA图片分割成一个3通道的BGR(其中R和B通道互换了位置)和一个单独的透明通道图片:
Mat rgba( 100, 100, CV_8UC4, Scalar(1,2,3,4) );
Mat bgr( rgba.rows, rgba.cols, CV_8UC3 );
Mat alpha( rgba.rows, rgba.cols, CV_8UC1 );
// 组合一个矩阵数组,是一项高效的操作,
// 因为,矩阵数据并未被复制,只是复制了数据头
Mat out[] = { bgr, alpha };
// rgba[0] -> bgr[2], rgba[1] -> bgr[1],
// rgba[2] -> bgr[0], rgba[3] -> alpha[0]
int from_to[] = { 0,2, 1,1, 2,0, 3,3 };
mixChannels( &rgba, 1, out, 2, from_to, 4 );
注意
与OpenCV 中许多新风格的 C++函数 (参考介绍小节 和 Mat::create() )不同的是, mixChannels 要求 ,在调用此函数之前,输出数组必须已经被分配了空间。
参考
split() 、 merge() 、 cvtColor()
计算绝对数组范数、绝对差范数或相对差范数。
C++: double norm ( InputArray src1 , int normType =NORM_L2, InputArray mask =noArray() )
C++: double norm ( InputArray src1 , InputArray src2 , int normType =NORM_L2, InputArray mask =noArray() )
C++: double norm ( const SparseMat& src , int normType )
参数: |
src1 – 第一个输入数组。 src2 – 第二个输入数组,其尺寸和类型与 src1 一致。 normType – 范数类型(参考下文详情)。 mask – 可选的操作掩码;它必须具有与 src1 相同的尺寸,必须具有 CV_8UC1 类型。 |
norm 函数 ,(在没有 src2 的情况下)计算 src1 的绝对范数:
或者 ,提供了 src2 的情况下,计算绝对或相对差范数:
或者
norm 函数 ,返回的即是计算出来的范数。
如果指定 了 mask 参数,并且不为空,则, 只会对掩码所指定的区域计算范数。
多通道的输入数组会被当作单通道数组处理,也就是说,所计算出来的结果,是将所有通道合并之后的结果。
将数组的范数或取值范围归一化。
C++: void normalize ( InputArray src , OutputArray dst , double alpha =1, double beta =0, int norm_type =NORM_L2, int dtype =-1, InputArray mask =noArray() )
C++: void normalize ( const SparseMat& src , SparseMat& dst , double alpha , int normType )
参数: |
src – 输入数组。 dst – 输出数组,与 src 的尺寸相同。 alpha – 要归一化的范数值;或者,对于数值范围的归一化,则表示取值范围的下界。 beta – 对于数值范围的归一化,表示取值范围的上界;对于范数的归一化,此参数无用。 normType – 归一化类型(参考下文的详细说明)。 dtype – 如果为负数,则输出数组的类型与 src 一致;否则,它的通道个数与 src 一致,位深为depth =CV_MAT_DEPTH(dtype) 。 mask – 可选的操作掩码。 |
normalize 函数 ,对输入数组中的元素进行缩放及平移,使得 ,当 normType=NORM_INF 、 NORM_L1 或 NORM_L2 时
(对应 地, 其中 , p=Inf 、 1 或 2) ;或者,当 normType=NORM_MINMAX ( 只适用于密集型数组 )时,
可选 的掩码,用于指定要对其进行归一化的子数组。 这就意味着,范数或最小最大值是针对该子数组而计算的,因而只有该子数组会被修改以实现归一化。如果 只希望只是使用掩码来计算范数或最小最大值,而对整个数组进行修改,那么,可以使用 norm() 和 Mat::convertTo() 。
对于稀疏矩阵,只有非零值会被分析及变换。出于这个原因,对于稀疏矩阵,是不允许进行范围变换的,因为,它可能会引起零值的偏移。
参考
主成分分析类。
这个类,用来计算一组向量的某个特殊成分。 该成分由协方差矩阵的特征向量组成,该协方差矩阵又是通过输入的向量集合计算出来的。 PCA 类,还可以用来将向量变换到该成分所定义的新坐标空间中去,或者转换回来。通常情况 下,在这个新的坐标系统中,来自 于原始集合的每个向量 ( 以及这些向量的任意线性组合 ) ,都可以用它的前几个成分来准确的近似表示,这些成分对应于协方差矩阵中最大的特征值组成的特征向量。 从几何方面来看,这意味着,妳计算出了该向量向某个子空间中的投影, 该子空间,是由基于个与协方差矩阵的支配性特征值对应的特征向量形成的。最终 ,这个投影非常接近于原始向量。 这样,对于来自 于某个高维空间中的原始向量,妳可以使用一个短得多的向量来表示,这个短向量,包含了被投影的向量在子空间中的坐标。 这样的变换,也被称作 K-L转换(Karhunen-Loeve Transform),或KLT。参考 http://en.wikipedia.org/wiki/Principal_component_analysis 。
下面的示例中,这个函数,需要两个矩阵作为参数。第一个函数,储存了一组向量(每行是一个向量),被用于计算主成分分析。第二个函数,储存了另一组用于“测试”的向量(每行是一个向量)。这些向量,首先会被通过主成分分析进行压缩,然后,重构回来,然后,会针对每个向量计算出重构错误值的范数,并且输出。
PCA compressPCA(InputArray pcaset, int maxComponents,
const Mat & testset, OutputArray compressed)
{
PCA pca(pcaset, // 传递数据
Mat(), // 未提供预计算的均值向量,
// 因此 , 由主成分分析引擎来进行计算
CV_PCA_DATA_AS_ROW, // 表明 ,那些向量是存储在矩阵的行中
// (如果向量 是储存在矩阵的列中,则使用
// CV_PCA_DATA_AS_COL )
maxComponents // 指定 要保留多少个主成分
);
// 如果 未提供测试数据,则,直接返回计算出来的成分, 可立即使用
if ( ! testset.data )
return pca;
CV_Assert( testset.cols == pcaset.cols );
compressed.create(testset.rows, maxComponents, testset.type());
Mat reconstructed;
for ( int i = 0 ; i < testset.rows; i ++ )
{
Mat vec = testset.row(i), coeffs = compressed.row(i);
// 压缩 该向量,其结果会被储存在
// 输出矩阵 的第 i 行中
pca.project(vec, coeffs);
// 然后重构 它
pca.backProject(coeffs, reconstructed);
// 然后计算 出偏差
printf( "%d. diff = %g \n " , i, norm(vec, reconstructed, NORM_L2));
}
return pca;
}
参考
calcCovarMatrix() 、 mulTransposed() 、 SVD 、 dft() 、 dct()
注意
•.此处有个示例,使用PCA来进行降维,同时保留一定数量的差异: opencv_source_code/samples/cpp/pca.cpp
PCA构造函数
C++: PCA:: PCA ( InputArray data , InputArray mean , int flags , int maxComponents =0 )
C++: PCA:: PCA ( InputArray data , InputArray mean , int flags , double retainedVariance )
参数: |
data – 输入的样本数据,以矩阵行或矩阵列的形式储存。 mean – 可选的均值;如果此矩阵为空( noArray() ),则,会从数据中计算均值。 flags – 操作标志位;目前,这个参数只是用来指明数据的布局: CV_PCA_DATA_AS_ROW 表明,输入样本的存储方式是矩阵行。 CV_PCA_DATA_AS_COL 表明,输入样本的存储方式是矩阵列。 maxComponents – 应当保留的最大的成分个数;默认情况下,所有的成分都被保留。 retainedVariance – 主成分分析过程中应当保留的差异的百分比。使用这个参数,会使得PCA自主决定要保留多少个分量,但是,它最少会保留2个。 |
默认构造函数 ,会初始化一个空白的 PCA结构 。其它构造函数 ,会初始化该数据结构,并且调用 PCA::operator() 。
对于所提供的数据集,进行主成分分析。
C++: PCA& PCA:: operator() ( InputArray data , InputArray mean , int flags , int maxComponents =0 )
C++: PCA& PCA:: computeVar ( InputArray data , InputArray mean , int flags , double retainedVariance )
参数: |
data – 输入的样本数据,以矩阵行或矩阵列的形式储存。 mean – 可选的均值;如果此矩阵为空( noArray() ),则,会从数据中计算均值。 flags – 操作标志位;目前,这个参数只是用来指明数据的布局: CV_PCA_DATA_AS_ROW 表明,输入样本的存储方式是矩阵行。 CV_PCA_DATA_AS_COL 表明,输入样本的存储方式是矩阵列。 maxComponents – 应当保留的最大的成分个数;默认情况下,所有的成分都被保留。 retainedVariance – 主成分分析过程中应当保留的差异的百分比。使用这个参数,会使得PCA自主决定要保留多少个分量,但是,它最少会保留2个 。 |
此操作符,对指定的数据集进行主成分分析。 可以安全地重复将同一个PCA 结构用于多个数据集。 也就是说,如果该结构之前被用于计算另一个数据集,则,已有 的内部数据会被清空,并且,会重新分配新的特征值、特征向量和均值,并且重新计算。
所计算出来的特征值,会被排序,从最大的到最小的。对应的特征向量,被存储为多个 PCA::eigenvectors 行。
将向量投影到主成分所在的子空间。
C++: Mat PCA:: project ( InputArray vec ) const
C++: void PCA:: project ( InputArray vec , OutputArray result ) const
参数: |
vec – 输入向量;必须与主成分分析阶段所使用的输入数据具有相同的维度和布局,也就是说,如果指定了 CV_PCA_DATA_AS_ROW ,那么, vec.cols==data.cols (向量维度),并且, vec.rows 即是要投影的向量的个数,对于 CV_PCA_DATA_AS_COL 的情况也是类似的。 result – 输出向量;对于 CV_PCA_DATA_AS_COL 的情况,在输出矩阵中,其列数与输入向量的个数相同,这意味着, result.cols==vec.cols ,并且,行数与主成分的个数(例如,通过构造函数传递的 maxComponents 参数)相等。 |
这些函数,会将一个或多个向量投影到主成分子空间中去,其中,每个向量的投影,都是由主成分空间中的因数来表示的。第一种形式,会返回一个矩阵,第二种形式,会将同样的矩阵写入到结果(result)参数中。因此,第一种形式,可以用作某个表达式的一部分,而第二种形式用在某个处理循环中会更高效。
利用主成分空间中的投影,重构向量。
C++: Mat PCA:: backProject ( InputArray vec ) const
C++: void PCA:: backProject ( InputArray vec , OutputArray result ) const
参数: |
vec – 向量在主成分子空间中的坐标,其布局和尺寸,与 PCA::project 的输出向量一致。 result – 重构之后的向量;其布局和尺寸,与 PCA::project 的输入向量一致。 |
这些函数,是 PCA::project() 的反向操作。它们接受投影 后的向量的主成分坐标作为输入,并且据此重构那些原始向量。除非所有 的主成分都被保留了,否则,重构之后的向量会与原始向量不同。但是, 一般情况下,如果成分的个数足够多(但仍然远远小于原始向量的维数),则差异会狠小。 主成分分析的数据会作为结果使用。
对于向量进行一次透视矩阵变换。
C++: void perspectiveTransform ( InputArray src , OutputArray dst , InputArray m )
参数: |
src – 输入两个通道或三个通道的浮点数数组;每个元素代表一个要被变换的二维/三维向量。 dst – 输出数组,其尺寸和类型与 src 一致。 m – 3x3 或 4x4 的浮点数变换矩阵。 |
perspectiveTransform 函数 ,会将 src 当作一个二维或者三维向量处理 ,对其中的每个元素进行变换, 如下所示:
其中
并且
此处展示 的是一个三维向量变换。对于二维的向量变换, z 分量会被省略。
注意
这个函数,会对由二维或三维向量组成的稀疏集合进行变换。如果 妳想对一张图片进行透视变换,则应当使用 warpPerspective() 。如果 妳具有一个相反的需求,即, 妳想要根据若干组变换前和变换后的点对计算出最可能的视图变换,则,妳可以使用 getPerspectiveTransform() 或 findHomography() 。
参考
transform() 、 warpPerspective() 、 getPerspectiveTransform() 、 findHomography()
计算二维向量的旋转角。
C++: void phase ( InputArray x , InputArray y , OutputArray angle , bool angleInDegrees =false )
参数: |
x – 输入数据,由二维向量的x坐标组成的浮点数数组。 y – 输入数据,由二维向量的y坐标组成的数组;它必须具有与 x 相同的尺寸和类型。 angle – 输出数据,由向量角度组成的数组;它具有与 x 相同的尺寸和类型。 angleInDegrees – 如果为真(true),则此函数以度为单位来计算角度,否则,单位为弧度。 |
phase 这个函数,计算由 x 和 y 中对应的元素所组成的每个二维向量的旋转角度:
角度的估算精确度是大约 0.3 度。 如果 x(I)=y(I)=0 ,则,对应的角度值 angle(I) 会被设置为 0 。
从二维向量的长度和角度计算出它们的x和y坐标。
C++: void polarToCart ( InputArray magnitude , InputArray angle , OutputArray x , OutputArray y , bool angleInDegrees =false )
参数: |
magnitude – 输入数据,二维向量的浮点数长度值数组;它可以是空白的矩阵( =Mat() ),这种情况下,该函数假设所有的长度值都为=1;如果不为空,则,它必须具有与 angle 一致的尺寸和类型。 angle – 输入数据,由二维向量的角度值组成的浮点数数组。 x – 输出数据,由二维向量的x坐标组成的数组;它具有与 angle 相同的尺寸和类型。 y – 输出数据,由二维向量的y 坐标组成的数组;它具有与 angle 相同的尺寸和类型。 angleInDegrees – 如果为真(true),则表示,输入数据中的角度值以度为单位,否则,是以弧度为单位。 |
polarToCart 这个函数,计算 magnitude 和 angle 中每个对应元素所表示的二维向量的笛卡尔坐标:
估算出来 的坐标值的相对精度为大约 1e-6 。
参考
cartToPolar() 、 magnitude() 、 phase() 、 exp() 、 log() 、 pow() 、 sqrt()
随机 数生成器。 它将状态 (目前 是一个 64 位的整数 )封装起来 , 并且提供 了各种方法,用于返回标量的随机数值,以及用于以随机数值填充数组。目前 ,它支持均 匀 (uniform)分布和高斯( 正态 )分布。 这个生成器,使用了G. Marsaglia 创造的进位相乘法(Multiply-With-Carry)( http://en.wikipedia.org/wiki/Multiply-with-carry )。高斯分布 的随机数,是使用G. Marsaglia 和W. W. Tsang 创建的 金字形神塔算法 (Ziggurat)( http://en.wikipedia.org/wiki/Ziggurat_algorithm ) 来生成的。
构造函数
C++: RNG:: RNG ( uint64 state )
参数: |
|
这是 RNG 的构造函数。第一 种形式,会将状态值设置为某个预设的值,这个值,在目前的实现中,等 于 2**32-1 。第二 种形式,会将状态值设置为指定的值。如果 妳传入参数 state=0 , 则,构造函数 会使用上述说明的默认值,而不是0,以避免产生一个单一的随机数序列,其中全部都是0。
返回具有指定类型的下一个随机数。
C++: RNG:: operator short int ()
C++: RNG:: operator unsigned int ()
这些方法中的每一个,都会使用进位相乘法更新状态值,并且返回下一个指定类型的随机数。对于整数类型, 所返回的数字,是在指定类型的所有可用数值范围内取值的。对于浮点 数类型,所返回的数值,是在 [0,1) 范围内取值的。
返回下一个随机数。
C++: unsigned int RNG:: operator() ()
C++: unsigned int RNG:: operator() ( unsigned int N )
参数: |
|
这些方法,会使用进位相乘法对状态值进行变换,并且返回下一个随机数。第一 种形式等价于 RNG::next() 。第 二种形式,返回的是,随机数对 N 取模的结果,这意味着,结果的取值范围是 [0, N) 。
对数组中的元素进行随机洗牌。
C++: void randShuffle ( InputOutputArray dst , double iterFactor =1., RNG* rng =0 )
参数: |
dst – 输入/输出的一维数值数组。 iterFactor – 缩放因子,决定随机交换操作的次数(参考下文的说明)。 rng – 可选的用于洗牌过程的随机数生成器;如果它的值为0,则,会使用 theRNG() 。 |
randShuffle 这个函数, 会对指定的一维数组进行洗牌,具体过程就是,随机选择 一对元素并且交换它们的位置。 这种交换操作的次数,是 dst.rows*dst.cols*iterFactor 。
参考
将一个矩阵归纳为一个向量。
C++: void reduce ( InputArray src , OutputArray dst , int dim , int rtype , int dtype =-1 )
参数: |
src – 输入的二维矩阵。 dst – 输出向量。它的尺寸及类型,由 dim 和 dtype 参数定义。 dim – 维度索引,矩阵的归纳过程会依据这个索引进行。0表示矩阵要归纳为一个行。1表示矩阵要归纳为一个列。 rtype – 归纳操作类型,可以是以下取值: CV_REDUCE_SUM: 输出的内容,是矩阵中所有行/列的和。 CV_REDUCE_AVG: 输出的内容,是矩阵中所有行/列的均值向量。 CV_REDUCE_MAX: 输出的内容,是矩阵中所有行/列的最大值(逐列/逐行计算)。 CV_REDUCE_MIN: 输出的内容,是矩阵中所有行/列的最小值(逐列/逐行计算)。 dtype – 如果为负数,则,输出向量的类型与输入矩阵一致,否则,类型会是 CV_MAKE_TYPE(CV_MAT_DEPTH(dtype), src.channels()) 。 |
reduce 这个函数, 会将矩阵归纳为一个向量,具体 就是, 将矩阵的行/列当作一组一维向量,并且 对它们进行指定的操作 ,直到最后只剩下一个行/列。例如, 这个函数可用来计算一个位图的水平及竖直投影。对于 CV_REDUCE_SUM 和 CV_REDUCE_AVG ,输出结果可能具有更大 的元素位深,以保持精度。 这两个归纳模式,也支持多通道的数组。
参考
计算一个缩放后的数组与另一个数组的和。
C++: void scaleAdd ( InputArray src1 , double alpha , InputArray src2 , OutputArray dst )
参数: |
src1 – 第一个输入数组。 scale – 第一个数组的缩放因子。 src2 – 第二个输入数组,与 src1 具有相同的尺寸和类型。 dst – 输出数组,与 src1 具有相同的尺寸和类型。 |
scaleAdd 这个函数,是 一个经典的基本线性代数计算操作, 即是 BLAS 中的 DAXPY 或 SAXPY 。 它计算的是,一个缩放后的数组与另一个数组的和:
这个函数,也可以使用一个矩阵表达式来模拟,例如:
Mat A(3, 3, CV_64F);
...
A.row(0) = A.row(1)* 2 + A.row(2);
参考
add() 、 addWeighted() 、 subtract() 、 Mat::dot() 、 Mat::convertTo() 、 矩阵表达式
解决一个或多个线性系统或最小二乘问题。
C++: bool solve ( InputArray src1 , InputArray src2 , OutputArray dst , int flags =DECOMP_LU )
参数: |
src1 – 输入矩阵,位于系统的左侧。 src2 – 输入矩阵,位于系统的右侧。 dst – 输出的解。 flags – 计算解(矩阵转化)的方法。 DECOMP_LU 使用高斯消元法,并且选中了最佳的支点元素。 DECOMP_CHOLESKY 乔里斯基 LL T 分解法;矩阵 src1 必须 是对称的,并且其中的元素都必需是正数。 DECOMP_EIG 特征值分解;矩阵 src1 必须是对称的。 DECOMP_SVD 单值分解(singular value decomposition (SVD))方法;系统可以是过定义的(over-defined)并且/或者矩阵 src1 可以是单一的 (singular)。 DECOMP_QR QR因子分解;系统可以是过定义的(over-defined)并且/或者矩阵 src1 可以是单一的(singular)。 DECOMP_NORMAL 之前的那些标志位都是互斥的,而这个标志位呢,可以与之前的任何一个标志位一同使用;它表示,对归一化方程src1 T ∙ src1 ∙ dst=src1 T src2 进行解决,而不是对原系统src1 ∙ dst=src2进行解决。 |
solve 函数, 可用来解决一个线性系统的问题,或者 一个最小矩形问题(后者 ,可利用SVD 或QR 方法来解决,或者指定 DECOMP_NORMAL 标志位 ):
如果使用 了 DECOMP_LU 或 DECOMP_CHOLESKY 方法, 则,当 src1 (或src1Tsrc1) 是非单一的,函数就会返回1。 否则,会返回 0 。 在后一种情况下, dst 无效。其它方法 ,对于左侧是单一的情况,会找到一个假的结果。
注意
如果妳想为欠定义的单一系统 src1 ∙ dst=0 寻找一个统一范数的解 的话,函数 solve 不会起作用。应当使用 SVD::solveZ() 。
参考
对矩阵的每一行或每一列进行排序。
C++: void sort ( InputArray src , OutputArray dst , int flags )
参数: |
src – 输入的单通道数组。 dst – 输出数组,其尺寸及类型与 src 一致。 flags – 操作标志位,是以下各个值的组合: CV_SORT_EVERY_ROW 矩阵中的每一行被独立排序。 CV_SORT_EVERY_COLUMN 矩阵中的每一列被独立排序;这个标志位与前一个标志位是互斥的。 CV_SORT_ASCENDING 矩阵中的每一行被按照升序排序。 CV_SORT_DESCENDING 矩阵中的每一行被按照降序排序;这个标志位与前一个标志位是互斥的。 |
sort 函数 ,将矩阵中的每一行或每一列按照升序或降序排序。所以 ,妳应当传入两个标志位才能产生预期的行为。如果 妳想将矩阵中的行或列按照字典顺序排序,则, 可以使用标准模板库(STL)中的 std::sort 泛型函数, 并传入适当的比较断言。
参考
将一个多通道的数组分离成多个单通道的数组。
C++: void split ( const Mat& src , Mat* mvbegin )
C++: void split ( InputArray m , OutputArrayOfArrays mv )
参数: |
src – 输入的多通道数组。 mv – 输出数组,或数组组成的向量;在该函数的第一个变种中,数组的个数必须与 src.channels() 匹配;必要的情况下,数组本身会被重新分配。 |
split 函数 ,将一个多通道的数组分割成多个单通道的数组:
如果 妳想要提取出单个通道,或者进行其它复杂的通道变动,则应当使用 mixChannels() 。
参考
HxLauncher: Launch Android applications by voice commands