最近使用opencv+vs2008讀取攝像頭的時候,抓取圖像總是返回空。無解,在網上看到一個資料,轉載於此。
GEMM
通用矩陣乘法
void cvGEMM( const CvArr* src1, const CvArr* src2, double alpha, const CvArr* src3, double beta, CvArr* dst, int tABC=0 ); #define cvMatMulAdd( src1, src2, src3, dst ) cvGEMM( src1, src2, 1, src3, 1, dst, 0 ) #define cvMatMul( src1, src2, dst ) cvMatMulAdd( src1, src2, 0, dst )
- src1
- 第一輸入數組
- src2
- 第二輸入數組
- src3
- 第三輸入數組 (偏移量),如果沒有偏移量,可以爲空( NULL) 。
- dst
- 輸出數組
- tABC
- T操作標誌,可以是 0 或者下面列舉的值的組合:
- CV_GEMM_A_T - 轉置 src1
- CV_GEMM_B_T - 轉置 src2
- CV_GEMM_C_T - 轉置 src3
- 例如, CV_GEMM_A_T+CV_GEMM_C_T 對應
- alpha*src1T*src2 + beta*src3T
函數 cvGEMM 執行通用矩陣乘法:
dst = alpha*op(src1)*op(src2) + beta*op(src3), 這裏 op(X) 是 X 或者 XT
所有的矩陣應該有相同的數據類型和協調的矩陣大小。支持實數浮點矩陣或者複數浮點矩陣。
Transform
對數組每一個元素執行矩陣變換
void cvTransform( const CvArr* src, CvArr* dst, const CvMat* transmat, const CvMat* shiftvec=NULL );
- src
- 輸入數組
- dst
- 輸出數組
- transmat
- 變換矩陣
- shiftvec
- 可選偏移向量
函數 cvTransform 對數組 src 每一個元素執行矩陣變換並將結果存儲到 dst:
- dst(I)=transmat*src(I) + shiftvec
或者
- dst(I)k=sumj(transmat(k,j)*src(I)j) + shiftvec(k)
N-通道數組 src 的每一個元素都被視爲一個N元向量,使用一個 M×N 的變換矩陣 transmat 和偏移向量 shiftvec 把它變換到一個 M-通道的數組 dst 的一個元素中。 這裏可以選擇將偏移向量 shiftvec 嵌入到 transmat 中。這樣的話 transmat 應該是 M×N+1 的矩陣,並且最右邊的一列被看作是偏移向量 。
輸入數組和輸出數組應該有相同的位深(depth)和同樣的大小或者 ROI 大小。 transmat 和 shiftvec 應該是實數浮點矩陣。
該函數可以用來進行 ND 點集的幾何變換,任意的線性顏色空間變換,通道轉換等。
MulTransposed
計算數組和數組的轉置的乘積
void cvMulTransposed( const CvArr* src, CvArr* dst, int order, const CvArr* delta=NULL );
- src
- 輸入矩陣
- dst
- 目標矩陣
- order
- 乘法順序
- delta
- 一個可選數組, 在乘法之前從 src 中減去該數組。
函數 cvMulTransposed 計算 src 和它的轉置的乘積。
函數求值公式:
如果 order=0
- dst=(src-delta)*(src-delta)T
否則
- dst=(src-delta)T*(src-delta)
Trace
返回矩陣的跡
CvScalar cvTrace( const CvArr* mat );
- mat
- 輸入矩陣
函數 cvTrace 返回矩陣mat的對角線元素的和。
-
tr(src) = ∑ mat(i,i) i
Transpose
矩陣的轉置
void cvTranspose( const CvArr* src, CvArr* dst ); #define cvT cvTranspose
- src
- 輸入矩陣
- dst
- 目標矩陣
函數 cvTranspose 對矩陣 src 求轉置:
- dst(i,j)=src(j,i)
注意,假設是複數矩陣不會求得複數的共軛。共軛應該是獨立的:查看的 cvXorS 例子代碼。
Det
返回矩陣的行列式值
double cvDet( const CvArr* mat );
- mat
- 輸入矩陣
函數 cvDet 返回方陣 mat 的行列式值。對小矩陣直接計算,對大矩陣用高斯(GAUSSIAN)消去法。對於對稱正定(positive-determined)矩陣也可以用 SVD 函數來求,U=V=NULL ,然後用 w 的對角線元素的乘積來計算行列式。
Invert
查找矩陣的逆矩陣或僞逆矩陣
double cvInvert( const CvArr* src, CvArr* dst, int method=CV_LU ); #define cvInv cvInvert
- src
- 輸入矩陣
- dst
- 目標矩陣
- method
- 求逆方法:
- CV_LU -最佳主元選取的高斯消除法
- CV_SVD - 奇異值分解法 (SVD)
- CV_SVD_SYM - 正定對稱矩陣的 SVD 方法
函數 cvInvert 對矩陣 src 求逆並將結果存儲到 dst。
如果是 LU 方法該函數返回 src 的行列式值 (src 必須是方陣)。 如果是 0, 矩陣不求逆, dst 用 0 填充。
如果 SVD 方法該函數返回 src 的條件數的倒數(最小奇異值和最大奇異值的比值) ,如果 src 全爲 0 則返回0。 如果 src 是奇異的, SVD 方法計算一個僞逆矩陣。
Solve
求解線性系統或者最小二乘法問題
int cvSolve( const CvArr* src1, const CvArr* src2, CvArr* dst, int method=CV_LU );
- src1
- 輸入矩陣
- src2
- 線性系統的右部
- dst
- 輸出解答
- method
- 解決方法(矩陣求逆) :
- CV_LU - 最佳主元選取的高斯消除法
- CV_SVD - 奇異值分解法 (SVD)
- CV_SVD_SYM - 對正定對稱矩陣的 SVD 方法
函數 cvSolve 解決線性系統或者最小二乘法問題 (後者用 SVD 方法可以解決):
如果使用 CV_LU 方法。 如果 src1 是非奇異的,該函數則返回 1 ,否則返回 0 ,在後一種情況下 dst 是無效的。
SVD
對實數浮點矩陣進行奇異值分解
void cvSVD( CvArr* A, CvArr* W, CvArr* U=NULL, CvArr* V=NULL, int flags=0 );
- A
- M×N 的輸入矩陣
- W
- 結果奇異值矩陣 (M×N 或者 N×N) 或者 向量 (N×1).
- U
- 可選的左部正交矩陣 (M×M or M×N). 如果 CV_SVD_U_T 被指定,應該交換上面所說的行與列的數目。
- V
- 可選右部正交矩陣(N×N)
- flags
- 操作標誌; 可以是 0 或者下面的值的組合:
- CV_SVD_MODIFY_A 通過操作可以修改矩陣 src1 。這樣處理速度會比較快。
- CV_SVD_U_T 意味着會返回轉置矩陣 U ,指定這個標誌將加快處理速度。
- CV_SVD_V_T 意味着會返回轉置矩陣 V ,指定這個標誌將加快處理速度。
函數 cvSVD 將矩陣 A 分解成一個對角線矩陣和兩個正交矩陣的乘積:
這裏 W 是一個奇異值的對角線矩陣,它可以被編碼成奇異值的一維向量,U 和 V 也是一樣。所有的奇異值都是非負的並按降序存儲。(U 和 V 也相應的存儲)。
SVD 算法在數值處理上已經很穩定,它的典型應用包括:
- 當 A 是一個方陣、對稱陣和正矩陣時精確的求解特徵值問題,例如, 當 A 時一個協方差矩陣時。在這種情況下 W 將是一個特徵值的的向量,並且 U=V是矩陣的特徵向量(因此,當需要計算特徵向量時 U 和 V 只需要計算其中一個就可以了) 。
- 精確的求解病態線性系統。
- 超定線性系統的最小二乘求解。上一個問題和這個問題都可以用指定 CV_SVD 的 cvSolve 方法。
- 精確計算矩陣的不同特徵,如秩(非零奇異值的數目), 條件數(最大奇異值和最小奇異值的比例), 行列式值(行列式的絕對值等於奇異值的乘積).上述的所有這些值都不要求計算矩陣 U 和 V 。
SVBkSb
奇異值回代算法(back substitution)
void cvSVBkSb( const CvArr* W, const CvArr* U, const CvArr* V, const CvArr* B, CvArr* X, int flags );
- W
- 奇異值矩陣或者向量
- U
- 左正交矩陣 (可能是轉置的)
- V
- 右正交矩陣 (可能是轉置的)
- B
- 原始矩陣 A 的僞逆的乘法矩陣。這個是可選參數。如果它被省略則假定它是一個適當大小的單位矩陣(因此 x 將是 A 的僞逆的重建).。
- X
- 目標矩陣: 奇異值回代算法的結果
- flags
- 操作標誌, 和剛剛討論的 cvSVD 的標誌一樣。
函數 cvSVBkSb 爲被分解的矩陣 A 和矩陣 B 計算回代逆(back substitution) (參見 cvSVD 說明) :
- X=V*W-1*UT*B
這裏
- W-1(i,i)=1/W(i,i) 如果 W(i,i) > epsilon•sumiW(i,i),
- 否則:0.
epsilon 是一個依賴於矩陣數據類型的的很小的數。該函數和 cvSVD 函數被用來執行 cvInvert 和 cvSolve, 用這些函數 (svd & bksb)的原因是初級函數(low-level)函數可以避免高級函數 (inv & solve) 計算中內部分配的臨時矩陣。
EigenVV
計算對稱矩陣的特徵值和特徵向量
void cvEigenVV( CvArr* mat, CvArr* evects, CvArr* evals, double eps=0 );
- mat
- 輸入對稱方陣。在處理過程中將被改變。
- evects
- 特徵向量輸出矩陣, 連續按行存儲
- evals
- 特徵值輸出矩陣,按降序存儲(當然特徵值和特徵向量的排序是同步的)。
- eps
- 對角化的精確度 (典型地, DBL_EPSILON=≈10-15 就足夠了)。
函數 cvEigenVV 計算矩陣 A 的特徵值和特徵向量:
mat*evects(i,:)' = evals(i)*evects(i,:)' (在 MATLAB 的記法)
矩陣 A 的數據將會被這個函數修改。
目前這個函數比函數 cvSVD 要慢,精確度要低, 如果已知 A 是正定的,(例如, 它是一個協方差矩陣), 它通常被交給函數 cvSVD 來計算其特徵值和特徵向量,尤其是在不需要計算特徵向量的情況下
CalcCovarMatrix
計算向量集合的協方差矩陣
void cvCalcCovarMatrix( const CvArr** vects, int count, CvArr* cov_mat, CvArr* avg, int flags );
- vects
- 輸入向量。他們必須有同樣的數據類型和大小。這個向量不一定非是一維的,他們也可以是二維(例如,圖像)等等。
- count
- 輸入向量的數目
- cov_mat
- 輸出協方差矩陣,它是浮點型的方陣。
- avg
- 輸入或者輸出數組 (依賴於標記“flags”) - 輸入向量的平均向量。
- flags
- 操作標誌,下面值的組合:
- CV_COVAR_SCRAMBLED - 輸出協方差矩陣按下面計算:
- scale * [vects[0] − avg,vects[1] − avg,...]T * [vects[0] − avg,vects[1] − avg,...], 即協方差矩陣是 count×count. 這樣一個不尋常的矩陣用於一組大型向量的快速PCA方法(例如, 人臉識別的 EigenFaces 技術)。這個混雜("scrambled")矩陣的特徵值將和真正的協方差矩陣的特徵值匹配,真正的特徵向量可以很容易的從混雜("scrambled")協方差矩陣的特徵向量中計算出來。
- CV_COVAR_NORMAL - 輸出協方差矩陣被計算成:
- scale * [vects[0] − avg,vects[1] − avg,...] * [vects[0] − avg,vects[1] − avg,...]T, 也就是說, cov_mat 將是一個和每一個輸入向量的元素數目具有同樣線性大小的通常協方差矩陣。 CV_COVAR_SCRAMBLED 和 CV_COVAR_NORMAL 只能同時指定其中一個。
- CV_COVAR_USE_AVG - 如果這個標誌被指定, 該函數將不會從輸入向量中計算 avg ,而是用過去的 avg 向量,如果 avg 已經以某種方式計算出來了這樣做是很有用的。或者如果協方差矩陣是部分計算出來的 - 倘若這樣, avg 不是輸入向量的子集的平均值,而是整個集合的平均向量。
- CV_COVAR_SCALE - 如果這個標誌被指定,協方差矩陣被縮放了。 the covariation matrix is scaled.在 "normal" 模式下縮放比例是 1./count, 在 "scrambled" 模式下縮放比例是每一個輸入向量的元素總和的倒數。 缺省地(如果沒有指定標誌) 協方差矩陣不被縮放 (scale=1)。
- CV_COVAR_SCRAMBLED - 輸出協方差矩陣按下面計算:
函數 cvCalcCovarMatrix 計算輸入向量的協方差矩陣和平均向量。該函數可以被運用到主成分分析中(PCA),以及馬氏距離(Mahalanobis distance)比較向量中等等。
Mahalanobis
計算兩個向量之間的馬氏距離(Mahalanobis distance)
double cvMahalanobis( const CvArr* vec1, const CvArr* vec2, CvArr* mat );
- vec1
- 第一個一維輸入向量
- vec2
- 第二個一維輸入向量
- mat
- 協方差矩陣的逆矩陣
函數 cvMahalanobis 計算兩個向量之間的加權距離,其返回結果是:
協方差矩陣可以用函數cvCalcCovarMatrix 計算出來,逆矩陣可以用函數 cvInvert 計算出來 (CV_SVD 方法是一個比較好的選擇, 因爲矩陣可能是奇異的).
CalcPCA
對一個向量集做PCA變換
void cvCalcPCA( const CvArr* data, CvArr* avg, CvArr* eigenvalues, CvArr* eigenvectors, int flags );
- data
- 輸入數據,每個向量是單行向量(CV_PCA_DATA_AS_ROW)或者單列向量(CV_PCA_DATA_AS_COL).
- avg
- 平均向量,在函數內部計算或者由調用者提供
- eigenvalues
- 輸出的協方差矩陣的特徵值
- eigenvectors
- 輸出的協方差矩陣的特徵向量(也就是主分量),每個向量一行
- flags
- 操作標誌,可以是以下幾種方式的組合:
- CV_PCA_DATA_AS_ROW - 向量以行的方式存放(也就是說任何一個向量都是連續存放的)
- CV_PCA_DATA_AS_COL - 向量以列的方式存放(也就是說某一個向量成分的數值是連續存放的)
- (上面兩種標誌是互相排斥的)
- CV_PCA_USE_AVG - 使用預先計算好的平均值
該函數對某個向量集做PCA變換.它首先利用cvCalcCovarMatrix計算協方差矩陣然後計算協方差矩陣的特徵值與特徵向量.輸出的特徵值/特徵向量的個數小於或者等於MIN(rows(data),cols(data)).
ProjectPCA
把向量向某個子空間投影
void cvProjectPCA( const CvArr* data, const CvArr* avg, const CvArr* eigenvectors, CvArr* result )
- data
- 輸入數據,每個向量可以是單行或者單列
- avg
- 平均向量.要麼它是單行向量那麼意味着輸入數據以行數據的形式存放,要麼就是單列向量,那麼就意味着那麼輸入向量就是以列的方式存放.
- eigenvectors
- 特徵向量(主分量),每個向量一行.
- result
- 輸出的分解係數矩陣,矩陣的行數必須與輸入向量的個數相等,矩陣的列數必須小於特徵向量的行數.
該函數將輸入向量向一個正交系(eigenvectors)投影.在計算點乘之前,輸入向量要減去平均向量:
result(i,:)=(data(i,:)-avg)*eigenvectors' // for CV_PCA_DATA_AS_ROW layout.
BackProjectPCA
根據投影係數重構原來的向量
void cvBackProjectPCA( const CvArr* proj, const CvArr* avg, const CvArr* eigenvects, CvArr* result );
- proj
- 輸入數據,與cvProjectPCA裏面的格式一致
- avg
- 平均向量.如果它是單行向量,那麼意味着輸出向量是以行的方式存放.否則就是單列向量,那麼輸出向量就是以列的方式存放.
- eigenvectors
- 特徵向量(主分量),每個向量一行.
- result
- 輸出的重構出來的矩陣
該函數根據投影係數重構原來的向量:
result(i,:)=proj(i,:)*eigenvectors + avg // for CV_PCA_DATA_AS_ROW layout
附
|