• Open Source Computer Vision Library

Cxcore數組操作

Wikipedia,自由的百科全书

目錄

初始化

CreateImage

創建頭並分配數據

IplImage* cvCreateImage( CvSize size, int depth, int channels );
size
圖像寬、高.
depth 
圖像元素的位深度,可以是下麵的其中之一:
IPL_DEPTH_8U - 無符號8位整型
IPL_DEPTH_8S - 有符號8位整型
IPL_DEPTH_16U - 無符號16位整型
IPL_DEPTH_16S - 有符號16位整型
IPL_DEPTH_32S - 有符號32位整型
IPL_DEPTH_32F - 單精度浮點數
IPL_DEPTH_64F - 雙精度浮點數
channels 
每個元素(像素)的顏色通道數量.可以是 1, 2, 3 或 4.通道是交叉存取的,例如通常的彩色圖像數據排列是:
b0 g0 r0 b1 g1 r1 ...
雖然通常 IPL 圖象格式可以存貯非交叉存取的圖像,並且一些OpenCV 也能處理他, 但是這個函數只能創建交叉存取圖像.

函數 cvCreateImage 創建頭並分配數據,這個函數是下列的縮寫型式

header = cvCreateImageHeader(size,depth,channels);
cvCreateData(header); //只是創建空間,並不會初始化空間內的數據

CreateImageHeader

分配,初始化,並且返回 IplImage結構

IplImage* cvCreateImageHeader( CvSize size, int depth, int channels );
size
圖像寬、高.
depth
像深 (見 CreateImage).
channels
通道數 (見 CreateImage).

函數 cvCreateImageHeader 分配, 初始化, 並且返回 IplImage結構. 這個函數相似於:

  iplCreateImageHeader( channels, 0, depth,
                        channels == 1 ? "GRAY" : "RGB",
                        channels == 1 ? "GRAY" : channels == 3 ? "BGR" :
                        channels == 4 ? "BGRA" : "",
                        IPL_DATA_ORDER_PIXEL, IPL_ORIGIN_TL, 4,
                        size.width, size.height,
                        0,0,0,0);

然而IPL函數不是作為預設的 (見 CV_TURN_ON_IPL_COMPATIBILITY 巨集)

調用cvCreateImageHeader創建的圖像,需要調用cvReleaseImageHeader釋放圖像頭,然後將原始圖像數據單獨刪除。

ReleaseImageHeader

釋放頭

void cvReleaseImageHeader( IplImage** image );
image 
雙指針指向頭記憶體分配單元.

函數 cvReleaseImageHeader 釋放頭. 相似於

if( image )
{
    iplDeallocate( *image, IPL_IMAGE_HEADER | IPL_IMAGE_ROI );
    *image = 0;
}

然而IPL函數不是作為預設的 (見 CV_TURN_ON_IPL_COMPATIBILITY 巨集)

ReleaseImage

釋放頭和圖像數據

void cvReleaseImage( IplImage** image );
image 
雙指針指向圖像記憶體分配單元。

函數 cvReleaseImage 釋放頭和圖像數據,相似於:

if( *image )
{
    cvReleaseData( *image );
    cvReleaseImageHeader( image );
}

InitImageHeader

初始化被用圖分配的圖像頭

IplImage* cvInitImageHeader( IplImage* image, CvSize size, int depth,
                             int channels, int origin=0, int align=4 );
image 
被初始化的圖像頭.
size 
圖像的寬高.
depth 
像深(見 CreateImage).
channels 
通道數(見 CreateImage).
origin 
IPL_ORIGIN_TL 或 IPL_ORIGIN_BL.
align 
圖像行排列, 典型的 4 或 8 位元組.

函數 cvInitImageHeader 初始化圖像頭結構, 指向用戶指定的圖像並且返回這個指針。

CloneImage

製作圖像的完整拷貝

IplImage* cvCloneImage( const IplImage* image );
image 
原圖像.

函數 cvCloneImage 製作圖像的完整拷貝包括頭、ROI和數據

SetImageCOI

基於給定的值設置感興趣通道

void cvSetImageCOI( IplImage* image, int coi );
image 
圖像頭.
coi 
感興趣通道.

函數 cvSetImageCOI 基於給定的值設置感興趣的通道。值 0 意味著所有的通道都被選定, 1 意味著第一個通道被選定等等。如果 ROI 是 NULL 並且COI!= 0, ROI 被分配. 然而大多數的 OpenCV 函數不支持 COI, 對於這種狀況當處理分離圖像/矩陣通道時,可以拷貝(通過 cvCopy 或cvSplit) 通道來分離圖像/矩陣,處理後如果需要可再拷貝(通過cvCopy 或 cvCvtPlaneToPix)回來.

GetImageCOI

返回感興趣通道號

int cvGetImageCOI( const IplImage* image );
image 
圖像頭.

函數cvGetImageCOI 返回圖像的感興趣通道(當所有的通道都被選中返回值是0).

SetImageROI

基於給定的矩形設置'感興趣'區域

void cvSetImageROI( IplImage* image, CvRect rect );
image 
圖像.
rect 
ROI 矩形.

函數 cvSetImageROI 基於給定的矩形設置圖像的 ROI(感興趣區域) . 如果ROI是NULL 並且參數RECT的值不等於整個圖像, ROI被分配. 不像 COI, 大多數的 OpenCV 函數支持 ROI 並且處理它就像它是一個分離的圖像 (例如, 所有的像素坐標從ROI的左上角或左下角(基於圖像的結構)計算。

ResetImageROI

釋放圖像的ROI

void cvResetImageROI( IplImage* image );
image 
圖像頭.

函數 cvResetImageROI 釋放圖像 ROI. 釋放之後整個圖像被認為是全部被選中的。相似的結果可以通過下述辦法

cvSetImageROI( image, cvRect( 0, 0, image->width, image->height ));
cvSetImageCOI( image, 0 );

但是後者的變數不分配 image->roi.

GetImageROI

返回圖像的 ROI 坐標

CvRect cvGetImageROI( const IplImage* image );
image 
圖像頭.

函數 cvGetImageROI 返回圖像ROI 坐標. 如果沒有ROI則返回矩形值為 cvRect(0,0,image->width,image->height)

CreateMat

創建矩陣

CvMat* cvCreateMat( int rows, int cols, int type );
rows 
矩陣行數。
cols 
矩陣列數。
type 
矩陣元素類型。 通常以 CV_<比特數>(S|U|F)C<通道數>型式描述, 例如:
   CV_8UC1 意思是一個8-bit 無符號單通道矩陣, CV_32SC2 意思是一個32-bit 有符號二個通道的矩陣。 

函數 cvCreateMat 為新的矩陣分配頭和下麵的數據,並且返回一個指向新創建的矩陣的指針。是下列操作的縮寫型式:

CvMat* mat = cvCreateMatHeader( rows, cols, type );
cvCreateData( mat );

矩陣按行存貯。所有的行以4個位元組對齊。

CreateMatHeader

創建新的矩陣頭

CvMat* cvCreateMatHeader( int rows, int cols, int type );
rows
矩陣行數.
cols
矩陣列數.
type
矩陣元素類型(見 cvCreateMat).

函數 cvCreateMatHeader 分配新的矩陣頭並且返回指向它的指針. 矩陣數據可被進一步的分配,使用cvCreateData 或通過 cvSetData明確的分配數據. 當這個矩陣不需要時,仍需要調用cvReleaseMat函數釋放矩陣頭記憶體單元.

ReleaseMat

刪除矩陣

void cvReleaseMat( CvMat** mat );
mat
雙指針指向矩陣.

函數cvReleaseMat 縮減矩陣數據參考計數並且釋放矩陣頭 :

if( *mat )
    cvDecRefData( *mat );
cvFree( (void**)mat );

InitMatHeader

初始化矩陣頭

CvMat* cvInitMatHeader( CvMat* mat, int rows, int cols, int type,
       	                void* data=NULL, int step=CV_AUTOSTEP );
mat
指針指向要被初始化的矩陣頭.
rows
矩陣的行數.
cols
矩陣的列數.
type
矩陣元素類型.
data
可選的,將指向數據指針分配給矩陣頭.
step
排列後的數據的整個行寬,預設狀態下,使用STEP的最小可能值。也就是說預設情況下假定矩陣的行與行之間無隙.

函數 cvInitMatHeader 初始化已經分配了的 CvMat 結構. 它可以被OpenCV矩陣函數用於處理原始數據。

例如, 下麵的代碼計算通用數組格式存貯的數據的矩陣乘積.

計算兩個矩陣的積

double a[] = { 1, 2, 3, 4,
               5, 6, 7, 8,
               9, 10, 11, 12 };

double b[] = { 1, 5, 9,
               2, 6, 10,
               3, 7, 11,
               4, 8, 12 };

double c[9];
CvMat Ma, Mb, Mc ;

cvInitMatHeader( &Ma, 3, 4, CV_64FC1, a );
cvInitMatHeader( &Mb, 4, 3, CV_64FC1, b );
cvInitMatHeader( &Mc, 3, 3, CV_64FC1, c );

cvMatMulAdd( &Ma, &Mb, 0, &Mc );
// c 數組存貯 a(3x4) 和 b(4x3) 矩陣的積

Mat

初始化矩陣的頭(輕磅變數)

CvMat cvMat( int rows, int cols, int type, void* data=NULL );
rows
矩陣行數
cols
列數.
type
元素類型(見CreateMat).
data
可選的分配給矩陣頭的數據指針 .

函數 cvMat 是個一快速內連函數,替代函數 cvInitMatHeader. 也就是說它相當於:

CvMat mat;
cvInitMatHeader( &mat, rows, cols, type, data, CV_AUTOSTEP );

CloneMat

創建矩陣拷貝

CvMat* cvCloneMat( const CvMat* mat );
mat
輸入矩陣.

函數 cvCloneMat 創建輸入矩陣的一個拷貝並且返回 該矩陣的指針.

CreateMatND

創建多維密集數組

CvMatND* cvCreateMatND( int dims, const int* sizes, int type );
dims
數組維數. 但不許超過 CV_MAX_DIM (預設=32,但這個預設值可能在編譯時被改變 )的定義
sizes
數組的維大小.
type
數組元素類型. 與 CvMat相同

函數cvCreateMatND 分配頭給多維密集數組並且分配下麵的數據,返回指向被創建數組的指針 . 是下列的縮減形式:

CvMatND* mat = cvCreateMatNDHeader( dims, sizes, type );
cvCreateData( mat );

矩陣按行存貯. 所有的行以4個位元組排列。.

CreateMatNDHeader

創建新的數組頭

CvMatND* cvCreateMatNDHeader( int dims, const int* sizes, int type );
dims
數組維數.
sizes
維大小.
type
數組元素類型. 與 CvMat相同

函數cvCreateMatND 分配頭給多維密集數組。數組數據可以用 cvCreateData 進一步的被分配或利用cvSetData由用戶明確指定.

ReleaseMatND

刪除多維數組

void cvReleaseMatND( CvMatND** mat );
mat
指向數組的雙指針.

函數 cvReleaseMatND 縮減數組參考計數並釋放數組頭:

if( *mat )
    cvDecRefData( *mat );
cvFree( (void**)mat );

InitMatNDHeader

初始化多維數組頭

CvMatND* cvInitMatNDHeader( CvMatND* mat, int dims, const int* sizes, int type, void* data=NULL );
mat
指向要被出初始化的數組頭指針.
dims
數組維數.
sizes
維大小.
type
數組元素類型. 與 CvMat相同
data
可選的分配給矩陣頭的數據指針.

函數 cvInitMatNDHeader 初始化 用戶指派的CvMatND 結構.

CloneMatND

創建多維數組的完整拷貝

CvMatND* cvCloneMatND( const CvMatND* mat );
mat
輸入數組

函數 cvCloneMatND 創建輸入數組的拷貝並返回指針.

DecRefData

縮減數組數據的引用計數

void cvDecRefData( CvArr* arr );
arr
數組頭.

如果引用計數指針非NULL,函數 cvDecRefData 縮減CvMat 或CvMatND 數據的引用計數,如果計數到0就刪除數據。在當前的版本中只有當數據是用cvCreateData 分配的引用計數才會是非NULL。在其他的情況下比如:

  • 使用cvSetData指派外部數據給矩陣頭;
  • 代表部分大的矩陣或圖像的矩陣頭;
  • 是從圖像頭或N維矩陣頭轉換過來的矩陣頭,

在這些情況下引用計數被設置成NULL因此不會被縮減。 無論數據是否被刪除,數據指針和引用計數指針都將被這個函數清空。

IncRefData

增加數組數據的引用計數

int cvIncRefData( CvArr* arr );
arr
數組頭.

函數 cvIncRefData 增加 CvMat 或 CvMatND 數據引用計數,如果引用計數非空返回新的計數值 否則返回0。

CreateData

分配數組數據

void cvCreateData( CvArr* arr );
arr
數組頭.

函數 cvCreateData 分配圖像,矩陣或多維數組數據. 對於矩陣類型使用OpenCV的分配函數,對於 IplImage類型如果CV_TURN_ON_IPL_COMPATIBILITY沒有被調用也是可以使用這種方法的反之使用 IPL 函數分配數據

ReleaseData

釋放數組數據

void cvReleaseData( CvArr* arr );
arr
數組頭

函數cvReleaseData 釋放數組數據. 對於 CvMat 或 CvMatND 結構只需調用 cvDecRefData(), 也就是說這個函數不能刪除外部數據。見 cvCreateData.

SetData

指派用戶數據給數組頭

void cvSetData( CvArr* arr, void* data, int step );
arr
數組頭.
data
用戶數據.
step
整行位元組長.

函數cvSetData 指派用戶數據給數組頭. 頭應該已經使用 cvCreate*Header, cvInit*Header 或 cvMat (對於矩陣)初始化過.

GetRawData

返回數組的底層信息

void cvGetRawData( const CvArr* arr, uchar** data,
                   int* step=NULL, CvSize* roi_size=NULL );
arr
數組頭.
data
輸出指針,指針指向整個圖像的結構或ROI
step
輸出行位元組長
roi_size
輸出ROI尺寸

函數 cvGetRawData 添充給輸出變數數組的底層信息。所有的輸出參數是可選的, 因此這些指針可設為NULL。如果數組是設置了ROI的 IplImage 結構, ROI參數被返回。

註意:輸出指針指向數組頭的對應的記憶體,不能釋放。建議用memcpy。

接下來的例子展示怎樣利用這個函數去訪問數組元素。

使用 GetRawData 計算單通道浮點數組的元素絕對值。

float* data;
int step;

CvSize size;
int x, y;

cvGetRawData( array, (uchar**)&data, &step, &size );
step /= sizeof(data[0]);

for( y = 0; y < size.height; y++, data += step )
    for( x = 0; x < size.width; x++ )
        data[x] = (float)fabs(data[x]);

GetMat

從不確定數組返回矩陣頭

CvMat* cvGetMat( const CvArr* arr, CvMat* header, int* coi=NULL, int allowND=0 );
arr
輸入數組.
header
指向 CvMat結構的指針,作為臨時緩存 .
coi
可選的輸出參數,用於輸出COI.
allowND
如果非0,函數就接收多維密集數組 (CvMatND*)並且返回 2D (如果 CvMatND 是二維的)或 1D 矩陣(當 CvMatND 是一維或多於二維). 數組必須是連續的.


   函數 cvGetMat從輸入的數組生成矩陣頭,輸入的數組可以是 - CvMat結構,  IplImage結構 或多維密集數組 CvMatND* (後者只有當 allowND != 0時才可以使用) . 如果是矩陣函數只是返回指向矩陣的指針.如果是 IplImage* 或 CvMatND* 函數用當前圖像的ROI初始化頭結構並且返回指向這個臨時結構的指針。因為CvMat不支持COI,所以他們的返回結果是不同的.

這個函數提供了一個簡單的方法,用同一代碼處理 IplImage 和 CvMat二種數據類型。這個函數的反向轉換可以用 cvGetImage將 CvMat 轉換成 IplImage .

輸入的數組必須有已分配好的底層數據或附加的數據,否則該函數將調用失敗 如果輸入的數組是IplImage 格式,使用平面式數據編排並設置了COI,函數返回的指針指向被選定的平面並設置COI=0.利用OPENCV函數對於多通道平面編排圖像可以處理每個平面。

   返回的 CvMat * 結構指向輸入的header。 By Jackyzzy 趙振陽

GetImage

從不確定數組返回圖像頭

IplImage* cvGetImage( const CvArr* arr, IplImage* image_header );
arr
輸入數組.
image_header
指向IplImage結構的指針,該結構存貯在一個臨時緩存 .

函數 cvGetImage 從輸出數組獲得圖頭,該數組可以是矩陣- CvMat*, 或圖像 - IplImage*。 如果是圖像的話函數只是返回輸入參數的指針,如果是 CvMat* 的話函數用輸入參數矩陣初始化圖像頭。因此如果我們把 IplImage 轉換成 CvMat 然後再轉換 CvMat 回 IplImage,如果ROI被設置過了我們可能會獲得不同的頭,這樣一些計算圖像跨度的IPL函數就會失敗。

CreateSparseMat

創建稀疏數組

CvSparseMat* cvCreateSparseMat( int dims, const int* sizes, int type );
dims
數組維數。相對於密集型矩陣,稀疏數組的維數是不受限制的(最多可達 216)。
sizes
數組的維大小。
type
數組元素類型,見 CvMat。

函數 cvCreateSparseMat 分配多維稀疏數組。剛初始化的數組不含元素,因此cvGet*D 或 cvGetReal*D函數對所有索引都返回0。

ReleaseSparseMat

刪除稀疏數組

void cvReleaseSparseMat( CvSparseMat** mat );
mat
雙指針指向數組。

函數 cvReleaseSparseMat釋放稀疏數組並清空數組指針

CloneSparseMat

創建稀疏數組的拷貝

CvSparseMat* cvCloneSparseMat( const CvSparseMat* mat );
mat
輸入數組。

函數 cvCloneSparseMat 創建輸入數組的拷貝並返回指向這個拷貝的指針。

獲取元素和數組子集

GetSubRect

返回輸入的圖像或矩陣的矩形數組子集的矩陣頭

CvMat* cvGetSubRect( const CvArr* arr, CvMat* submat, CvRect rect );
arr
輸入數組。
submat
指向矩形數組子集矩陣頭的指針。
rect
以0坐標為基準的ROI。

函數 cvGetSubRect 根據指定的數組矩形返回矩陣頭,換句話說,函數允許像處理一個獨立數組一樣處理輸入數組的一個指定子矩形。函數在處理時要考慮進輸入數組的ROI,因此數組的ROI是實際上被提取的。

GetRow, GetRows

返回數組的一行或在一定跨度內的行

CvMat* cvGetRow( const CvArr* arr, CvMat* submat, int row );
CvMat* cvGetRows( const CvArr* arr, CvMat* submat, int start_row, int end_row, int delta_row=1 );
arr
輸入數組。
submat
指向返回的子數組頭的指針。
row
被選定行的索引下標,索引下標從0開始。
start_row
跨度的開始行(包括此行)索引下標,索引下標從0開始。
end_row
跨度的結束行(不包括此行)索引下標,索引下標從0開始。
delta_row
在跨度內的索引下標跨步,從開始行到結束行每隔delta_row行提取一行。

函數GetRow 和 GetRows 返回輸入數組中指定的一行或在一定跨度內的行對應的數組頭。 註意GetRow 實際上是 以下cvGetRows調用的簡寫:

cvGetRow( arr, submat, row ) ~ cvGetRows( arr, submat, row, row + 1, 1 );

GetCol, GetCols

返回數組的一列或一定跨度內的列

CvMat* cvGetCol( const CvArr* arr, CvMat* submat, int col );
CvMat* cvGetCols( const CvArr* arr, CvMat* submat, int start_col, int end_col );
arr
輸入數組。
submat
指向結果子數組頭的指針。
col
被選定列的索引下標,索引下標從0開始。
start_col
跨度的開始列(包括該列)索引下標,索引下標從0開始。
end_col
跨度的結束列(不包括該列)索引下標,索引下標從0開始。

函數 GetCol 和 GetCols 根據指定的列/列跨度返回對應的數組頭。註意GetCol 實際上是以下 cvGetCols調用的簡寫形式:

cvGetCol( arr, submat, col ); // ~ cvGetCols( arr, submat, col, col + 1 );

GetDiag

返回一個數組對角線

CvMat* cvGetDiag( const CvArr* arr, CvMat* submat, int diag=0 );
arr
輸入數組.
submat
指向結果子集的頭指針.
diag
數組對角線。0是主對角線,-1是主對角線上面對角線,1是主對角線下對角線,以此類推。

函數 cvGetDiag 根據指定的diag參數返回數組的對角線頭。

GetSize

返回矩陣或圖像ROI的大小

CvSize cvGetSize( const CvArr* arr );
arr
數組頭。

函數 cvGetSize 返回圖像或矩陣的行數和列數,如果是圖像就返回ROI的大小。

InitSparseMatIterator

初始化稀疏數組元素迭代器

CvSparseNode* cvInitSparseMatIterator( const CvSparseMat* mat,
                                       CvSparseMatIterator* mat_iterator );
mat
輸入的數組.
mat_iterator
被初始化的迭代器.

函數 cvInitSparseMatIterator 初始化稀疏數組元素的迭代器並且返回指向第一個元素的指針,如果數組為空則返回NULL。

GetNextSparseNode

初始化稀疏數組元素迭代器

CvSparseNode* cvGetNextSparseNode( CvSparseMatIterator* mat_iterator );
mat_iterator
稀疏數組的迭代器

函數cvGetNextSparseNode 移動迭代器到下一個稀疏矩陣元素並返回指向他的指針。在當前的版本不存在任何元素的特殊順序,因為元素是按HASH表存貯的下麵的列子描述怎樣在稀疏矩陣上迭代 :

利用cvInitSparseMatIterator 和cvGetNextSparseNode 計算浮點稀疏數組的和。

double sum;
int i, dims = cvGetDims( array );
CvSparseMatIterator mat_iterator;
CvSparseNode* node = cvInitSparseMatIterator( array, &mat_iterator );

for( ; node != 0; node = cvGetNextSparseNode( &mat_iterator ))
{
    int* idx = CV_NODE_IDX( array, node ); /* get pointer to the element indices */
    float val = *(float*)CV_NODE_VAL( array, node ); /* get value of the element
                                                      (assume that the type is CV_32FC1) */
    printf( "(" );
    for( i = 0; i < dims; i++ )
        printf( "%4d%s", idx[i], i < dims - 1 ? "," : "): " );
    printf( "%g\n", val );

sum += val;


printf( "\nTotal sum = %g\n", sum );

GetElemType

返回數組元素類型

int cvGetElemType( const CvArr* arr );
arr
輸入數組.

函數 GetElemType 返回數組元素類型就像在cvCreateMat 中討論的一樣:

CV_8UC1 ... CV_64FC4

GetDims, GetDimSize

返回數組維數和他們的大小或者特殊維的大小

int cvGetDims( const CvArr* arr, int* sizes=NULL );
int cvGetDimSize( const CvArr* arr, int index );
arr
輸入數組.
sizes
可選的輸出數組維尺寸向量,對於2D數組第一位是數組行數(高),第二位是數組列數(寬)
index
以0為基準的維索引下標(對於矩陣0意味著行數,1意味著列數,對於圖象0意味著高,1意味著寬。

函數 cvGetDims 返回維數和他們的大小。如果是 IplImage 或 CvMat 總是返回2,不管圖像/矩陣行數。函數 cvGetDimSize 返回特定的維大小(每維的元素數)。例如,接下來的代碼使用二種方法計算數組元素總數。

// via cvGetDims()
int sizes[CV_MAX_DIM];
int i, total = 1;
int dims = cvGetDims( arr, size );
for( i = 0; i < dims; i++ )
    total *= sizes[i];

// via cvGetDims() and cvGetDimSize()
int i, total = 1;
int dims = cvGetDims( arr );
for( i = 0; i < dims; i++ )
    total *= cvGetDimsSize( arr, i );

Ptr*D

返回指向特殊數組元素的指針

uchar* cvPtr1D( const CvArr* arr, int idx0, int* type=NULL );
uchar* cvPtr2D( const CvArr* arr, int idx0, int idx1, int* type=NULL );
uchar* cvPtr3D( const CvArr* arr, int idx0, int idx1, int idx2, int* type=NULL );
uchar* cvPtrND( const CvArr* arr, int* idx, int* type=NULL, int create_node=1, unsigned* precalc_hashval=NULL );
arr
輸入數組.
idx0
元素下標的第一個以0為基準的成員
idx1
元素下標的第二個以0為基準的成員
idx2
元素下標的第三個以0為基準的成員
idx
數組元素下標
type
可選的,矩陣元素類型輸出參數
create_node
可選的,為稀疏矩陣輸入的參數。如果這個參數非零就意味著被需要的元素如果不存在就會被創建。
precalc_hashval
可選的,為稀疏矩陣設置的輸入參數。如果這個指針非NULL,函數不會重新計算節點的HASH值,而是從指定位置獲取。這種方法有利於提高智能組合數據的操作(TODO: 提供了一個例子)

函數cvPtr*D 返回指向特殊數組元素的指針。數組維數應該與轉遞給函數物下標數相匹配,除了 cvPtr1D 函數,它可以被用於順序存取的1D,2D或nD密集數組

函數也可以用於稀疏數組,並且如果被需要的節點不存在函數可以創建這個節點並設置為0

就像其它獲取數組元素的函數 (cvGet[Real]*D, cvSet[Real]*D)如果元素的下標超出了範圍就會產生錯誤

Get*D

返回特殊的數組元素

CvScalar cvGet1D( const CvArr* arr, int idx0 );
CvScalar cvGet2D( const CvArr* arr, int idx0, int idx1 );
CvScalar cvGet3D( const CvArr* arr, int idx0, int idx1, int idx2 );
CvScalar cvGetND( const CvArr* arr, int* idx );
arr
輸入數組.
idx0
元素下標第一個以0為基準的成員
idx1
元素下標第二個以0為基準的成員
idx2
元素下標第三個以0為基準的成員
idx
元素下標數組

函數cvGet*D 返回指定的數組元素。對於稀疏數組如果需要的節點不存在函數返回0 (不會創建新的節點)

GetReal*D

返回單通道數組的指定元素

double cvGetReal1D( const CvArr* arr, int idx0 );
double cvGetReal2D( const CvArr* arr, int idx0, int idx1 );
double cvGetReal3D( const CvArr* arr, int idx0, int idx1, int idx2 );
double cvGetRealND( const CvArr* arr, int* idx );
arr
輸入數組,必須是單通道.
idx0
元素下標的第一個成員,以0為基準
idx1
元素下標的第二個成員,以0為基準
idx2
元素下標的第三個成員,以0為基準
idx
元素下標數組

函數cvGetReal*D 返回單通道數組的指定元素,如果數組是多通道的,就會產生運行時錯誤,而 cvGet*D 函數可以安全的被用於單通道和多通道數組,但他們運行時會有點慢

如果指定的點不存在對於稀疏數組點會返回0(不會創建新的節點)。

mGet

返回單通道浮點矩陣指定元素

double cvmGet( const CvMat* mat, int row, int col );
mat
輸入矩陣.
row
行下標,以0為基點.
col
列下標,以0為基點

函數 cvmGet 是 cvGetReal2D對於單通道浮點矩陣的快速替代函數,函數運行比較快速因為它是內連函數 ,這個函數對於數組類型、數組元素類型的檢查作的很少,並且僅在調式模式下檢查數的行和列範圍。

Set*D

修改指定的數組

void cvSet1D( CvArr* arr, int idx0, CvScalar value );
void cvSet2D( CvArr* arr, int idx0, int idx1, CvScalar value );
void cvSet3D( CvArr* arr, int idx0, int idx1, int idx2, CvScalar value );
void cvSetND( CvArr* arr, int* idx, CvScalar value );
arr
輸入數組
idx0
元素下標的第一個成員,以0為基點
idx1
元素下標的第二個成員,以0為基點
idx2
元素下標的第三個成員,以0為基點
idx
元素下標數組
value
指派的值

函數 cvSet*D 指定新的值給指定的數組元素。對於稀疏矩陣如果指定節點不存在函數創建新的節點

SetReal*D

修改指定數組元素值

void cvSetReal1D( CvArr* arr, int idx0, double value );
void cvSetReal2D( CvArr* arr, int idx0, int idx1, double value );
void cvSetReal3D( CvArr* arr, int idx0, int idx1, int idx2, double value );
void cvSetRealND( CvArr* arr, int* idx, double value );
arr
輸入數組.
idx0
元素下標的第一個成員,以0為基點
idx1
元素下標的第二個成員,以0為基點
idx2
元素下標的第三個成員,以0為基點
idx
元素下標數組
value
指派的值

函數 cvSetReal*D 分配新的值給單通道數組的指定元素,如果數組是多通道就會產生運行時錯誤。然而cvSet*D 可以安全的被用於多通道和單通道數組,只是稍微有點慢。

對於稀疏數組如果指定的節點不存在函數會創建該節點。

mSet

為單通道浮點矩陣的指定元素賦值。

void cvmSet( CvMat* mat, int row, int col, double value );
mat
矩陣.
row
行下標,以0為基點.
col
列下標,以0為基點.
value
矩陣元素的新值

函數cvmSet 是cvSetReal2D 快速替代,對於單通道浮點矩陣因為這個函數是內連的所以比較快,函數對於數組類型、數組元素類型的檢查作的很少,並且僅在調式模式下檢查數的行和列範圍。

ClearND

清除指定數組元素

void cvClearND( CvArr* arr, int* idx );
arr
輸入數組.
idx
數組元素下標

函數cvClearND 清除指定密集型數組的元素(置0)或刪除稀疏數組的元素 ,如果元素不存在函數不作任何事

拷貝和添加

Copy

拷貝一個數組給另一個數組

void cvCopy( const CvArr* src, CvArr* dst, const CvArr* mask=NULL );
src
輸入數組。
dst
輸出數組。
mask
操作掩碼是8比特單通道的數組,它指定了輸出數組中被改變的元素。
函數cvCopy從輸入數組中複製選定的成分到輸出數組:
如果mask(I)!=0,則dst(I)=src(I)。
如果輸入輸出數組中的一個是IplImage類型的話,其ROI和COI將被使用。輸入輸出數組必須是同樣的類型、維數和大小。函數也可以用來複制散列數組(這種情況下不支持mask)。

Set

設置數組所有元素為指定值

void cvSet( CvArr* arr, CvScalar value, const CvArr* mask=NULL );
arr
輸出數組。
value
填充值。
mask
操作掩碼是8比特單通道的數組,它指定了輸出數組中被改變的元素。

函數 cvSet 拷貝數量值到輸出數組的每一個被除數選定的元素:

arr(I)=value if mask(I)!=0

如果數組 arr 是 IplImage 類型, 那麼就會使用ROI,但COI不能設置。

SetZero

清空數組

void cvSetZero( CvArr* arr );
#define cvZero cvSetZero
arr
要被清空數組.

函數 cvSetZero 清空數組. 對於密集型號數組(CvMat, CvMatND or IplImage) cvZero(array) 就相當於 cvSet(array,cvScalarAll(0),0), 對於稀疏數組所有的元素都將被刪除.

SetIdentity

初始化帶尺度的單位矩陣

void cvSetIdentity( CvArr* mat, CvScalar value=cvRealScalar(1) );
mat
待初始化的矩陣 (不一定是方陣)。
value
賦值給對角線元素的值。

函數 cvSetIdentity 初始化帶尺度的單位矩陣:

arr(i,j)=value 如果 i=j,
否則為 0

Range

用指定範圍的數來填充矩陣.

void cvRange( CvArr* mat, double start, double end );
mat
即將被初始化的矩陣,必須是指向單通道的32位(整型或浮點型)的矩陣的指針.
start
指定範圍的最小邊界
end
指定範圍的最大邊界

該函數按以下方式初始化矩陣:

arr(i,j)=(end-start)*(i*cols(arr)+j)/(cols(arr)*rows(arr))

例如:以下的代碼將按相應的整型數初始化一維向量:

CvMat* A = cvCreateMat( 1, 10, CV_32S ); cvRange( A, 0, A->cols ); //A將被初始化為[0,1,2,3,4,5,6,7,8,9]

變換和置換

Reshape

不拷貝數據修改矩陣/圖像形狀

CvMat* cvReshape( const CvArr* arr, CvMat* header, int new_cn, int new_rows=0 );
arr
輸入的數組.
header
被添充的矩陣頭
new_cn
新的通道數.new_cn = 0 意味著不修改通道數
new_rows
新的行數. 如果new_rows = 0保持原行數不修改否則根據 new_cn 值修改輸出數組

函數 cvReshape 初始化 CvMat 頭header 以便於讓頭指向修改後的形狀(但數據保持原樣)-也就是說修改通道數,修改行數或者兩者者改變.

例如, 接下來的代碼創建一個圖像緩存、兩個圖像頭,第一個是 320x240x3 圖像第二個是 960x240x1 圖像:

IplImage* color_img = cvCreateImage( cvSize(320,240), IPL_DEPTH_8U, 3 );
CvMat gray_mat_hdr;
IplImage gray_img_hdr, *gray_img;
cvReshape( color_img, &gray_mat_hdr, 1 );
gray_img = cvGetImage( &gray_mat_hdr, &gray_img_hdr );

下一個例子轉換3x3 矩陣成單向量 1x9

CvMat* mat = cvCreateMat( 3, 3, CV_32F );
CvMat row_header, *row;
row = cvReshape( mat, &row_header, 0, 1 );

ReshapeMatND

修改多維數組形狀,拷貝/不拷貝數據

 CvArr* cvReshapeMatND( const CvArr* arr,
                        int sizeof_header, CvArr* header,
                        int new_cn, int new_dims, int* new_sizes );

#define cvReshapeND( arr, header, new_cn, new_dims, new_sizes )   \
        cvReshapeMatND( (arr), sizeof(*(header)), (header), \
                        (new_cn), (new_dims), (new_sizes))
arr
輸入數組
sizeof_header
輸出頭的大小,對於IplImage, CvMat 和 CvMatND 各種結構輸出的頭均是不同的.
header
被添充的輸出頭.
new_cn
新的通道數,如果new_cn = 0 則通道數保持原樣
new_dims
新的維數. 如果new_dims = 0 則維數保持原樣。
new_sizes
新的維大小.只有當 new_dims=1值被使用,因為要保持數組的總數一致,因此如果 new_dims = 1, new_sizes 是不被使用的

函數cvReshapeMatND 是 cvReshape 的高級版本,它可以處理多維數組(能夠處理通用的圖像和矩陣)並且修改維數,下麵的是使用cvReshapeMatND重寫 cvReshape的二個例子 :

IplImage* color_img = cvCreateImage( cvSize(320,240), IPL_DEPTH_8U, 3 );
IplImage gray_img_hdr, *gray_img;
gray_img = (IplImage*)cvReshapeND( color_img, &gray_img_hdr, 1, 0, 0 );

...

/*second example is modified to convert 2x2x2 array to 8x1 vector */
int size[] = { 2, 2, 2 };
CvMatND* mat = cvCreateMatND( 3, size, CV_32F );
CvMat row_header, *row;
row = cvReshapeND( mat, &row_header, 0, 1, 0 );

Repeat

用原數組管道式添充輸出數組

void cvRepeat( const CvArr* src, CvArr* dst );
src
輸入數組, 圖像或矩陣。
dst
輸出數組,圖像或矩陣

函數cvRepeat 使用被管道化的原數組添充輸出數組:

dst(i,j)=src(i mod rows(src), j mod cols(src))

因此 ,輸出數組可能小於也可能大於輸入數組.

Flip

垂直,水平或即垂直又水平翻轉二維數組

void  cvFlip( const CvArr* src, CvArr* dst=NULL, int flip_mode=0);
#define cvMirror cvFlip


src
原數組.
dst
目標責任制數組. 如果 dst = NULL 翻轉是在內部替換.
flip_mode
指定怎樣去翻轉數組。
flip_mode = 0 沿X-軸翻轉, flip_mode > 0 (如 1) 沿Y-軸翻轉, flip_mode < 0 (如 -1) 沿X-軸和Y-軸翻轉.見下麵的公式

函數cvFlip 以三種方式之一翻轉數組 (行和列下標是以0為基點的):

dst(i,j)=src(rows(src)-i-1,j) if flip_mode = 0
dst(i,j)=src(i,cols(src1)-j-1) if flip_mode > 0
dst(i,j)=src(rows(src)-i-1,cols(src)-j-1) if flip_mode < 0

函數主要使用在:

  • 垂直翻轉圖像(flip_mode = 0)用於 頂-左和底-左圖像結構的轉換, 主要用於WIN32系統下的視頻操作處理.
  • 水平圖像轉換,使用連續的水平轉換和絕對值差檢查垂直軸對稱(flip_mode > 0)
  • 水平和垂直同時轉換,用於連續的水平轉換和絕對真理值差檢查中心對稱s(flip_mode < 0)
  • 翻轉1維指針數組的順序(flip_mode > 0)

Split

分割多通道數組成幾個單通道數組或者從數組中提取一個通道

void cvSplit( const CvArr* src, CvArr* dst0, CvArr* dst1,
               CvArr* dst2, CvArr* dst3 );
#define cvCvtPixToPlane cvSplit
src
原數組.
dst0...dst3
目標通道

函數 cvSplit 分割多通道數組成分離的單通道數組d。可獲得兩種操作模式 . 如果原數組有N通道且前N輸出數組非NULL, 所有的通道都會被從原數組中提取,如果前N個通道只有一個通道非NULL函數只提取該指定通道,否則會產生一個錯誤,餘下的通道(超過前N個通道的以上的)必須被設置成NULL,對於設置了COI的IplImage 結使用cvCopy 也可以從圖像中提取單通道。

Merge

從幾個單通道數組組合成多通道數組或插入一個單通道數組

void cvMerge( const CvArr* src0, const CvArr* src1,
              const CvArr* src2, const CvArr* src3, CvArr* dst );
#define cvCvtPlaneToPix cvMerge
src0... src3
輸入的通道.
dst
輸出數組.

函數cvMerge 是前一個函數的反向操作。如果輸出數組有N個通道並且前N個輸入通道非NULL,就拷貝所有通道到輸出數組,如果在前N個通道中只有一個單通道非NULL ,只拷貝這個通道到輸出數組,否則 就會產生錯誤。除前N通道以外的餘下的通道必須置NULL。對於設置了COI的 IplImage結構使用 cvCopy也可以實現向圖像中插入一個通道 。

MixChannels

拷貝輸入數組的若幹個通道到輸出數組的某些通道上面.

void cvMixChannels( const CvArr** src, int src_count,
                   CvArr** dst, int dst_count,
                   const int* from_to, int pair_count );
src
輸入數組
src_count
輸入數組的個數
dst
輸出數組
dst_count
輸出數組的個數
from_to
對數的陣列
pair_count
from_to裡面的對數的個數,或者說被拷貝的位面的個數.

RandShuffle

隨機交換數組的元素

void cvRandShuffle( CvArr* mat, CvRNG* rng, double iter_factor=1.);
mat
輸入的矩陣,用來被隨機處理.
rng
隨機數產生器用來隨機交換數組元素.如果為NULL,一個當前的隨機數發生器將被創建與使用.
iter_factor
相關的參數,用來刻劃交換操作的密度.請看下麵的說明.

這個函數在每個反覆的操作中交換隨機選擇的矩陣裡面的元素(在多通道的數組裡面每個元素可能包括若幹個部分),反覆的次數(也就是交換的對數)等於round(iter_factor*rows(mat)*cols(mat)), 因此如果iter_factor=0,沒有交換產生,如果等於1意味著隨機交換了rows(mat)*cols(mat)對數.

算術,邏輯和比較

LUT

利用查找表轉換數組

void cvLUT( const CvArr* src, CvArr* dst, const CvArr* lut );
src
元素為8位的原數組。
dst
與原數組有相同通道數的輸出數組,深度不確定
lut
有256個元素的查找表;必須要與原輸出數組有相同像深 。

函數cvLUT 使用查找表中的值添充輸出數組. 坐標入口來自於原數組,也就是說函數處理每個元素按如下方式:

dst(I)=lut[src(I)+DELTA]

這裡當src的深度是CV_8U時DELTA=0 ,src的深度是CV_8S時 DELTA=128

ConvertScale

使用線性變換轉換數組

void cvConvertScale( const CvArr* src, CvArr* dst, double scale=1, double shift=0 );
#define cvCvtScale cvConvertScale
#define cvScale  cvConvertScale
#define cvConvert( src, dst )  cvConvertScale( (src), (dst), 1, 0 )
src
輸入數組.
dst
輸出數組
scale
比例因數.
shift
該加數被加到輸入數組元素按比例縮放後得到的元素上

函數 cvConvertScale 有多個不同的目的因此就有多個同義函數(如上面的#define所示)。 該函數首先對輸入數組的元素進行比例縮放,然後將shift加到比例縮放後得到的各元素上,即: dst(I)=src(I)*scale + (shift,shift,...),最後可選的類型轉換將結果拷貝到輸出數組。

多通道的數組對各個通道是獨立處理的。

類型轉換主要用舍入和溢出截斷來完成。也就是如果縮放+轉換後的結果值不能用輸出數組元素類型值精確表達,就設置成在輸出數組數據軸上最接近該數的值。

如果 scale=1, shift=0 且輸入數組和輸出數組類型相同,則不會進行比例縮放,相當於該函數的同義函數:cvConvert。 如果 scale=1, shift=0 且輸入數組和輸出數組類型不同,則cvConvertScale會根據兩種類型自動調整scale和shift,使得輸入數組類型區間中的任意值能夠映射到輸出數組的類型區間上。

ConvertScaleAbs

使用線性變換轉換輸入數組元素成8位無符號整型

void cvConvertScaleAbs( const CvArr* src, CvArr* dst, double scale=1, double shift=0 );
#define cvCvtScaleAbs cvConvertScaleAbs
src
原數組
dst
輸出數組 (深度為 8u).
scale
比例因數.
shift
原數組元素按比例縮放後添加的值。

函數 cvConvertScaleAbs 與前一函數是相同的,但它是存貯變換結果的絕對值:

dst(I)=abs(src(I)*scale + (shift,shift,...))

函數只支持目標數數組的深度為 8u (8-bit 無符號) , 對於別的類型函數仿效於cvConvertScale 和 cvAbs 函數的聯合

Add

計算兩個數組中每個元素的和

void cvAdd( const CvArr* src1, const CvArr* src2, CvArr* dst, const CvArr* mask=NULL );
src1
第一個原數組
src2
第二個原數組
dst
輸出數組
mask
操作的覆蓋面, 8-bit單通道數組; 只有覆蓋面指定的輸出數組被修改。

函數 cvAdd 加一個數組到別一個數組中:

dst(I)=src1(I)+src2(I) if mask(I)!=0

除覆蓋面外所有的數組必須有相同的類型相同的大小(或ROI尺寸)。

AddS

計算數量和數組的和

void cvAddS( const CvArr* src, CvScalar value, CvArr* dst, const CvArr* mask=NULL );
src
原數組.
value
被加入數量
dst
輸出數組
mask
操作的覆蓋面(8-bit單通道數組) ; 只有覆蓋面指定的輸出數組被修改

函數 cvAddS 用數量值與原數組src1的每個元素想加並存貯結果到

dst(I)=src(I)+value if mask(I)!=0

除覆蓋面外所有數組都必須有相同的類型,相同的大小(或ROI大小)

AddWeighted

計算兩數組的加權值的和

void  cvAddWeighted( const CvArr* src1, double alpha,
                     const CvArr* src2, double beta,
                     double gamma, CvArr* dst );
src1
第一個原數組.
alpha
第一個數組元素的權值
src2
第二個原數組
beta
第二個數組元素的權值
dst
輸出數組
gamma
添加的常數項。

函數 cvAddWeighted 計算兩數組的加權值的和:

dst(I)=src1(I)*alpha+src2(I)*beta+gamma

所有的數組必須有相同的類型相同的大小(或ROI大小)

Sub

計算兩個數組每個元素的差

void cvSub( const CvArr* src1, const CvArr* src2, CvArr* dst, const CvArr* mask=NULL );
src1
第一個原數組
src2
第二個原數組.
dst
輸出數組.
mask
操作覆蓋面( 8-bit 單通道數組); 只有覆蓋面指定的輸出數組被修改

函數cvSub 從一個數組減去別一個數組:

dst(I)=src1(I)-src2(I) if mask(I)!=0

除覆蓋面外所有數組都必須有相同的類型,相同的大小(或ROI大小)

SubS

計算數組和數量之間的差

void cvSubS( const CvArr* src, CvScalar value, CvArr* dst, const CvArr* mask=NULL );
src
原數組.
value
被減的數量.
dst
輸出數組.
mask
操作覆蓋面( 8-bit 單通道數組); 只有覆蓋面指定的輸出數組被修改

函數 cvSubS 從原數組的每個元素中減去一個數量:

dst(I)=src(I)-value if mask(I)!=0

除覆蓋面外所有數組都必須有相同的類型,相同的大小(或ROI大小)。

SubRS

計算數量和數組之間的差

void cvSubRS( const CvArr* src, CvScalar value, CvArr* dst, const CvArr* mask=NULL );
src
第一個原數組。
value
被減的數量
dst
輸出數組
mask
操作覆蓋面( 8-bit 單通道數組); 只有覆蓋面指定的輸出數組被修改

函數 cvSubRS 從一個數量減去原數組的每個元素:

dst(I)=value-src(I) if mask(I)!=0

除覆蓋面外所有數組都必須有相同的類型,相同的大小(或ROI大小)。

Mul

計算兩個數組中每個元素的積

void cvMul( const CvArr* src1, const CvArr* src2, CvArr* dst, double scale=1 );
src1
第一個原數組.
src2
第二個原數組.
dst
輸出數組.
scale
設置的比例因數

函數 cvMul 計算兩個數組中每個元素的積:

dst(I)=scale•src1(I)•src2(I)

所有的數組必須有相同的類型和相同的大小(或ROI大小)

Div

兩個數組每個元素相除

void cvDiv( const CvArr* src1, const CvArr* src2, CvArr* dst, double scale=1 );
src1
第一個原數組。如該指針為NULL,假高該數組的所有元素都為1
src2
第二個原數組。
dst
輸出數組
scale
設置的比例因數

函數 cvDiv 用一個數組除以另一個數組:

dst(I)=scale•src1(I)/src2(I), if src1!=NULL
dst(I)=scale/src2(I),:  if src1=NULL

所有的數組必須有相同的類型和相同的大小(或ROI大小)

And

計算兩個數組的每個元素的按位與

void cvAnd( const CvArr* src1, const CvArr* src2, CvArr* dst, const CvArr* mask=NULL );
src1
第一個原數組
src2
第二個原數組.
dst
輸出數組
mask
操作覆蓋面( 8-bit 單通道數組); 只有覆蓋面指定的輸出數組被修改

函數 cvAnd 計算兩個數組的每個元素的按位邏輯與:

dst(I)=src1(I)&src2(I) if mask(I)!=0

對浮點數組按位表示操作是很有利的。除覆蓋面,所有數組都必須有相同的類型,相同的大小(或ROI大小)。

AndS

計算數組每個元素與數量之間的按位與

void cvAndS( const CvArr* src, CvScalar value, CvArr* dst, const CvArr* mask=NULL );
src
原數組.
value
操作中用到的數量
dst
輸出數組
mask
操作覆蓋面( 8-bit 單通道數組); 只有覆蓋面指定的輸出數組被修改

函數 AndS 計算數組中每個元素與數量之量的按位與:

dst(I)=src(I)&value if mask(I)!=0

在實際操作之前首先把數量類型轉換成與數組相同的類型。對浮點數組按位表示操作是很有利的。除覆蓋面,所有數組都必須有相同的類型,相同的大小(或ROI大小)。

接下來的例子描述怎樣計算浮點數組元素的絕對值,通過清除最前面的符號位:

float a[] = { -1, 2, -3, 4, -5, 6, -7, 8, -9 };
CvMat A = cvMat( 3, 3, CV_32F, &a );
int i, abs_mask = 0x7fffffff;
cvAndS( &A, cvRealScalar(*(float*)&abs_mask), &A, 0 );
for( i = 0; i < 9; i++ )
    printf("%.1f ", a[i] );

代碼結果是:

1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0

Or

計算兩個數組每個元素的按位或

void cvOr( const CvArr* src1, const CvArr* src2, CvArr* dst, const CvArr* mask=NULL );
src1
第一個原數組
src2
第二個原數組
dst
輸出數組.
mask
操作覆蓋面( 8-bit 單通道數組); 只有覆蓋面指定的輸出數組被修改

函數 cvOr 計算兩個數組每個元素的按位或:

dst(I)=src1(I)|src2(I)

對浮點數組按位表示操作是很有利的。除覆蓋面,所有數組都必須有相同的類型,相同的大小(或ROI大小)。

OrS

計算數組中每個元素與數量之間的按位或

void cvOrS( const CvArr* src, CvScalar value, CvArr* dst, const CvArr* mask=NULL );
src1
原數組
value
操作中用到的數量
dst
目數組.
mask
操作覆蓋面( 8-bit 單通道數組); 只有覆蓋面指定的輸出數組被修改

函數 OrS 計算數組中每個元素和數量之間的按位或:

dst(I)=src(I)|value if mask(I)!=0

在實際操作之前首先把數量類型轉換成與數組相同的類型。對浮點數組按位表示操作是很有利的。除覆蓋面,所有數組都必須有相同的類型,相同的大小(或ROI大小)。

Xor

計算兩個數組中的每個元素的按位異或

void cvXor( const CvArr* src1, const CvArr* src2, CvArr* dst, const CvArr* mask=NULL );
src1
第一個原數組
src2
第二個原數組.
dst
輸出數組
mask
操作覆蓋面( 8-bit 單通道數組); 只有覆蓋面指定的輸出數組被修改

函數 cvXor 計算兩個數組元素的按位異或:

dst(I)=src1(I)\oplussrc2(I) if mask(I)!=0

對浮點數組按位表示操作是很有利的。除覆蓋面,所有數組都必須有相同的類型,相同的大小(或ROI大小)。

XorS

計算數組元素與數量之間的按位異或

void cvXorS( const CvArr* src, CvScalar value, CvArr* dst, const CvArr* mask=NULL );
src
原數組
value
操作中用到的數量
dst
輸出數組.
mask
操作覆蓋面( 8-bit 單通道數組); 只有覆蓋面指定的輸出數組被修改。

函數 XorS 計算數組元素與數量之間的按位異或:

dst(I)=src(I)\oplusvalue if mask(I)!=0

在實際操作之前首先把數量類型轉換成與數組相同的類型。對浮點數組按位表示操作是很有利的。除覆蓋面,所有數組都必須有相同的類型,相同的大小(或ROI大小)。

下麵例子描述怎樣對共軛複數向量轉換,通過轉換前面的符號位:

float a[] = { 1, 0, 0, 1, -1, 0, 0, -1 }; /* 1, j, -1, -j */
CvMat A = cvMat( 4, 1, CV_32FC2, &a );
int i, neg_mask = 0x80000000;
cvXorS( &A, cvScalar( 0, *(float*)&neg_mask, 0, 0 ), &A, 0 );
for( i = 0; i < 4; i++ )
    printf("(%.1f, %.1f) ", a[i*2], a[i*2+1] );

The code should print:

(1.0,0.0) (0.0,-1.0) (-1.0,0.0) (0.0,1.0)

Not

計算數組元素的按位取反

void cvNot( const CvArr* src, CvArr* dst );
src1
原數組
dst
輸出數組

函數不取反每個數組元素的每一位

dst(I)=~src(I)

Cmp

比較兩個數組元素P

void cvCmp( const CvArr* src1, const CvArr* src2, CvArr* dst, int cmp_op );
src1
第一個原數組
src2
第二個原數組,這兩個數組必須都是單通道數據。
dst
輸出數組必須是 8u 或 8s 類型.
cmp_op
該標識指定要檢查的元素之間的關係:
CV_CMP_EQ - src1(I) "等於" src2(I)
CV_CMP_GT - src1(I) "大於" src2(I)
CV_CMP_GE - src1(I) "大於等於" src2(I)
CV_CMP_LT - src1(I) "小於" src2(I)
CV_CMP_LE - src1(I) "小於等於" src2(I)
CV_CMP_NE - src1(I) "不等於" src2(I)

函數 cvCmp 比較兩個數組的對應元素並且添充輸出數組:

dst(I)=src1(I) op src2(I),

這裡 op 是 '=', '>', '>=', '<', '<=' or '!='.

如果元素之間的關係為真則設置dst(I)為 0xff (也就是所有的位都為 '1') 否則為0。除了輸出數組所有數組必須是相同的類型相同的大小(或ROI大小)。

CmpS

比較數組的每個元素與數量的關係

void cvCmpS( const CvArr* src, double value, CvArr* dst, int cmp_op );
src
原數,輸入數組必須是單通道數據。
value
用與數組元素比較的數量值
dst
輸出數組必須是 8u 或 8s 類型.
cmp_op
該標識指定要檢查的元素之間的關係:
CV_CMP_EQ - src1(I) "等於" value
CV_CMP_GT - src1(I) "大於" value
CV_CMP_GE - src1(I) "大於等於" value
CV_CMP_LT - src1(I) "小於" value
CV_CMP_LE - src1(I) "小於等於" value
CV_CMP_NE - src1(I) "不等於" value

函數 cvCmpS 比較數組元素與數量並且添充目標覆蓋面數組:

dst(I)=src(I) op scalar,

這裡 op 是 '=', '>', '>=', '<', '<=' or '!='.

如果元素之間的關係為真則設置dst(I)為 0xff (也就是所有的位都為 '1') 否則為0。所有的數組必須有相同的大小(或ROI大小)

InRange

檢查數組元素是否在兩個數組之間

void cvInRange( const CvArr* src, const CvArr* lower, const CvArr* upper, CvArr* dst );
src
第一個原數組
lower
包括進的下邊界數組
upper
不包括進的上邊界線數組
dst
輸出數組必須是 8u 或 8s 類型.

函數 cvInRange 對輸入的數組作範圍檢查,對於單通道數組:

dst(I)=lower(I)0 <= src(I)0 < upper(I)0

對二通道數組:

dst(I)=lower(I)0 <= src(I)0 < upper(I)0 &&
       lower(I)1 <= src(I)1 < upper(I)1

以此類推

如果 src(I) 在範圍內dst(I)被設置為 0xff (每一位都是 '1')否則置0 。 除了輸出數組所有數組必須是相同的類型相同的大小(或ROI大小)。

InRangeS

檢查數組元素是否在兩個數量之間

void cvInRangeS( const CvArr* src, CvScalar lower, CvScalar upper, CvArr* dst );
src
第一個原數組
lower
包括進的下邊界.
upper
不包括進的上邊界
dst
輸出數組必須是 8u 或 8s 類型.

函數 cvInRangeS 檢查輸入數組元素範圍: 對於單通道數組:

dst(I)=lower0 <= src(I)0 < upper0

對於雙通道數組以此類推:

dst(I)=lower0 <= src(I)0 < upper0 &&
       lower1 <= src(I)1 < upper1

如果 src(I) 在範圍內dst(I)被設置為 0xff (每一位都是 '1')否則置0 。所有的數組必須有相同的大小(或ROI大小)

Max

查找兩個數組中每個元素的較大值

void cvMax( const CvArr* src1, const CvArr* src2, CvArr* dst );
src1
第一個原數組
src2
第二個原數組
dst
輸出數組

函數 cvMax 計算兩個數組中每個元素的較大值:

dst(I)=max(src1(I), src2(I))

所有的數組必須的一個單通道,相同的數據類型和相同的大小(或ROI大小)

MaxS

查找數組元素與數量之間的較大值

void cvMaxS( const CvArr* src, double value, CvArr* dst );
src
第一個原數組.
value
數量值.
dst
輸出數組

函數 cvMaxS 計算數組元素和數量之間的較大值:

dst(I)=max(src(I), value)

所有數組必須有一個單一通道,相同的數據類型相同的大小(或ROI大小)

Min

查找兩個數組元素之間 的較小值

void cvMin( const CvArr* src1, const CvArr* src2, CvArr* dst );
src1
第一個原數組
src2
第二個原數組.
dst
輸出數組.

函數cvMin計算兩個數組元素的較小值

dst(I)=min(src1(I),src2(I))

所有數組必須有一個單一通道,相同的數據類型相同的大小(或ROI大小)

MinS

查找數組元素和數量之間的較小值

void cvMinS( const CvArr* src, double value, CvArr* dst );
src
第一個原數組
value
數量值.
dst
輸出數組..

函數 cvMinS 計算數組元素和數量之量的較小值:

dst(I)=min(src(I), value)

所有數組必須有一個單一通道,相同的數據類型相同的大小(或ROI大小)

AbsDiff

計算兩個數組差的絕對值

void cvAbsDiff( const CvArr* src1, const CvArr* src2, CvArr* dst );
src1
第一個原數組
src2
第二個原數組
dst
輸出數組

函數 cvAbsDiff 計算兩個數組差的絕對值

dst(I)c = abs(src1(I)c - src2(I)c).

所有數組必須有相同的數據類型相同的大小(或ROI大小)

 

AbsDiffS

計算數組元素與數量之間差的絕對值

void cvAbsDiffS( const CvArr* src, CvArr* dst, CvScalar value );
#define cvAbs(src, dst) cvAbsDiffS(src, dst, cvScalarAll(0))
src
原數組.
dst
輸出數組
value
數量.

函數 cvAbsDiffS 計算數組元素與數量之間差的絕對值

dst(I)c = abs(src(I)c - valuec).

所有數組必須有相同的數據類型相同的大小(或ROI大小)

統計

CountNonZero

計算非零數組元素個數

int cvCountNonZero( const CvArr* arr );
arr
數組, 必須是單通道數組或者設置COI(感興趣通道)的多通道圖像。

函數 cvCountNonZero 返回arr中非零元素的數目:

result = sumI arr(I)!=0

當IplImage 支持ROI和COI。

Sum

計算數組元素的和

CvScalar cvSum( const CvArr* arr );
arr
數組.

函數 cvSum 獨立地為每一個通道計算數組元素的和 S :

Sc = sumI arr(I)c

如果數組是IplImage類型和設置了COI, 該函數只處理選定的通道並將和存儲到第一個標量成員 (S0)。 常見論壇討論貼 cvSum的結果分析

Avg

計算數組元素的平均值

CvScalar cvAvg( const CvArr* arr, const CvArr* mask=NULL );
arr
數組.
mask
可選操作掩模

函數 cvAvg 獨立地為每一個通道計算數組元素的平均值 M :

N = \sum_i (\mbox{mask}(i) \neq 0)
M_c = \frac{1}{N} \sum_{i,\mbox{mask}(i) \neq 0} \mbox{arr}(i)_c

如果數組是 IplImage 類型和設置 COI , 該函數只處理選定的通道並將和存儲到第一個標量成員 (S0)。

AvgSdv

計算數組元素的平均值和標準差

void cvAvgSdv( const CvArr* arr, CvScalar* mean, CvScalar* std_dev, const CvArr* mask=NULL );
arr
數組
mean
指向平均值的指針, 如果不需要的話可以為空( NULL)。
std_dev
指向標準差的指針。
mask
可選操作掩模。

函數 cvAvgSdv 獨立地為每一個通道計算數組元素的平均值和標準差:

N = \sum_i (mask(i) \neq 0)
\mbox{mean}_c = \frac{1}{N} \sum_{i,\mbox{mask}(i) \neq 0} \mbox{arr}(i)_c
\mbox{std-dev}_c = \sqrt{ \frac{1}{N} \sum_{i,\mbox{mask}(i) \neq 0} (\mbox{arr}(i)_c - \mbox{mean}_c)^2}

如果數組是 IplImage 類型和 設置了COI ,該函數只處理選定的通道並將平均值和標準差存儲到第一個輸出標量成員 (mean0std-dev0)。

MinMaxLoc

查找數組和子數組的全局最小值和最大值

void cvMinMaxLoc( const CvArr* arr, double* min_val, double* max_val,
                  CvPoint* min_loc=NULL, CvPoint* max_loc=NULL, const CvArr* mask=NULL );
arr
輸入數組, 單通道或者設置了 COI 的多通道。
min_val
指向返回的最小值的指針。
max_val
指向返回的最大值的指針。
min_loc
指向返回的最小值的位置指針。
max_loc
指向返回的最大值的位置指針。
mask
選擇一個子數組的操作掩模。

函數 MinMaxLoc 查找元素中的最小值和最大值以及他們的位置。函數在整個數組、或選定的ROI區域(對IplImage)或當MASK不為NULL時指定的數組區域中,搜索極值 。如果數組不止一個通道,它就必須是設置了 COI 的 IplImage 類型。 如果是多維數組 min_loc->x 和 max_loc->x 將包含極值的原始位置信息 (線性的)。

Norm

計算數組的絕對範數, 絕對差分範數或者相對差分範數

double cvNorm( const CvArr* arr1, const CvArr* arr2=NULL, int norm_type=CV_L2, const CvArr* mask=NULL );
arr1
第一輸入圖像
arr2
第二輸入圖像 ,如果為空(NULL), 計算 arr1 的絕對範數,否則計算 arr1-arr2 的絕對範數或者相對範數。
normType
範數類型,參見“討論”。
mask
可選操作掩模。

如果 arr2 為空(NULL),函數 cvNorm 計算 arr1 的絕對範數:

norm = ||arr1||C = maxI abs(arr1(I)), 如果 normType = CV_C
norm = ||arr1||L1 = sumI abs(arr1(I)), 如果 normType = CV_L1
norm = ||arr1||L2 = sqrt( sumI arr1(I)2), 如果 normType = CV_L2


如果 arr2 不為空(NULL), 該函數計算絕對差分範數或者相對差分範數:

norm = ||arr1-arr2||C = maxI abs(arr1(I)-arr2(I)), 如果 normType = CV_C
norm = ||arr1-arr2||L1 = sumI abs(arr1(I)-arr2(I)), 如果 normType = CV_L1
norm = ||arr1-arr2||L2 = sqrt( sumI (arr1(I)-arr2(I))2 ), 如果 normType = CV_L2

或者

norm = ||arr1-arr2||C/||arr2||C, 如果 normType = CV_RELATIVE_C
norm = ||arr1-arr2||L1/||arr2||L1, 如果 normType = CV_RELATIVE_L1
norm = ||arr1-arr2||L2/||arr2||L2, 如果 normType = CV_RELATIVE_L2

函數 Norm 返回計算所得的範數。多通道數組被視為單通道處理,因此,所有通道的結果是結合在一起的。

Reduce

簡化一個矩陣成為一個向量

cvReduce( const CvArr* src, CvArr* dst, int dim, int op=CV_REDUCE_SUM);
src
輸入矩陣
dst
輸出的通過處理輸入矩陣的所有行/列而得到的單行/列向量
dim
矩陣被簡化後的維數索引.0意味著矩陣被處理成一行,1意味著矩陣被處理成為一列,-1時維數將根據輸出向量的大小自動選擇.
op
簡化操作的方式,可以有以下幾種取值:
CV_REDUCE_SUM-輸出是矩陣的所有行/列的和.
CV_REDUCE_AVG-輸出是矩陣的所有行/列的平均向量.
CV_REDUCE_MAX-輸出是矩陣的所有行/列的最大值.
CV_REDUCE_MIN-輸出是矩陣的所有行/列的最小值.

這個函數通過把矩陣的每行/列當作一維向量並對其做某種特殊的操作將一個矩陣簡化成為一個向量.例如,這個函數可以用於計算一個光柵圖象的水平或者垂直投影.在取值為CV_REDUCE_AVG與CV_REDUCE_SUM的情況下輸出可能有很大的位深度用於維持準確性,這兩種方式也適合於處理多通道數組.

註意,對於CV_REDUCE_SUM和CV_REDUCE_AVG方式來說,輸入和輸出的位數定義有如下關係

輸入:CV_8U 輸出:CV_32S CV_32F

輸入:CV_16U 輸出:CV_32F CV_64F

輸入:CV_16S 輸出:CV_32F CV_64F

輸入:CV_32F 輸出: CV_32F CV_64F

輸入:CV_64F 輸出: CV_64F

而對於CV_REDUCE_MAX和CV_REDUCE_MIN方式來說,輸入和輸出的位數必須一致

線性代數


DotProduct

用歐幾裡得準則計算兩個數組的點積

double cvDotProduct( const CvArr* src1, const CvArr* src2 );
src1
第一輸入數組。
src2
第二輸入數組。

函數 cvDotProduct 計算並返回兩個數組的歐幾裡得點積。

src1•src2 = sumI(src1(I)*src2(I))

如果是多通道數組,所有通道的結果是累加在一起的。特別地, cvDotProduct(a,a),將返回 ||a||2 ,這裡 a 是一個復向量。 該函數可以處理多通道數組,逐行或逐層等等。

Normalize

根據某種範數或者數值範圍歸一化數組.

void cvNormalize( const CvArr* src, CvArr* dst,
                 double a=1, double b=0, int norm_type=CV_L2,
                 const CvArr* mask=NULL );
src
輸入數組
dst
輸出數組,支持原地運算
a
輸出數組的最小/最大值或者輸出數組的範數
b
輸出數組的最大/最小值
norm_type
歸一化的類型,可以有以下的取值:
CV_C - 歸一化數組的C-範數(絕對值的最大值)
CV_L1 - 歸一化數組的L1-範數(絕對值的和)
CV_L2 - 歸一化數組的(歐幾里德)L2-範數
CV_MINMAX - 數組的數值被平移或縮放到一個指定的範圍
mask
操作掩膜,用於指示函數是否僅僅對指定的元素進行操作

該函數歸一化輸入數組使它的範數或者數值範圍在一定的範圍內

當norm_type==CV_MINMAX:

dst(i,j)=(src(i,j)-min(src))*(b'-a')/(max(src)-min(src)) + a', if mask(i,j)!=0

dst(i,j)=src(i,j) otherwise

其中b'=MAX(a,b), a'=MIN(a,b);

當norm_type!=CV_MINMAX:

dst(i,j)=src(i,j)*a/cvNorm(src,0,norm_type,mask), if mask(i,j)!=0

dst(i,j)=src(i,j) otherwise

下麵是一個簡單的例子: float v[3] = { 1, 2, 3 };

CvMat V = cvMat( 1, 3, CV_32F, v );

// make vector v unit-length;

// equivalent to

// for(int i=0;i<3;i++) v[i]/=sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2]);

cvNormalize( &V, &V );

CrossProduct

計算兩個三維向量的叉積

void cvCrossProduct( const CvArr* src1, const CvArr* src2, CvArr* dst );
src1
第一輸入向量。
src2
第二輸入向量。
dst
輸出向量

函數 cvCrossProduct 計算兩個三維向量的差積:

dst = src1 × src2, (dst1 = src12src23 - src13src22 , dst2 = src13src21 - src11src23 , dst3 = src11src22 - src12src21).

ScaleAdd

計算一個數組縮放後與另一個數組的和

void cvScaleAdd( const CvArr* src1, CvScalar scale, const CvArr* src2, CvArr* dst );
#define cvMulAddS cvScaleAdd
src1
第一輸入數組
scale
第一輸入數組的縮放因數
src2
第二輸入數組
dst
輸出數組

函數 cvScaleAdd 計算一個數組縮放後與另一個數組的和:

dst(I)=src1(I)*scale + src2(I)

所有的數組參數必須有相同的類型和大小。

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 點集的幾何變換,任意的線性顏色空間變換,通道轉換等。

PerspectiveTransform

向量數組的透視變換

void cvPerspectiveTransform( const CvArr* src, CvArr* dst, const CvMat* mat );
src
輸入的三通道浮點數組
dst
輸出三通道浮點數組
mat
4 × 4 變換矩陣

函數 cvPerspectiveTransform 用下麵的方式變換 src 的每一個元素 (通過將其視為二維或者三維的向量):

(x, y, z) -> (x'/w, y'/w, z'/w)

或者

(x, y) -> (x'/w, y'/w),

這裡

(x', y', z', w') = mat*(x, y, z, 1)

或者

(x', y', w') = mat*(x, y, 1)

並且 w = w' 如果 w'!=0, 否則 w = inf

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 方法可以解決):

\mbox{dst} = \arg \min_X |\mbox{src1}\cdot X-\mbox{src2}|

如果使用 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 分解成一個對角線矩陣和兩個正交矩陣的乘積:

\mathbf{\it A=U W V^T}

這裡 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)。

函數 cvCalcCovarMatrix 計算輸入向量的協方差矩陣和平均向量。該函數 可以被運用到主成分分析中(PCA),以及馬氏距離(Mahalanobis distance)比較向量中等等。

Mahalanobis

計算兩個向量之間的馬氏距離(Mahalanobis distance)

double cvMahalanobis( const CvArr* vec1, const CvArr* vec2, CvArr* mat );
vec1
第一個一維輸入向量
vec2
第二個一維輸入向量
mat
協方差矩陣的逆矩陣

函數 cvMahalanobis 計算兩個向量之間的加權距離,其返回結果是:

d(vec1,vec2)=\sqrt{ \sum_{i,j} \{mat(i,j)*(vec1(i)-vec2(i))*(vec1(j)-vec2(j))\} }

協方差矩陣可以用函數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.

數學函數

Round, Floor, Ceil

轉換浮點數為整數

int cvRound( double value );
int cvFloor( double value );
int cvCeil( double value );
value
輸入浮點值

函數 cvRound, cvFloor, cvCeil 用一種舍入方法將輸入浮點數轉換成整數。 cvRound 返回和參數最接近的整數值。 cvFloor 返回不大於參數的最大整數值。cvCeil 返回不小於參數的最小整數值。在某些體繫結構中該函數 工作起來比標準 C 操作起來還要快。如果參數的絕對值大於 231 ,結果是不可預料的。對特殊值 (±Inf, NaN) 未進行處理。

Sqrt

計算平方根

float cvSqrt( float value );
value
輸入浮點值

函數 cvSqrt 計算輸入值的平方根。如果輸入的是複數, 結果將不可預料。

InvSqrt

計算平方根的倒數

float cvInvSqrt( float value );
value
輸入浮點值

函數 cvInvSqrt 計算輸入值的平方根的倒數,大多數情況下它比 1./sqrt(value) 要快。 如果輸入的是 0 或者複數,結果將不可預料。特別值 (±Inf, NaN) 是不可控制的。

Cbrt

計算立方根

float cvCbrt( float value );
value
輸入浮點值

函數 cvCbrt 計算輸入值的立方根,大多數情況下它比 pow(value,1./3) 要快。 另外, 負數也是可操作的。特別值 (±Inf, NaN) 是不可控制的。

FastArctan

計算二維向量的角度

float cvFastArctan( float y, float x );
x
二維向量的 x 坐標
y
二維向量的 y 坐標

函數 cvFastArctan 計算二維向量的全範圍角度角度, 變化範圍是 0°到 360°。 精確度為 ~0.1° 。

IsNaN

判斷輸入是否是一個數字

int cvIsNaN( double value );
value
輸入浮點值

函數 cvIsNaN 發現輸入是一個數字則返回 1 ( IEEE754 標準 ),否則返回 0 。

IsInf

判斷輸入是否是無窮大

int cvIsInf( double value );
value
輸入浮點值

函數 cvIsInf 如果輸入是 ±Infinity ( IEEE754 標準 )則返回 1 ,否則返回 0 .

CartToPolar

計算二維向量的長度和/或者角度

void cvCartToPolar( const CvArr* x, const CvArr* y, CvArr* magnitude,
                    CvArr* angle=NULL, int angle_in_degrees=0 );
x
x 坐標數組
y
y 坐標數組
magnitude
存儲向量長度輸出數組, 如果不是必要的它可以為空(NULL)
angle
存儲角度輸出數組, 如果不是必要的它可以為空(NULL)。它可以被標準化為弧度 (0..2π) 或者度數(0..360°)

所有的數組只支持浮點類型的運算,也即x,y,magnitude,angle必須是浮點類型的數組。

angle_in_degrees
指示角度是用弧度或者度數表示的標誌,預設模式為弧度

函數 cvCartToPolar 計算二維向量(x(I),y(I))的長度,角度,或者兩者同時計算:

magnitude(I) = sqrt(x(I)2 + y(I)2),

angle(I) = atan(y(I) / x(I))

角度的精確度 ≈0.1°. (0,0) 點的角度被設置為 0.

(建議:英文文檔雖然是寫成atan( y(I)/x(I) ),但是建議和C中的表達方式統一。atan不能識別在那個象限,只能返回0-180°,atan2(x,y)才能返回0-360°的值)

PolarToCart

計算極坐標形式的二維向量對應的直角坐標

void cvPolarToCart( const CvArr* magnitude, const CvArr* angle,
                    CvArr* x, CvArr* y, int angle_in_degrees=0 );
magnitude
長度數組.如果為空(NULL),長度被假定為全是 1's.
angle
角度數組,弧度或者角度表示.
x
輸出 x 坐標數組, 如果不需要,可以為空(NULL).
y
輸出 y 坐標數組, 如果不需要,可以為空(NULL).
angle_in_degrees
指示角度是用弧度或者度數表示的標誌,預設模式為弧度

函數 cvPolarToCart 計算每個向量magnitude(I)*exp(angle(I)*j), j=sqrt(-1)的 x 坐標,y 坐標或者兩者都計算:

x(I)=magnitude(I)*cos(angle(I)),
y(I)=magnitude(I)*sin(angle(I))

Pow

對數組內每個元素求冪

void cvPow( const CvArr* src, CvArr* dst, double power );
src
輸入數組
dst
輸出數組, 應該和輸入數組有相同的類型
power
冪指數

函數 cvPow 計算輸入數組的每個元素的 p 次冪:

dst(I)=src(I)^p, 如果p是整數
否則dst(I)=abs(src(I))^p

也就是說,對於非整型的冪指數使用輸入數組元素的絕對值進行計算。然而,使用一些額外的操作,負值也可以得到正確的結果,象下麵的例子,計算數組元素的立方根:

CvSize size = cvGetSize(src);
CvMat* mask = cvCreateMat( size.height, size.width, CV_8UC1 );
cvCmpS( src, 0, mask, CV_CMP_LT ); /* 查找負數 */
cvPow( src, dst, 1./3 );
cvSubRS( dst, cvScalarAll(0), dst, mask ); /* 輸入的負值的結果求反 */
cvReleaseMat( &mask );

對於一些冪值, 例如整數值, 0.5 和 -0.5, 優化演算法被使用。

Exp

計算數組元素的指數冪

void cvExp( const CvArr* src, CvArr* dst );
src
輸入數組
dst
輸出數組, 它應該是 double 型的或者和輸入數組有相同的類型

函數 cvExp 計算輸入數組的每個元素的 e 次冪:

dst(I)=exp(src(I))

最大相對誤差為 ≈7e-6. 通常, 該函數轉換無法輸出的值為 0 輸出。

Log

計算每個數組元素的絕對值的自然對數

void cvLog( const CvArr* src, CvArr* dst );
src
輸入數組。
dst
輸出數組,它應該是 double 型的或者和輸入數組有相同的類型。

函數 cvLog 計算輸入數組每個元素的絕對值的自然對數:

dst(I)=log(abs(src(I))), src(I)!=0
dst(I)=C,  src(I)=0

這裡 C 是一個大負數 (≈-700 現在的實現中)。

SolveCubic

求解曲線函數的實根

void cvSolveCubic( const CvArr* coeffs, CvArr* roots );
coeffs
等式繫數, 一個三到四個元素的數組.
roots
輸出的矩陣等式的實根。它應該具有三個元素.

函數 cvSolveCubic 求解曲線函數的實根:

coeffs[0]*x^3 + coeffs[1]*x^2 + coeffs[2]*x + coeffs[3] = 0
(如果coeffs是四元素的矢量)

或者

x^3 + coeffs[0]*x^2 + coeffs[1]*x + coeffs[2] = 0
(如果coeffs是三元素的矢量)

函數返回求解得到的實根數目. 實根被存儲在矩陣root中, 如果只有一個實根則用0來替代相關值.

隨機數生成

RNG

初始化隨機數生成器狀態

CvRNG cvRNG( int64 seed=-1 );
seed
64-bit 的值用來初始化一個隨機序列

函數 cvRNG 初始化隨機數生成器並返回其狀態。指向這個狀態的指針可以傳遞給函數 cvRandInt, cvRandReal 和 cvRandArr . 在通常的實現中使用一個 multiply-with-carry generator 。

RandArr

用隨機數填充數組並更新 RNG 狀態

void cvRandArr( CvRNG* rng, CvArr* arr, int dist_type, CvScalar param1, CvScalar param2 );
rng
被 cvRNG 初始化的 RNG 狀態.
arr
輸出數組
dist_type
分佈類型:
CV_RAND_UNI - 均勻分佈
CV_RAND_NORMAL - 正態分佈 或者 高斯分佈
param1
分佈的第一個參數。如果是均勻分佈它是隨機數範圍的閉下邊界。如果是正態分佈它是隨機數的平均值。
param2
分佈的第二個參數。如果是均勻分佈它是隨機數範圍的開上邊界。如果是正態分佈它是隨機數的標準差。

函數 cvRandArr 用均勻分佈的或者正態分佈的隨機數填充輸出數組。在下麵的例子中該函數被用來添加一些正態分佈的浮點數到二維數組的隨機位置。

/* let's noisy_screen be the floating-point 2d array that is to be "crapped" */
CvRNG rng_state = cvRNG(0xffffffff);
int i, pointCount = 1000;
/* allocate the array of coordinates of points */
CvMat* locations = cvCreateMat( pointCount, 1, CV_32SC2 );
/* arr of random point values */
CvMat* values = cvCreateMat( pointCount, 1, CV_32FC1 );
CvSize size = cvGetSize( noisy_screen );

cvRandInit( &rng_state,
            0, 1, /* 現在使用虛參數以後再調整 */
            0xffffffff /*這裡使用一個確定的種子  */,
            CV_RAND_UNI /* 指定為均勻分佈類型 */ );

/* 初始化 locations */
cvRandArr( &rng_state, locations, CV_RAND_UNI, cvScalar(0,0,0,0), cvScalar(size.width,size.height,0,0) );

/* modify RNG to make it produce normally distributed values */
rng_state.disttype = CV_RAND_NORMAL;
cvRandSetRange( &rng_state,
                30 /* deviation */,
                100 /* average point brightness */,
                -1 /* initialize all the dimensions */ );
/* generate values */
cvRandArr( &rng_state, values, CV_RAND_NORMAL,
           cvRealScalar(100), // average intensity
           cvRealScalar(30) // deviation of the intensity
          );

/* set the points */
for( i = 0; i < pointCount; i++ )
{
    CvPoint pt = *(CvPoint*)cvPtr1D( locations, i, 0 );
    float value = *(float*)cvPtr1D( values, i, 0 );
    *((float*)cvPtr2D( noisy_screen, pt.y, pt.x, 0 )) += value;
}

/* not to forget to release the temporary arrays */
cvReleaseMat( &locations );
cvReleaseMat( &values );

/* RNG state does not need to be deallocated */

RandInt

返回 32-bit 無符號整型並更新 RNG

unsigned cvRandInt( CvRNG* rng );
rng
被 cvRNG 初始化的 RNG 狀態,被 RandSetRange (雖然, 後面這個函數對我們正討論的函數的結果沒有什麼影響)隨意地設置。

函數 cvRandInt 返回均勻分佈的隨機 32-bit 無符號整型值並更新 RNG 狀態。它和 C 運行庫裡面的 rand() 函數十分相似,但是它產生的總是一個 32-bit 數而 rand() 返回一個 0 到 RAND_MAX (它是 2**16 或者 2**32, 依賴於操作平臺)之間的數。

該函數用來產生一個標量隨機數,例如點, patch sizes, table indices 等,用模操作可以產生一個確定邊界的整數,人和其他特定的邊界縮放到 0.. 1可以產生一個浮點數。下麵是用 cvRandInt 重寫的前一個函數討論的例子:

/* the input and the task is the same as in the previous sample. */
CvRNG rng_state = cvRNG(0xffffffff);
int i, pointCount = 1000;
/* ... - no arrays are allocated here */
CvSize size = cvGetSize( noisy_screen );
/* make a buffer for normally distributed numbers to reduce call overhead */
#define bufferSize 16
float normalValueBuffer[bufferSize];
CvMat normalValueMat = cvMat( bufferSize, 1, CV_32F, normalValueBuffer );
int valuesLeft = 0;

for( i = 0; i < pointCount; i++ )
{
    CvPoint pt;
    /* generate random point */
    pt.x = cvRandInt( &rng_state ) % size.width;
    pt.y = cvRandInt( &rng_state ) % size.height;

    if( valuesLeft <= 0 )
    {   
        /* fulfill the buffer with normally distributed numbers if the buffer is empty */
        cvRandArr( &rng_state, &normalValueMat, CV_RAND_NORMAL, cvRealScalar(100), cvRealScalar(30) );
        valuesLeft = bufferSize;
    }
    ((float*)cvPtr2D( noisy_screen, pt.y, pt.x, 0 ) = normalValueBuffer[--valuesLeft];
}

/* there is no need to deallocate normalValueMat because we have
both the matrix header and the data on stack. It is a common and efficient
practice of working with small, fixed-size matrices */

RandReal

返回浮點型隨機數並更新 RNG

double cvRandReal( CvRNG* rng );
rng
被 cvRNG 初始化的 RNG 狀態

函數 cvRandReal 返回均勻分佈的隨機浮點數,範圍在 0..1 之間 (不包括 1 )。

離散變換

DFT

執行一維或者二維浮點數組的離散傅立葉正變換或者離散傅立葉逆變換

#define CV_DXT_FORWARD  0
#define CV_DXT_INVERSE  1
#define CV_DXT_SCALE:2
#define CV_DXT_ROWS: 4
#define CV_DXT_INV_SCALE (CV_DXT_SCALE|CV_DXT_INVERSE)
#define CV_DXT_INVERSE_SCALE CV_DXT_INV_SCALE
void cvDFT( const CvArr* src, CvArr* dst, int flags, int nonzero_rows=0);
src
輸入數組, 實數或者複數.
dst
輸出數組,和輸入數組有相同的類型和大小。
flags
變換標誌, 下麵的值的組合:
CV_DXT_FORWARD - 正向 1D 或者 2D 變換. 結果不被縮放.
CV_DXT_INVERSE - 逆向 1D 或者 2D 變換. 結果不被縮放.當然 CV_DXT_FORWARD 和 CV_DXT_INVERSE 是互斥的.
CV_DXT_SCALE - 對結果進行縮放: 用數組元素數除以它. 通常, 它和 CV_DXT_INVERSE 組合在一起,可以使用縮寫 CV_DXT_INV_SCALE.
CV_DXT_ROWS - 輸入矩陣的每個獨立的行進行整型或者逆向變換。這個標誌允許用戶同時變換多個向量,減少開銷(它往往比處理它自己要快好幾倍), 進行 3D 和高維的變換等等。
nonzero_rows
輸入矩陣中非0行的個數(在2維的Forward變換中),或者是輸出矩陣中感興趣的行(在反向的2維變換中)。如果這個值是負數,0,或者大於總行數的一個值,它將會被忽略。這個參數可以用來加速2維DFT/IDFT的速度。見下麵的例子。


函數 cvDFT 執行一維或者二維浮點數組的離散傅立葉正變換或者離散傅立葉逆變換:

N 元一維向量的正向傅立葉變換:
y = F(N)•x, 這裡 F(N)jk=exp(-i•2Pi•j•k/N), i=sqrt(-1)

y[k] =\sum_{n=0}^{N-1}x[n]e^{-i\frac{2\pi}{N} nk}           k=0,1,...N-1

N 元一維向量的逆向傅立葉變換:
x'= (F(N))-1•y = conj(F(N))•y
x = (1/N)•x
M×N 元二維向量的正向傅立葉變換:
Y = F(M)•X•F(N)
M×N 元二維向量的逆向傅立葉變換:
X'= conj(F(M))•Y•conj(F(N))
X = (1/(M•N))•X'

假設時實數數據 (單通道) ,從 IPL 借鑒過來的壓縮格式被用來表現一個正向傅立葉變換的結果或者逆向傅立葉變換的輸入:

Re Y0,0:  Re Y0,1:Im Y0,1:Re Y0,2: Im Y0,2  ...  Re Y0,N/2-1   Im Y0,N/2-1  Re Y0,N/2
Re Y1,0:  Re Y1,1:Im Y1,1:Re Y1,2: Im Y1,2  ...  Re Y1,N/2-1   Im Y1,N/2-1  Re Y1,N/2
Im Y1,0:  Re Y2,1:Im Y2,1:Re Y2,2: Im Y2,2  ...  Re Y2,N/2-1   Im Y2,N/2-1  Im Y2,N/2
............................................................................................
Re YM/2-1,0   Re YM-3,1   Im YM-3,1  Re YM-3,2   Im YM-3,2 ...  Re YM-3,N/2-1  Im YM-3,N/2-1 Re YM-3,N/2
Im YM/2-1,0   Re YM-2,1   Im YM-2,1  Re YM-2,2   Im YM-2,2 ...  Re YM-2,N/2-1  Im YM-2,N/2-1 Im YM-2,N/2
Re YM/2,0:Re YM-1,1   Im YM-1,1  Re YM-1,2   Im YM-1,2  ... Re YM-1,N/2-1  Im YM-1,N/2-1 Im YM-1,N/2

註意:如果 N 時偶數最後一列存在(is present), 如果 M 時偶數最後一行(is present).

如果是一維實數的變換結果就像上面矩陣的第一行的形式。 利用DFT求解二維捲積

   CvMat* A = cvCreateMat( M1, N1, CV_32F );
   CvMat* B = cvCreateMat( M2, N2, A->type );

   // it is also possible to have only abs(M2-M1)+1×abs(N2-N1)+1
   // part of the full convolution result
   CvMat* conv = cvCreateMat( A->rows + B->rows - 1, A->cols + B->cols - 1, A->type );

   // initialize A and B
   ...

   int dft_M = cvGetOptimalDFTSize( A->rows + B->rows - 1 );
   int dft_N = cvGetOptimalDFTSize( A->cols + B->cols - 1 );

   CvMat* dft_A = cvCreateMat( dft_M, dft_N, A->type );
   CvMat* dft_B = cvCreateMat( dft_M, dft_N, B->type );
   CvMat tmp;

   // copy A to dft_A and pad dft_A with zeros
   cvGetSubRect( dft_A, &tmp, cvRect(0,0,A->cols,A->rows));
   cvCopy( A, &tmp );
   cvGetSubRect( dft_A, &tmp, cvRect(A->cols,0,dft_A->cols - A->cols,A->rows));
   cvZero( &tmp );
   // no need to pad bottom part of dft_A with zeros because of
   // use nonzero_rows parameter in cvDFT() call below

   cvDFT( dft_A, dft_A, CV_DXT_FORWARD, A->rows );

   // repeat the same with the second array
   cvGetSubRect( dft_B, &tmp, cvRect(0,0,B->cols,B->rows));
   cvCopy( B, &tmp );
   cvGetSubRect( dft_B, &tmp, cvRect(B->cols,0,dft_B->cols - B->cols,B->rows));
   cvZero( &tmp );
   // no need to pad bottom part of dft_B with zeros because of
   // use nonzero_rows parameter in cvDFT() call below

   cvDFT( dft_B, dft_B, CV_DXT_FORWBRD, B->rows );

   cvMulSpectrums( dft_A, dft_B, dft_A, 0 /* or CV_DXT_MUL_CONJ to get correlation
::::::::::: rather than convolution */ );

   cvDFT( dft_A, dft_A, CV_DXT_INV_SCALE, conv->rows ); // calculate only the top part
   cvGetSubRect( dft_A, &tmp, cvRect(0,0,conv->cols,conv->rows) );

   cvCopy( &tmp, conv );

GetOptimalDFTSize

對於給定的矢量尺寸返回最優DFT尺寸

int cvGetOptimalDFTSize( int size0 );
size0
矢量長度.

函數 cvGetOptimalDFTSize 返回最小值 N that is greater to equal to size0, such that DFT of a vector of size N can be computed fast. In the current implementation N=2p×3q×5r for some p, q, r.

The function returns a negative number if size0 is too large (very close to INT_MAX)

MulSpectrums

兩個傅立葉頻譜的每個元素的乘法(Performs per-element multiplication of two Fourier spectrums)

void cvMulSpectrums( const CvArr* src1, const CvArr* src2, CvArr* dst, int flags );
src1
第一輸入數組
src2
第二輸入數組
dst
輸出數組,和輸入數組有相同的類型和大小。
flags
下麵列舉的值的組合:
CV_DXT_ROWS - 把數組的每一行視為一個單獨的頻譜 (參見 cvDFT 的參數討論).
CV_DXT_MUL_CONJ - 在做乘法之前取第二個輸入數組的共軛.

函數 cvMulSpectrums 執行兩個 CCS-packed 或者實數或複數傅立葉變換的結果複數矩陣的每個元素的乘法。(performs per-element multiplication of the two CCS-packed or complex matrices that are results of real or complex Fourier transform.)

該函數和 cvDFT 可以用來快速計算兩個數組的捲積.

DCT

執行一維或者二維浮點數組的離散餘弦變換或者離散反餘弦變換

#define CV_DXT_FORWARD  0
#define CV_DXT_INVERSE  1
#define CV_DXT_ROWS: 4
void cvDCT( const CvArr* src, CvArr* dst, int flags );
src
輸入數組, 1D 或者 2D 實數數組.
dst
輸出數組,和輸入數組有相同的類型和大小。
flags
變換標誌符, 下麵值的組合:
CV_DXT_FORWARD - 1D 或者 2D 餘弦變換.
CV_DXT_INVERSE - 1D or 2D 反餘弦變換.
CV_DXT_ROWS - 對輸入矩陣的每個獨立的行進行餘弦或者反餘弦變換. 這個標誌允許用戶同時進行多個向量的變換,可以用來減少開銷(它往往比處理它自己要快好幾倍),以及 3D 和高維變換等等。

函數 cvDCT 執行一維或者二維浮點數組的離散餘弦變換或者離散反餘弦變換:

N 元一維向量的餘弦變換:
y = C(N)•x, 這裡 C(N)jk=sqrt((j==0?1:2)/N)•cos(Pi•(2k+1)•j/N)
 y[m] =    \sum_{k=0}^{N-1} x_k \cos \left[\frac{\pi}{N} m \left(k+\frac{1}{2}\right) \right]
N 元一維向量的反餘弦變換:
x = (C(N))-1•y = (C(N))T•y
M×N 元二維向量的餘弦變換:
Y = (C(M))•X•(C(N))T
M×N 元二維向量的反餘弦變換:
X = (C(M))T•Y•C(N)
Views
個人工具