1 摘要
上一篇文章已經(jīng)介紹了矩陣類自己的方法伴逸,本章將會詳細介紹和矩陣運算相關的函數(shù)。下表簡單列舉了列舉了這些以矩陣為參數(shù)或者為返回值的函數(shù)。
參數(shù)method的取值 | 含義 |
---|---|
cv::abs() | 矩陣內(nèi)所有元素取絕對值并返回結果 |
cv::absdiff() | 計算兩個矩陣差值的絕對值并返回結果 |
cv::add() | 兩個矩陣逐元素相加 |
cv::addWeighted() | 兩個矩陣逐元素加權求和其骄,可以理解為Alpha混合 |
cv::bitwise_and() | 兩個矩陣逐元素按位與運算 |
cv::bitwise_not() | 兩個矩陣逐元素按位非運算 |
cv::bitwise_or() | 兩個矩陣逐元素按位或運算 |
cv::bitwise_xor() | 兩個矩陣逐元素按位異或運算 |
cv::calcCovarMatrix() | 計算一組n維向量的協(xié)方差 |
cv::cartToPolar() | 計算二維向量的角度和幅度 |
cv::checkRange() | 檢查矩陣的無效值 |
cv::compare() | 對兩個矩陣中的所有元素應用一個指定的比較運算符 |
cv::completeSymm() | 通過將一半元素復制到另一半使得矩陣對稱 |
cv::convertScaleAbs() | 縮放矩陣啃奴,取絕對值草则,然后將其中數(shù)據(jù)格式轉化為8位無符號型 |
cv::countNonZero() | 計算矩陣中的非零元素 |
cv::arrToMat() | 將2.1版本之前的數(shù)組轉化為cv::Mat的實例 |
cv::dct() | 計算矩陣的離散余弦變換 |
cv::determinant() | 計算方陣的行列式 |
cv::dft() | 計算矩陣的離散傅立葉變換 |
cv::divide() | 對兩個矩陣執(zhí)行逐元素除法運算 |
cv::eigen() | 計算方針的特征值和特征向量 |
cv::exp() | 對矩陣執(zhí)行逐元素求指數(shù)冪運算 |
cv::extractImageCOI() | 從2.1之前版本的數(shù)組中提取單個通道 |
cv::flip() | 繞指定軸翻轉矩陣 |
cv::gemm() | 執(zhí)行廣義的矩陣乘法 |
cv::getConvertElem() | 獲取單個像素的類型轉換函數(shù) |
cv::getConvertScaleElem() | 獲取單個像素的類型轉換和縮放函數(shù) |
cv::idct() | 計算矩陣的離散余弦逆變換 |
cv::idft() | 計算矩陣的離散傅立葉逆變換 |
cv::inRange() | 測試矩陣的元素是否包含在其他兩個矩陣的值之間 |
cv::invert() | 求方陣的逆 |
cv::log() | 逐元素計算自然對數(shù) |
cv::magnitude() | 計算二維向量的幅度 |
cv::LUT() | 將矩陣轉換為查找表的索引 |
cv::Mahalanobis() | 計算兩個向量之間的馬氏距離 |
cv::max() | 逐元素求兩個矩陣之間的最大值 |
cv::mean() | 計算矩陣元素的平均值 |
cv::meanStdDev() | 計算數(shù)組元素的均值和標準差 |
cv::merge() | 將多個單通道矩陣合并為一個多通道矩陣 |
cv::min() | 逐元素求兩個矩陣之間的最小值 |
cv::minMaxLoc() | 在矩陣中尋找最大和最小值 |
cv::mixChannels() | 打亂從輸入矩陣到輸出矩陣的通道 |
cv::mulSpectrums() | 對兩個傅立葉譜矩陣執(zhí)行逐元素乘法運算 |
cv::multiply() | 對兩個矩陣執(zhí)行逐元素乘法運算 |
cv::mulTransposed() | 計算矩陣和其轉置對逐元素乘積 |
cv::norm() | 在兩個矩陣之間計算歸一化相關系數(shù) |
cv::normalize() | 將矩陣中對元素標準化到某個值內(nèi) |
cv::perspectiveTransform() | 執(zhí)行一系列向量的透視矩陣變換 |
cv::phase() | 計算二維向量的方向 |
cv::polarToCart() | 已知角度和幅度钢拧,求二維向量 |
cv::pow() | 對矩陣內(nèi)對每個元素執(zhí)行冪運算 |
cv::randu() | 使用均勻分布的隨機數(shù)填充矩陣 |
cv::randn() | 使用正態(tài)分布的隨機數(shù)填充矩陣 |
cv::randShuffle() | 隨機打亂矩陣元素 |
cv::reduce() | 通過特定的操作將二維矩陣退化為向量 |
cv::repeat() | 將一個矩陣的內(nèi)容復制到另外一個矩陣 |
cv::saturate_cast<>() | 飽和轉換原始類型 |
cv::scaleAdd() | 逐元素的執(zhí)行矩陣加法,第一個矩陣可以選擇先執(zhí)行縮放操作 |
cv::setIdentity() | 將對角線上的元素設置為1炕横,其余元素設置為0 |
cv::solve() | 求出線性方程組的解 |
cv::solveCubic() | 計算三次方程的實根 |
cv::solvePoly() | 找到多項式方程的復根 |
cv::sort() | 排序矩陣中的任意行或者列的所有元素 |
cv::sortIdx() | 和函數(shù)cv::sort()類似源内,但是這里并不會修改矩陣本身,僅返回排序結果的索引值 |
cv::split() | 將多通道矩陣分解為多個單通道矩陣 |
cv::sqrt() | 逐元素計算矩陣的平方根 |
cv::subtract() | 逐元素對兩個矩陣執(zhí)行減法運算 |
cv::sum() | 計算數(shù)組所有元素的和 |
cv::theRNG() | 返回一個隨機數(shù)生成器 |
cv::trace() | 計算一個矩陣的跡 |
cv::transform() | 對矩陣的每個元素應用矩陣變換 |
cv::transpose() | 計算矩陣的轉置矩陣 |
上面所列舉的函數(shù)都遵循下面列舉的一些通用的規(guī)則份殿,特殊的場景會在函數(shù)的描述中注明膜钓。
飽和
輸出的計算結果會被飽和轉換至輸出矩陣的元素類型。
輸出
如果輸出矩陣的類型和尺寸不滿足要求伯铣,將會使用函數(shù)cv::Mat::create()
創(chuàng)建新的輸出矩陣實例呻此。通常情況下要求的輸出類型和尺寸和輸入矩陣相同,但是對于某些特殊的函數(shù)可能不同腔寡。如函數(shù)cv::transpose
返回的尺寸焚鲜,cv::split
函數(shù)返回的類型會發(fā)生改變。
標量
大多數(shù)如cv::add()
的計算函數(shù)都可以執(zhí)行矩陣和矩陣放前,以及矩陣和標量的計算忿磅。矩陣和標量的矩陣計算結果和使用該標量創(chuàng)建一個矩陣的計算結果相同。
掩碼
當一個函數(shù)存在掩碼參數(shù)時凭语,只有掩碼元素不為0對應位置的元素才會被計算葱她。
dtype
很多算法和相似的函數(shù)不會要求輸入矩陣具有相同的類型杏愤,或者即使它們具有相同的類型链瓦,輸出矩陣也可能是不同的類型。在這些場景下刁愿,輸出矩陣必須通過參數(shù)dtype
明確的制定它的深度炒辉。當函數(shù)或者算法中需要設置此參數(shù)時豪墅,它可以被設置為任何基礎數(shù)據(jù)類型,如CV_32F
黔寇,其規(guī)定了輸出矩陣中的基本數(shù)據(jù)類型偶器。如果輸入矩陣的類型相同,該參數(shù)可以設置為默認值-1缝裤,這樣輸出矩陣的數(shù)據(jù)類型就會和輸入矩陣保持一致屏轰。
原位操作
除非另有說明,任何輸入矩陣和輸出矩陣具有相同尺寸和類型的操作都結果直接寫入到輸入矩陣中憋飞。
多通道
對于不需要使用多通道的操作霎苗,如果存在多通道的參數(shù),則每個通道會被單獨處理搀崭。
2 函數(shù)清單
cv::abs()
該函數(shù)計算一個矩陣或者矩陣表達式的絕對值叨粘,最常使用的場景是計算矩陣中每個元素的絕對值猾编,該函數(shù)的原型如下。
cv::MatExpr cv::abs(cv::InputArray src);
// 以矩陣表達式作為參數(shù)
cv::MatExpr cv::abs(const cv::MatExpr& src);
該函數(shù)在處理矩陣參數(shù)和表達式參數(shù)時能夠恰當?shù)淖R別和處理一些特殊場景升敲,并轉化為cv::absDiff()
或者其他函數(shù)去處理具體的邏輯答倡。例如在處理下列場景時內(nèi)部會轉化為其他函數(shù)。
m2 = cv::abs(m0 - m1)
會被轉化為cv::absdiff(m0, m1, m2)
m2 = cv::abs(m0)
會被轉化為m2 = cv::absdiff(m0, cv::Scalar::all(0), m2)
m2 = cv::Mat_<Vec<uchar,n>>(cv::abs(alpha*m0 + beta))(alpha和beta為實數(shù))
會被轉化為cv::convertScaleAbs(m0, m2, alpha, beta)
第三個例子是計算一個n通道矩陣的縮放和平移結果驴党,如在校正圖像對比度時可能會使用到這個表達式瘪撇。在被函數(shù)cv::absdiff()
替代的實例中,計算的結果和輸入數(shù)組保持相同的大小和元素數(shù)據(jù)類型港庄,在被函數(shù)cv::convertScaleAbs()
替代的例子中倔既,計算結果的元素基本數(shù)據(jù)類型總為CV_U8
。
cv::absdiff()
該函數(shù)計算兩個矩陣中對應元素的差值鹏氧,并取其絕對值渤涌,將結果寫入到指定矩陣中,其原型如下把还。
// src1:被減矩陣
// src2:減矩陣
// dst:計算結果
void cv::absdiff(cv::InputArray src1, cv::InputArray src2, cv::OutputArray dst)
該函數(shù)會對結果進行飽和轉換实蓬,計算公式如下。
cv::add()
該函數(shù)計算兩個矩陣中對應元素的和吊履,并將結果寫入到指定矩陣中安皱,其原型如下。
// src1:第一個矩陣
// src2:第二個矩陣
// dot:計算結果
// mask:計算掩碼矩陣艇炎,可選參數(shù)酌伊,只有當掩碼對應元素不為0時,該位置對應的兩個輸入矩陣才會計算
// dtype:輸出矩陣的基本數(shù)據(jù)類型
void cv::add(cv::InputArray src1, cv::InputArray src2, cv::OutputArray dst,
cv::InputArray mask = cv::noArray(), int dtype = -1);
該函數(shù)會對結果進行飽和轉換缀踪,計算公式如下居砖。
需要注意的是對于一些簡單的運算可以直接使用表達式,OpenCV會調用合適的函數(shù)完成計算驴娃,如悯蝉。
// 簡單矩陣加法表達式
dst = src1 + src2;
dst += src1;
cv::addWeighted()
該函數(shù)是對兩個矩陣的加權求和,其原型如下托慨。
// src1: 第一個輸入矩陣
// alpha: 第一個輸入矩陣的權重
// src2: 第二個輸入矩陣
// beta: 第二個輸入矩陣的權重
// gamma: 計算結果的偏移值
// dst: 計算結果
// dtype: 輸出矩陣元素的數(shù)據(jù)類型
void cv::addWeighted(cv::InputArray src1, double alpha,
cv::InputArray src2, double beta,
double gamma, cv::OutputArray dst, int dtype = -1);
該函數(shù)的計算公式如下。
兩個源矩陣只要尺寸相同暇榴,它們中的元素可以有不同的數(shù)據(jù)類型厚棵,也可以有不同的通道數(shù),如一個是灰度圖蔼紧,而另一個是彩圖婆硬。該函數(shù)可以實現(xiàn)圖像透明度混合,即可以將上式中的γ設置為0奸例,并使β+α=1彬犯,則可以得到如下公式向楼。
函數(shù)cv::addWeighted()
非常靈活,通常將參數(shù)alpha
和beta
設置為大于等于0的數(shù)谐区,參數(shù)gamma
的設置通常取決于圖像像素的平均值或者最大值湖蜕。下面展示了一個實現(xiàn)了圖像透明度混合實例的部分核心代碼。
// 圖像Src1的數(shù)據(jù)會被混合到圖像Src2指定中
cv::Mat src = cv::imread(..., cv::IMREAD_COLOR);
cv::Mat dst = cv::imread(..., cv::IMREAD_COLOR);
// 獲取在Src2中混合的起點位置
int x = ...;
int y = ...;
// 獲取混合的參數(shù)
double alpha = ...;
double beta = ...;
// 混合圖像
cv::Mat target = cv::Mat(dst, cv::Rect(x, y, src_w, src_h));
cv::addWeighted(src, alpha, target, beta, 0, target);
上面的代碼讀取了兩張圖像src1和src2宋列,并分別從它們之重選取了部分數(shù)據(jù)進行混合昭抒,并展示混合后的圖像src2,其效果如下圖炼杖。
cv::bitwise_and()
該函數(shù)逐元素對兩個矩陣執(zhí)行位與運算灭返,其原型如下。
// src1: 第一個輸入矩陣
// src2: 第二個輸入矩陣
// dst:計算結果
// mask:計算掩碼矩陣坤邪,可選參數(shù)熙含,只有當掩碼對應元素不為0時,該位置對應的兩個輸入矩陣才會計算
void cv::bitwise_and(cv::InputArray src1, cv::InputArray src2, cv::OutputArray dst,
cv::InputArray mask = cv::noArray());
如果不使用掩碼矩陣艇纺,執(zhí)行兩個矩陣的位與計算可以直接使用如下表達式怎静。
dst = src1 & src2;
cv::bitwise_not()
該函數(shù)逐元素對某個矩陣執(zhí)行位非運算,其原型如下喂饥。
// src: 輸入矩陣
// dst:計算結果
// mask:計算掩碼矩陣消约,可選參數(shù),只有當掩碼對應元素不為0時员帮,該位置對應的兩個輸入矩陣才會計算
void cv::bitwise_not(cv::InputArray src, cv::OutputArray dst,
cv::InputArray mask = cv::noArray());
如果不使用掩碼矩陣或粮,對一個矩陣執(zhí)行逐元素的位非運算可以直接使用如下表達式。
dst = !src1;
cv::bitwise_or()
該函數(shù)逐元素對兩個矩陣執(zhí)行位或運算捞高,其原型如下氯材。
// src1: 第一個輸入矩陣
// src2: 第二個輸入矩陣
// dst:計算結果
// mask:計算掩碼矩陣,可選參數(shù)硝岗,只有當掩碼對應元素不為0時氢哮,該位置對應的兩個輸入矩陣才會計算
void cv::bitwise_and(cv::InputArray src1, cv::InputArray src2,
cv::OutputArray dst, cv::InputArray mask = cv::noArray());
如果不使用掩碼矩陣,執(zhí)行兩個矩陣的位或計算可以直接使用如下表達式型檀。
dst = src1 | src2;
cv::bitwise_xor()
該函數(shù)逐元素對兩個矩陣執(zhí)行位異或運算冗尤,其原型如下。
// src1: 第一個輸入矩陣
// src2: 第二個輸入矩陣
// dst:計算結果
// mask:計算掩碼矩陣胀溺,可選參數(shù)裂七,只有當掩碼對應元素不為0時,該位置對應的兩個輸入矩陣才會計算
void cv::bitwise_and(cv::InputArray src1, cv::InputArray src2, cv::OutputArray dst,
cv::InputArray mask = cv::noArray());
如果不使用掩碼矩陣仓坞,執(zhí)行兩個矩陣的位異或計算可以直接使用如下表達式背零。
dst = src1 ^ src2;
cv::calcCovarMatrix()
對于一個由n維向量組成的矩陣,假設每個向量表示一組隨機變量无埃,每組變量的個數(shù)都為m徙瓶,則這n個隨機變量的協(xié)方差矩陣可以由下面兩個函數(shù)求出毛雇。兩組隨機變量的協(xié)方差可以理解為是這兩組變量在統(tǒng)計學上分布的相似程度,而n組變量的任意兩組變量的協(xié)方差則構成了一個協(xié)方差矩陣侦镇。如果不熟悉協(xié)方差矩陣的數(shù)學概念灵疮,可以參考協(xié)方差矩陣。函數(shù)原型如下虽缕。
// samples:n*1或者1*n的原始樣本矩陣的地址
// nsamples:樣本數(shù)
// covar:計算得到的協(xié)方差矩陣的引用
// mean:均值矩陣的引用
// flags:計算時采用的策略始藕,具體見下表
// ctype:輸出矩陣中元素的基本數(shù)據(jù)類型
void cv::calcCovarMatrix(const cv::Mat* samples, int nsamples,
cv::Mat& covar, cv::Mat& mean,
int flags, int ctype = cv::F64);
// samples:n*m的原始樣本矩陣
// 其他參數(shù)和上面函數(shù)含義一致
void cv::calcCovarMatrix(cv::InputArray samples,
cv::Mat& covar, cv::Mat& mean,
int flags, int ctype = cv::F64);
該函數(shù)可以通過參數(shù)flags
自定義計算策略,該參數(shù)所有可選的值及其含義如下表氮趋,除了特殊情況外可以使用與運算符啟用多個標志伍派。
參數(shù)flags的取值 | 含義 |
---|---|
cv::COVAR_NORMAL | 計算均值和協(xié)方差矩陣 |
cv::COVAR_SCRAMBLED | 使用快速PCA “scrambled”策略計算協(xié)方差矩陣 |
cv::COVAR_USE_AVERAGE | 參數(shù)mean作為輸入?yún)?shù)使用,不會計算均值矩陣 |
cv::COVAR_SCALE | 縮放協(xié)方差矩陣計算結果 |
cv::COVAR_ROWS | 將每行數(shù)據(jù)看成時一個向量剩胁,即一組隨機變量 |
cv::COVAR_COLS | 將每列數(shù)據(jù)看成時一個向量诉植,即一組隨機變量 |
需要注意參數(shù)flags
的cv::COVAR_NORMAL
和cv::COVAR_SCRAMBLED
選項是互斥的,在選擇cv::COVAR_NORMAL
和cv::COVAR_ROWS
的情況下昵观,協(xié)方差矩陣的計算公式如下晾腔。其中vmn
表示原始樣本第n行m列元素。vn表示第n個向量即第n組隨機變量的均值啊犬。z是計算結果的縮放系數(shù)灼擂,當cv::COVAR_SCALE
標記未啟用時,其值為1觉至。計算結果將會時一個n??n的矩陣剔应。
如果選擇cv::COVAR_SCRAMBLED
和cv::COVAR_ROWS
,協(xié)方差矩陣的計算公式如下语御。注意在這個計算公式中峻贮,矩陣的轉置運算符被放到了第一個矩陣之上,對于同樣的n??m矩陣应闯,計算得到的是尺寸為m??m協(xié)方差矩陣纤控。在一些特定場景下,如對向量元素較長的樣本數(shù)據(jù)計算快速主成分分析(PCA)時會使用這種技術碉纺,一個應用實例就是人臉識別的特征臉算法船万。
當已知多維向量的均值向量時,參數(shù)flags
可以選擇cv::COVAR_USE_AVERAGE
從而減少計算時間骨田。對于n行??m列的輸入樣本矩陣而言唬涧,當設置cv::COVAR_SCALE
時,計算的協(xié)方差矩陣會被縮放盛撑,縮放系數(shù)等于1.0/m,但是當cv::COVAR_SCRAMBLED
被啟用時捧搞,縮放系數(shù)則等于1.0/n抵卫,可以理解為1/單組隨機變量個長度狮荔。
該函數(shù)的輸入輸出函數(shù)中元素的基本數(shù)據(jù)類型都應該是相同的浮點數(shù)類型,協(xié)方差矩陣的尺寸根據(jù)選擇的是標準cv::COVAR_NORMAL
還是反轉cv::COVAR_SCRAMBLED
的計算策略相應為n??n和m??m介粘。
cv::cartToPolar()
該函數(shù)原型如下殖氏,它讀取兩個輸入矩陣x和y,將其中對應的元素組成一個點Point(x, y)姻采,并計算該點的極坐標表示雅采,將其幅度(長度)和角度分別放在輸出矩陣magnitude
和angle
中。參數(shù)angleInDegrees
表示返回的角度矩陣單位慨亲,ture
表示角度婚瓜,false
表示弧度。
// x:第一個輸入矩陣
// y:第二個輸入矩陣
// magnitude:幅度矩陣
// angle:角度/弧度矩陣
// angleInDegrees:角度矩陣的單位刑棵,ture表示角度巴刻,false表示弧度
void cv::cartToPolar(cv::InputArray x, cv::InputArray y,
cv::OutputArray magnitude, cv::OutputArray angle,
bool angleInDegrees = false);
幅度計算公式如下。
角度計算公式如下蛉签。
cv::checkRange()
該函數(shù)測試輸入矩陣中的每個元素是否位于指定的范圍之內(nèi)胡陪,其原型如下。需要注意的是任何NaN或者inf值會直接被判定為超出指定范圍碍舍。
// src:待測試矩陣
// quiet:某個元素不在指定范圍內(nèi)是否拋出異常柠座,Yes不會拋出異常,No會
// pos:用于存儲第一個越界元素位置的地址
// minVal:指定范圍最小值
// maxVal:指定范圍最大值
// 返回值:是否所有元素都在指定范圍內(nèi)片橡,所有元素都在返回true妈经,任一個不在返回false
bool cv::checkRange(cv::InputArray src, bool quiet = true, cv::Point* pos = 0,
double minVal = -DBL_MAX, double maxVal = DBL_MAX);
cv::compare()
該函數(shù)采用特定的運算符比較兩個輸入矩陣,其原型如下锻全。輸出矩陣dst
中元素的基本數(shù)據(jù)類型為8位序列狂塘,如果符合比較條件將被設置為255,不符合將被設置為0鳄厌。
// src1:第一個輸入矩陣
// src2:第二個輸入矩陣
// dst:比較結果矩陣
// cmpop:比較策略荞胡,可選值見下文
bool cv::compare(cv::InputArray src1, cv::InputArray src2,
cv::OutputArray dst, int cmpop);
比較策略即參數(shù)cmpop的可選擇值及其含義如下表。
參數(shù)cmpop的取值 | 比較運算符 |
---|---|
cv::CMP_EQ | (src1i == src2i) |
cv::CMP_GT | (src1i > src2i) |
cv::CMP_GE | (src1i >= src2i) |
cv::CMP_LT | (src1i < src2i) |
cv::CMP_LE | (src1i <= src2i) |
cv::CMP_NE | (src1i != src2i) |
另外你也可以直接使用運算符來完成相同的計算了嚎。
dst = src1 == src2;
dst = src1 > src2;
dst = src1 >= src2;
dst = src1 < src2;
dst = src1 <= src2;
dst = src1 != src2;
cv::completeSymm()
該函數(shù)沿著矩陣對角線將一半元素拷貝到其對應的轉置位置泪漂,從而使得整個矩陣對稱,其原型如下歪泳。
// mtx:需要處理的矩陣
// lowerToUpper:矩陣拷貝的方式萝勤,true表示將上三角拷貝至下三角,false則相反
bool cv::completeSymm(cv::InputArray mtx, bool lowerToUpper = false);
cv::convertScaleAbs()
該函數(shù)是一系列操作的集合呐伞,它首先縮放原始矩陣敌卓,再施加一個偏移量,再求其絕對值伶氢,之后將結果飽和轉換為8位無符號字符型數(shù)據(jù)趟径,其原型如下瘪吏。
// src:元素矩陣
// dst:輸出矩陣
// alpha:縮放因子
// beta:偏移量
void cv::convertScaleAbs(cv::InputArray src, cv::OutputArray dst,
double alpha = 1.0, double beta = 0.0);
需要注意的是,當參數(shù)alpha
設置為1.0蜗巧,或者參數(shù)beta
設置為0掌眠。0時不需要為性能擔憂充易,OpenCV是很智能的垦细,它不會去執(zhí)行無用的運算波势。另外為了通用性考量汉形,可以使用如下方式實現(xiàn)同樣的計算邏輯控漠。
for(int i = 0; i < src.rows; i++) {
for(int j = 0; j < src.cols*src.channels(); j++) {
dst.at<dst_type>(i, j) = satuarate_cast<dst_type>((double)src.at<src_type>(i, j) * alpha + beta);
}
}
cv::countNonZero()
該函數(shù)計算矩陣中非零元素的個數(shù)嘀韧,其原型如下带到。
// mtx:輸入矩陣
// 返回值:輸入矩陣中非零元素的個數(shù)
int cv::countNonZero(cv::InputArray mtx);
cv::cvarrToMat()
該函數(shù)用于將OpenCV2.1版本之前的圖像和矩陣類型轉化為cv::Mat
實例缚柳,默認情況下靠娱,該函數(shù)只會創(chuàng)建矩陣頭沧烈,并不會去拷貝真正的數(shù)據(jù)段,因此在使用cv::Mat
實例時不要釋放老版本指向的數(shù)據(jù)段像云。參數(shù)copyData
設置為true
會拷貝原始的數(shù)據(jù)锌雀。該函數(shù)原型如下。
// src:老版本的數(shù)組實例迅诬,如CvMat腋逆,IplImage或者CvMatND
// copyData:是否需要拷貝數(shù)據(jù)段內(nèi)容
// allowND:是否允許嘗試轉換CvMatND實例
// coiMode:興趣通道模式
// 該值為0時如果設置了興趣通道則COI會拋出異常
// 如果為非零值,則忽略興趣通道直接處理整個圖像
cv::Mat cv::cvarrToMat(const CvArr* src, bool copyData = false,
bool allowND = true, int coiMode = 0);
該函數(shù)并不能轉換所有的CvMatND
實例侈贷,成功的關鍵在于矩陣是否連線惩歉,或者至少能夠被表示為連續(xù)矩陣的序列。具體的將就是對于所有的i俏蛮,或者在最壞情況下除一個i
之外撑蚌,A.dim[i].size??A.dim.step[i]
的值都應該等于A.dim.step[i-1]
。如果參數(shù)allowND
的值為true
搏屑,則該函數(shù)會嘗試處理CvMatND
實例争涌,如果失敗會拋出異常。如果allowND
的值為false
辣恋,參數(shù)src
為CvMatND
實例亮垫,則該函數(shù)會直接拋出異常。另外如果你缺失需要處理老版本中的興趣通道COI
伟骨,你可以使用函數(shù)cv::extractImageCOI()
單獨為這個感興趣的像素通道創(chuàng)建新版本矩陣實例饮潦。
此外有時我們還需要將新版本實例轉化為老版本的變量,將cv::Mat
實例轉換為老版本的IplImage *
變量的方法如下携狭。
Cv::Mat A( 640, 480, cv::U8C3 );
// casting is implicit on assignment
IplImage.my_img = A;
iplImage* img = &my_img;
cv::dct()
該函數(shù)求原始矩陣的離散余弦變換或者離散余弦逆變換继蜡,其原型如下。該函數(shù)和一般的離散變換會在后文中會詳細介紹,這里暫時先不用理解其原理和應用場景稀并。
// src:輸入矩陣鲫剿,必須是一維或者二維,向量長度必須是偶數(shù)稻轨,必要時可以填充數(shù)據(jù)
// dst:計算結果,和輸入矩陣具有相同的尺寸
// flags:計算策略
// 可選值為DCT_INVERSE和DCT_ROWS雕凹,可以使用邏輯與符號同時選擇
// DCT_INVERSE表示執(zhí)行逆變換
// DCT_ROWS表示將矩陣視為n個一維行向量單獨計算而不是二維向量整體計算
void cv::dct(cv::InputArray src, cv::OutputArray dst, int flags);
該函數(shù)的效率和輸入矩陣的尺寸密切相關殴俱,但是并不是一種單調關系。建議在使用該函數(shù)時枚抵,先使用函數(shù)cv::getOptimalDFTSize()
獲取到比輸入數(shù)組更大的高效尺寸线欲,并將輸入數(shù)組擴展到這個大小。該函數(shù)在計算長度為n向量的離散余弦變換/逆變換時會依賴于n/2長度向量的離散傅立葉變換汽摹,因此正確的最佳輸入矩陣尺寸計算方式如下李丰。
size_t opt_dft_size = 2 * cv::getOptimalDFTSize((N+1)/2);
cv::dft()
該函數(shù)求原始矩陣的離散傅立葉變換或者離散傅立葉逆變換,其原型如下逼泣。該函數(shù)和離散傅立葉變換背后的數(shù)學知識會在后文中會詳細介紹趴泌,這里暫時先不用理解其原理和應用場景。
// src:輸入矩陣拉庶,必須是一維或者二維
// dst:計算結果矩陣嗜憔,和輸入矩陣具有相同的尺寸
// flags:計算策略標記
// nonzeroRows:有意義的行數(shù)
void cv::dft(cv::InputArray src, cv::OutputArray dst,
int flags = 0, int nonzeroRows = 0);
通過設置參數(shù)flag時可以自定義計算過程,其可選值有DFT_INVERSE
氏仗、DFT_ROWS吉捶、DFT_SCALE
、DFT_COMPLEX_OUTPUT
和DFT_REAL_OUTPUT
皆尔,可以使用邏輯與符號組合多個策略呐舔。DCT_INVERSE
表示執(zhí)行逆變換。DCT_ROWS
表示將矩陣視為n個一維行向量單獨計算而不是二維向量整體計算慷蠕。DFT_SCALE
表示將計算結果除以矩陣的元素數(shù)量從而標準化數(shù)據(jù)珊拼。DFT_SCALE
通常和DFT_INVERSE
同時使用。因為這樣保證了在計算逆的逆時將具有正確的標準化結果砌们。
DFT_COMPLEX_OUTPUT
和DFT_REAL_OUTPUT
非常有用杆麸,因為實數(shù)矩陣的傅立葉變換結果具有復數(shù)共軛對稱性。因此即使得到的結果是復數(shù)浪感,結果矩陣仍然和輸入矩陣具有相同的元素個數(shù)昔头,而不是它的兩倍。這種包裝是函數(shù)cv::dft()
的默認行為影兽,如果想要強制輸出復數(shù)結果揭斧,則需要設置DFT_COMPLEX_OUTPUT
標記。在計算離散傅立葉逆變換時,通常輸入矩陣是復數(shù)矩陣讹开,而輸出結果也是復數(shù)矩陣盅视,但是如果輸入矩陣具有復數(shù)共軛對稱性,或者說它就是實數(shù)矩陣計算離散傅立葉變換的結果旦万,則其逆變換的結果也是一個實數(shù)矩陣闹击。如果你在計算逆變換時能夠確定輸入矩陣的這種復數(shù)共軛對稱性,并且你希望得到一個實數(shù)矩陣以其減少一半的內(nèi)存使用量成艘,則你可以設置DFT_REAL_OUTPUT
標記赏半。需要注意的是設置DFT_REAL_OUTPUT
標記后,函數(shù)cv::dft()
并不會真正去檢查輸入矩陣具有復數(shù)共軛對稱性淆两,僅僅只是假定其有這種性質断箫。
參數(shù)nonzeroRows
在被設置為非0值m時,如果執(zhí)行離散傅立葉變換秋冰,則該函數(shù)會認為只有前m行是有意義的仲义,如果執(zhí)行離散傅立葉逆變換,則認為輸出矩陣的前m行是非0的剑勾。該標記在計算卷積相關性時特別方便埃撵。
同樣的,該函數(shù)的性能和輸入矩陣的尺寸密切相關甥材,并且這種關系不是單調的盯另。因此建議在使用該函數(shù)時,先使用函數(shù)cv::getOptimalDFTSize()
獲取到比輸入數(shù)組更大的高效尺寸洲赵,并將輸入數(shù)組擴展到這個大小鸳惯。
cv::cvtColor()
該函數(shù)將圖像數(shù)據(jù)從1種顏色空間轉換到另外一個顏色空間,并且保持元素的基本數(shù)據(jù)類型不變叠萍。其原型如下芝发。該函數(shù)輸入矩陣的基本元素類型可以是8或者16位無符號整型,或者是32位無符號浮點型數(shù)據(jù)苛谷,其處理的結果和元素矩陣保持相同的尺寸和元素的基本數(shù)據(jù)類型辅鲸。參數(shù)code
表示需要映射的顏色空間,會在下面的表格中介紹腹殿。參數(shù)dstCn
指定輸出結果的顏色通道數(shù)独悴,如果選擇默認值0,則將會根據(jù)原始數(shù)據(jù)和顏色空間轉化類型兩個因素決定處理結果中的顏色通道數(shù)锣尉。
// src:輸入數(shù)組
// dst:處理結果
// code:顏色映射的代碼刻炒,具體見下面的表格
// dstCn:輸出元素的顏色通道數(shù),默認值為0
void cv::cvtColor(cv::InputArray src, cv::OutputArray dst,
int code, int dstCn = 0);
參數(shù)code的含義如下表自沧。
參數(shù)code的取值 | 含義 |
---|---|
cv::COLOR_BGR2RGB cv::COLOR_RGB2BGR cv::COLOR_RGBA2BGRA cv::COLOR_BGRA2RGBA |
在RGB和BGR顏色空間中轉化坟奥,可以包含alpha通道即透明度通道 |
cv::COLOR_RGB2RGBA cv::COLOR_BGR2BGRA |
為RGB和BGR顏色空間添加alpha通道 |
cv::COLOR_RGBA2RGB cv::COLOR_BGRA2BGR |
移除RGB和BGR顏色空間中的alpha通道 |
cv::COLOR_RGB2BGRA cv::COLOR_RGBA2BGR cv::COLOR_BGRA2RGB cv::COLOR_BGR2RGBA |
在RGB和BGR顏色空間中轉化,并添加或者移除alpha通道 |
cv::COLOR_RGB2GRAY cv::COLOR_BGR2GRAY cv::COLOR_RGBA2GRAY cv::COLOR_BGRA2GRAY |
從RGB或BGR顏色空間轉換到灰度數(shù)據(jù),可選移除alpha通道 |
cv::COLOR_GRAY2RGB cv::COLOR_GRAY2BGR cv::COLOR_GRAY2RGBA cv::COLOR_GRAY2BGRA |
從灰度數(shù)據(jù)轉換到RGB或BGR顏色空間爱谁,可選添加alpha通道 |
cv::COLOR_RGB2BGR565 cv::COLOR_BGR2BGR565 cv::COLOR_BGR5652RGB cv::COLOR_BGR5652BGR cv::COLOR_RGBA2BGR565 cv::COLOR_BGRA2BGR565 cv::COLOR_BGR5652RGBA cv::COLOR_BGR5652BGRA |
在RGB或BGR顏色空間和BGR565顏色空間之間相互轉換晒喷,可以添加或者移除alpha通道 |
cv::COLOR_GRAY2BGR565 cv::COLOR_BGR5652GRAY |
在灰度數(shù)據(jù)和BGR565顏色空間之間相互轉換 |
cv::COLOR_RGB2BGR555 cv::COLOR_BGR2BGR555 cv::COLOR_BGR5552RGB cv::COLOR_BGR5552BGR cv::COLOR_RGBA2BGR555 cv::COLOR_BGRA2BGR555 cv::COLOR_BGR5552RGBA cv::COLOR_BGR5552BGRA |
在RGB或BGR顏色空間和BGR555顏色空間之間相互轉換,可以添加或者移除alpha通道 |
cv::COLOR_GRAY2BGR555 cv::COLOR_BGR5552GRAY |
在灰度數(shù)據(jù)和BGR555顏色空間之間相互轉換 |
cv::COLOR_RGB2XYZ cv::COLOR_BGR2XYZ cv::COLOR_XYZ2RGB cv::COLOR_XYZ2BGR |
在RGB或BGR顏色空間和CIE XYZ顏色空間之間相互轉換访敌,CIE XYZ使用Rec709標準和D65白光源 |
cv::COLOR_RGB2YCrCb cv::COLOR_BGR2YCrCb cv::COLOR_YCrCb2RGB cv::COLOR_YCrCb2BGR |
在RGB或BGR顏色空間和亮度色度YCC顏色空間之間相互轉換 |
cv::COLOR_RGB2HSV cv::COLOR_BGR2HSV cv::COLOR_HSV2RGB cv::COLOR_HSV2BGR |
在RGB或BGR顏色空間和HSV顏色空間之間相互轉換 |
cv::COLOR_RGB2HLS cv::COLOR_BGR2HLS cv::COLOR_HLS2RGB cv::COLOR_HLS2BGR |
在RGB或BGR顏色空間和HLS顏色空間之間相互轉換 |
cv::COLOR_RGB2Lab cv::COLOR_BGR2Lab cv::COLOR_Lab2RGB cv::COLOR_Lab2BGR |
在RGB或BGR顏色空間和CIE Lab顏色空間之間相互轉換 |
cv::COLOR_RGB2Luv cv::COLOR_BGR2Luv cv::COLOR_Luv2RGB cv::COLOR_Luv2BGR |
在RGB或BGR顏色空間和CIE Luv顏色空間之間相互轉換 |
cv::COLOR_BayerBG2RGB cv::COLOR_BayerGB2RGB cv::COLOR_BayerRG2RGB cv::COLOR_BayerGR2RGB cv::COLOR_BayerBG2BGR cv::COLOR_BayerGB2BGR cv::COLOR_BayerRG2BGR cv::COLOR_BayerGR2BGR |
從Bayer模式(單通道)數(shù)據(jù)轉換到RGB或BGR顏色空間 |
這里并不會詳細的介紹這些顏色空間的差異凉敲,如需要了解可以移步至另一個篇文章《數(shù)字媒體基礎2-數(shù)字圖像表示》。現(xiàn)在只需要知道OpenCV提供了相關的函數(shù)能夠處理這些顏色空間的數(shù)據(jù)轉換寺旺。顏色空間轉換隱含如下約定荡陷,8位位深度圖像像素的取值范圍為0到255,16位位深度圖像像素的取值范圍為0到65536迅涮,浮點型數(shù)據(jù)的取值范圍為0.0到1.0』展辏灰度圖轉換為顏色圖時叮姑,所有的顏色通道值都相同,但是逆變換時采用了如下的加權計算公式据悔。
在HSV和HLS顏色空間中传透,色調(hue)的取值范圍通常為[0, 360),因此在8位位深度的圖像中极颓,記錄色調值的時候需要記錄其除2后的結果朱盐。
cv::determinant()
該函數(shù)計算一個滿足特定需求的方陣行列式,其輸入矩陣元素必須是單通道的菠隆,并且其基本數(shù)據(jù)類型必須是浮點型兵琳。如果輸入矩陣的尺寸不大,會使用標準公式直接計算骇径,如果輸入的矩陣過大躯肌,會使用性能更高的高斯清除法(Gaussian elimination)計算。其原型如下破衔。
// mat:待計算矩陣
// return:輸入矩陣的行列式
double cv::determinant(cv::InputArray mat);
如果確定一個矩陣是對稱正定的清女,可以使用奇異值分解(Singular Value Decomposition, SVD)來求行列式,這個數(shù)學概念會在后續(xù)章節(jié)中詳細介紹晰筛。需要注意的是使用這個技巧時需要將參數(shù)U和V都設置為NULL嫡丙,然后就可以通過求矩陣W的乘積得到行列式結果。
cv::divide()
該函數(shù)計算標量和矩陣的商读第,它有兩個形式曙博,第一個形式的計算公式如下。
其函數(shù)原型如下卦方。
void cv::divide(cv::InputArray src1, cv::InputArray src2, cv::OutputArray dst,
double scale = 1.0, int dtype = -1);
第二個形式的計算公式如下羊瘩。
其函數(shù)原型如下。
void cv::divide(double scale, cv::InputArray src2, cv::OutputArray dst,
int dtype = -1);
cv::eigen()
給定一個對策矩陣,該函數(shù)可以計算出其特征向量(Eigenvectors)和特征值(Eigenvalues)尘吗。該函數(shù)的輸入矩陣元素基本數(shù)據(jù)類型必須是浮點型逝她,計算結果特征值矩陣將以遞減順序包含輸入矩陣的特質值。如果需要獲取特征向量睬捶,則特征向量會按行的形式存儲在矩陣中黔宛,并且其順序和對應的特征值在特征值向量中的順序相同。參數(shù)lowindex
和highindex
必須一起使用擒贸,它們共同決定了哪些特征值或者特征向量會被計算臀晃,如當這兩個參數(shù)分別設置為0和1時,只有最大的兩個特征向量才會被計算介劫。該函數(shù)原型如下徽惋。
bool cv::eigen(cv::InputArray src, cv::OutputArray eigenvalues,
int lowindex = -1, int highindex = -1);
bool cv::eigen(cv::InputArray src, cv::OutputArray eigenvalues,
cv::OutputArray eigenvectors,
int lowindex = -1,int highindex = -1);
cv::exp()
該函數(shù)計算以自然對數(shù)e為底,輸入矩陣中每個元素為指數(shù)的值座韵,其原型如下险绘。
void cv::exp(cv::InputArray src, cv::OutputArray dst);
cv::extractImageCOI()
該函數(shù)從2.1版本之前的數(shù)組對象arr
,如IplImage
或者CvMat
實例中提取興趣通道(COI)誉碴。如果指定了參數(shù)coi
宦棺,則提取對應的通道,如果未指定黔帕,則提取輸入數(shù)組內(nèi)部指定的興趣通道代咸。其原型如下。需要注意的是該函數(shù)僅僅用于兼容老版本OpenCV成黄,如果使用現(xiàn)代版本的矩陣對象cv::Mat
呐芥,請使用函數(shù)cv::mixChannels()
或者cv::split()
。
bool cv::extractImageCOI(const CvArr* arr, cv::OutputArray dst, int coi = -1);
cv::flip()
該函數(shù)可以單獨繞x軸或y軸對圖像做鏡像處理奋岁,也可以同時繞xy軸鏡像圖像贩耐。其原型如下。
/// src:輸入矩陣
/// dst:輸出矩陣
/// flipCode:翻轉參數(shù)
/// 小于0時厦取,同時繞x軸和y軸做鏡像潮太。等于0時,繞x軸做鏡像虾攻。大于0時繞y軸做鏡像
void cv::flip(cv::InputArray src, cv::OutputArray dst, int flipCode = 0 );
cv::gemm()
該方法計算廣義的矩陣乘法(Generalized matrix multiplication, GEMM)铡买,可以實現(xiàn)矩陣乘法,轉置后的矩陣乘法和帶比例的乘法等霎箍。其原型如下奇钞。其中參數(shù)flags
的取值可以是cv::GEM_1_T
、cv::GEM_2_T
和cv::GEM_3_T
漂坏,以及他們之中的任意組合景埃。所有的矩陣尺寸都應該滿足矩陣乘法的要求媒至,元素的基本數(shù)據(jù)類型都應該是浮點型。
// src1:被乘數(shù)矩陣
// src2:乘數(shù)矩陣
// alpha:src1*src2結果的權重
// src3:偏移矩陣
// beta:偏移矩陣的權重
// dst:計算結果矩陣
// flags: 是否取輸入矩陣的轉置
void cv::gemm(cv::InputArray src1, cv::InputArray src2, double alpha,
cv::InputArray src3, double beta,
cv::OutputArray dst, int flags = 0);
該函數(shù)的計算公式如下谷徙。其中和上面函數(shù)原型參數(shù)相同的變量表示相同的意思拒啰,op表示是否需要取矩陣轉置后的結果。
該函數(shù)還支持雙通道的矩陣,其兩個通道會被視為復數(shù)的兩個部分。另外如下示例必尼,該函數(shù)還可以直接使用矩陣表達式實現(xiàn)。
cv::gemm(src1, src2, alpha, src3, bets, dst,cv::GEMM_1_T | cv::GEMM_3_T );
// 上面的函數(shù)等價于如下表達式
dst = alpha * src1.T() * src2 + beta * src3.T()
cv::getConvertElem()和cv::getConvertScaleElem()
這兩個函數(shù)返回用于特定類型轉換的函數(shù)的函數(shù)指針册着,其原型如下。其中通道數(shù)cn
指的是內(nèi)存連續(xù)的fromType
類型的數(shù)量脾歧,這意味著對于連續(xù)存儲的矩陣甲捏,你可以直接將該值設置為元素的個數(shù)從而一次處理整個矩陣。
// fromType:原始基本數(shù)據(jù)類型鞭执,如cv::U8
// toType:目標基本數(shù)據(jù)類型摊鸡,如CV_32F
// 返回值:返回下面的函數(shù)指針ConvertData
cv::convertData cv::getConvertElem(int fromType, int toType);
// from:帶處理像素集合的內(nèi)存地址
// to:存儲處理后數(shù)據(jù)的內(nèi)存地址
// cn:通道數(shù)
typedef void (*ConvertData)(const void* from, void* to, int cn);
// 返回值:返回下面的函數(shù)指針ConvertScaleData
cv::convertScaleData cv::getConvertScaleElem(int fromType, int toType);
// alpha:縮放系數(shù)
// beta:偏移值
// 需要主要的是縮放后偏移操作優(yōu)先于類型轉換操作
typedef void (*ConvertScaleData)(const void* from, void* to, int cn,
double alpha, double beta);
cv::idct()
該函數(shù)計算某個矩陣的離散余弦逆變換,其原型如下蚕冬。
// flags:是否逐行按一維離散余弦逆變換公式計算
void cv::idct(cv::InputArray src, cv::OutputArray dst, int flags);
也可以通過如下方式實現(xiàn)。
cv::dct( src, dst, flags | cv::DCT_INVERSE );
cv::inRange()
該函數(shù)用于判斷某個矩陣內(nèi)部的元素是否位于指定的區(qū)間內(nèi)是辕,輸出矩陣的基本數(shù)據(jù)類型為cv::U8C1
囤热,如果對應的元素位于指定的區(qū)間內(nèi),其值為255获三,否則為0旁蔼。對于多通道矩陣而言,輸出矩陣仍是單通道的疙教,當對應元素的所有通道都位于指定的區(qū)間內(nèi)時輸出255棺聊,否則輸出0。
// upperb:區(qū)間上邊界贞谓,包含該值
// lowerb:區(qū)間下邊界限佩,包含該值
void cv::inRange(cv::InputArray src, cv::InputArray upperb,
cv::InputArray lowerb, cv::OutputArray dst);
cv::insertImageCOI()
該函數(shù)用于和OpenCV2.1之前版本的數(shù)組對象(如IplImage
和CvMat
的實例)交互,它可以從Cv::Mat
實例中讀取數(shù)據(jù)裸弦,并將其寫入到老版數(shù)組對象中的指定通道中祟同。矩陣img
和arr
必須具有相同的尺寸,數(shù)據(jù)將會被拷貝至數(shù)組arr中理疙。
// img:源矩陣晕城,必須是單通道
// arr:目標數(shù)組,OpenCV2.1之前版本的數(shù)組對象
// coi:指定的通道
void cv::insertImageCOI(cv::InputArray img, CvArr* arr, int coi = -1);
需要注意的是如果處理的是新版本矩陣對象窖贤,需要使用cv::merge()
合并矩陣砖顷。
cv::invert()
該函數(shù)求矩陣的逆贰锁,矩陣src的基本數(shù)據(jù)類型必須是浮點型,因為該函數(shù)有計算偽逆(Pseudo-inverses)的可能滤蝠,輸入矩陣src
可以不是方陣豌熄。該函數(shù)支持多種計算逆矩陣的方法,可以通過參數(shù)method
控制几睛,這些方法列舉如下表房轿,函數(shù)返回值取決于使用的方法。
// 如果矩陣src是奇異矩陣(Singular Matrix)所森,則返回0
// method:使用的計算方法
double cv::invert(cv::InputArray src, cv::OutputArray dst,
int method = cv::DECOMP_LU);
參數(shù)method的取值及其含義如下表囱持。
參數(shù)method的取值 | 含義 |
---|---|
cv::DECOMP_LU | 高斯消除法(LU分解) |
cv::DECOMP_SVD | 奇異值分解(Singular value decomposition, SVD) |
cv::DECOMP_CHOLESKY | 只用于對稱正定矩陣 |
在使用cv::DECOMP_LU
方法時,函數(shù)返回值為矩陣src
的行列式焕济,如果該值為0纷妆,則求逆計算失敗,矩陣dst的所有元素都為0晴弃。如果使用cv::DECOMP_SVD
方法掩幢,則函數(shù)返回值是矩陣逆條件數(shù)量(即最小和最大特征值的比)。如果此時矩陣src
是奇異的上鞠,則該函數(shù)會計算矩陣的偽逆际邻。方法cv::DECOMP_SVD
和cv::DECOMP_CHOLESKY
要求矩陣src
必須是方陣,并且是非奇異正定的芍阎。
cv::log()
該函數(shù)計算矩陣src中每個元素的自然對數(shù)世曾,對于值等于或者小于0時,矩陣dst
中對應的元素將會被填充為一個較大負值谴咸。其原型如下轮听。
void cv::log(cv::InputArray src, cv::OutputArray dst);
cv::LUT()
該函數(shù)通過src
矩陣中定義的索引值到lut矩陣中查找對應的元素,將結果放到矩陣dst中岭佳。矩陣src的基本數(shù)據(jù)類型位深度為8位血巍,如果是8位無符號整數(shù),則該函數(shù)在計算時會在這個索引值的基礎上加128珊随,使之剛好位于矩陣lut的索引區(qū)間內(nèi)述寡。矩陣lut
應該包含256個元素,它可以是單通道或者和矩陣src
具有相同的通道數(shù)叶洞。
當矩陣src
為多通道辨赐,lut
為單通道時,則索引矩陣src
中每個元素的每個通道索引都會在lut
的單個通道中查詢映射值京办。如果此時lut
為多通道掀序,則src
的每個元素的索引值隊在lut
的對應通道中查詢映射值。該函數(shù)原型如下惭婿。
void cv::LUT(cv::InputArray src, cv::InputArray lut, cv::OutputArray dst);
cv::magnitude()
該函數(shù)主要用于計算二維向量場中笛卡爾坐標系向極坐標系(極坐標系中的每個點由到極點的距離和夾角表示)轉換時該點到極點的距離不恭。即將矩陣x和矩陣y對應值求平方和后的結果開發(fā)再賦值給矩陣dst中對應的元素叶雹。該函數(shù)原型如下。
void cv::magnitude(cv::InputArray x, cv::InputArray y, cv::OutputArray dst);
cv::Mahalanobis()
該函數(shù)計算某個點(樣本)的馬氏距離(Mahalanobis distance)换吧,馬氏距離的定義是樣本集中的某個點到該樣本的高斯分布中心的向量距離折晦,以該高斯分布的逆協(xié)方差作為度量來計算,如下圖沾瓦。
圖中满着,三個橢圓上所有樣本到分布中心的距離分別為1.0、2.0和3.0贯莺。直觀上看风喇,這類似基礎統(tǒng)計學中的標準分數(shù)(z-core),即某個一維點到分布中心的距離是由該分布的方差作為單位衡量的缕探,而馬氏距離可以認為是該思路在高維空間中的推廣魂莫。馬氏距離的計算公式如下,其中向量x表示一個n維樣本中任意一點爹耗,向量μ中元素表示n維樣本中對應維度的均值耙考,∑-1表示n維樣本的逆協(xié)方差矩陣。
函數(shù)cv::Mahalanobis()
的原型如下潭兽。
// vec1:樣本矩陣倦始,大小為m*1,表示一個樣本點
// vec2:均值矩陣山卦,大小為m*1鞋邑,表示在m個維度上的均值
// vec3:協(xié)方差逆矩陣,大小為m*m怒坯,位m個維度上的原始樣本集合協(xié)方差矩陣
double cv::mahalanobis(cv::InputArray vec1, cv::InputArray vec2,
cv::InputArray icovar);
使用該函數(shù)參數(shù)化簡上述公式后可以得到如下公式。
在使用該函數(shù)時需要傳入?yún)?shù)逆協(xié)方差矩陣藻懒,可以使用函數(shù)cv::calcCovarMatrix()
先計算出原始樣本集的協(xié)方差矩陣剔猿,再使用函數(shù)cv::invert()
和參數(shù)cv::DECOMP_SVD
計算其逆矩陣。使用參數(shù)cv::DECOMP_SVD
是一個好的編程習慣嬉荆,因為你可能遇到一個包含奇異值0的分布归敬。
cv::max()
該系列函數(shù)逐元素比較一個矩陣中所有元素與另外一個矩陣中對應元素,或者與一個標量的大小鄙早,返回一個矩陣表達式或者將結果寫入到指定的矩陣中汪茧,它們原型如下。
// 返回值:矩陣表達式
// src1和src2是兩個待比較的矩陣
cv::MatExpr cv::max(const cv::Mat& src1, const cv::Mat& src2);
// 矩陣元素和標量比較
MatExpr cv::max(const cv::Mat& src1, double value);
// 標量和矩陣元素比較
MatExpr cv::max(double value, const cv::Mat& src1);
// 將比較結果寫入到指定矩陣中
void cv::max(cv::InputArray src1, cv::InputArray src2, cv::OutputArray dst);
void cv::max(const Mat& src1, const Mat& src2, Mat& dst);
void cv::max(const Mat& src1, double value, Mat& dst);
cv::mean()
該函數(shù)計算了輸入數(shù)組中沒有被蒙版遮住的所有像素的平均值限番,如果輸入矩陣元素是多通道的舱污,則每個通道都會被單獨計算。函數(shù)原型如下弥虐。
cv::Scalar cv::mean(cv::InputArray src, cv::InputArray mask = cv::noArray());
cv::meanStdDev()
該函數(shù)計算矩陣的均值和標準差扩灯,如果矩陣元素包含多個通道媚赖,則每個通道會被單獨計算,返回的矩陣尺寸為m??1珠插,m是輸入矩陣中元素的通道數(shù)惧磺。參數(shù)mask為蒙版矩陣,在計算矩陣和方差時如果該矩陣中的元素為非零值捻撑,則輸入矩陣的元素不會被列入計算范圍磨隘,即計算均值時統(tǒng)計的總元素數(shù)也不包含該矩陣。函數(shù)原型如下顾患。
void cv::meanStdDev(cv::InputArray src, cv::OutputArray mean,
cv::OutputArray stddev, cv::InputArray mask = cv::noArray());
cv::merge()
該函數(shù)是函數(shù)cv::split()
的反向操作番捂,它將多個矩陣合并為1個矩陣。其函數(shù)原型如下描验。
// mv:待合并的C語音風格的矩陣數(shù)組
// count:矩陣數(shù)組中矩陣個數(shù)
// dst:合并結果
void cv::merge(const cv::Mat* mv, size_t count, cv::OutputArray dst);
// mv:待合并的STL風格的矩陣數(shù)組
void merge(const vector<cv::Mat>& mv, cv::OutputArray dst);
cv::min()
該函數(shù)取矩陣對另外一個矩陣中對應元素白嘁,或者對某個特定值比較后的最小值,返回一個矩陣表達式或者將結果寫入到指定的矩陣中膘流。函數(shù)原型如下絮缅。
// 返回值:矩陣表達式
// src1和src2是兩個待比較的矩陣
cv::MatExpr cv::min(const cv::Mat& src1, const cv::Mat& src2);
// 矩陣元素和標量比較
MatExpr cv::min(const cv::Mat& src1, double value);
// 標量和矩陣元素比較
MatExpr cv::min(double value, const cv::Mat& src1);
// 將比較結果寫入到指定矩陣中
void cv::min(cv::InputArray src1, cv::InputArray src2, cv::OutputArray dst);
void cv::min(const Mat& src1, const Mat& src2, Mat& dst);
void cv::min(const Mat& src1, double value, Mat& dst);
cv::minMaxIdx()
這類函數(shù)查找矩陣中的最大和最小值,將它們及它們的索引寫入到指定的地址中呼股。該函數(shù)可以用于處理任意維度的矩陣和稀疏矩陣耕魄。在處理稀疏矩陣時,只處理其中的有效數(shù)據(jù)彭谁,也就是廣義的非零元素吸奴,但是需要注意的是,在稀疏矩陣的操作過程中可能存在值為0的有效元素缠局。具體可以參考前面章節(jié)的稀疏矩陣介紹则奥,這部分值為0的有效元素也會被納入到統(tǒng)計中。該函數(shù)原型如下狭园。
// src:待查詢矩陣读处,只能是單通道
// minVal和maxVal:最小值和最大值寫入地址,不能為NULL
// minIdx和maxIdx:最小值和最大值索引的寫入地址唱矛,可傳NULL
// mask:蒙版矩陣
void cv::minMaxIdx(cv::InputArray src, double* minVal, double* maxVal,
int* minIdx, int* maxIdx, cv::InputArray mask = cv::noArray());
void cv::minMaxIdx(const cv::SparseMat& src, double* minVal, double* maxVal,
int* minIdx, int* maxIdx);
需要注意的是在輸入元素是一維矩陣的情況下罚舱,用于存儲最值索引的參數(shù)minVal
和maxVal
也必須是分配了2位雙精度浮點型數(shù)據(jù)的內(nèi)存地址。這是因為該函數(shù)使用了這樣一個慣例绎谦,單維數(shù)組本質上是一個M??1點矩陣管闷,此時返回的索引值第二個元素總為0。
cv::mixChannels()
該函數(shù)可以從一個或者多個輸入圖像中讀取數(shù)據(jù)窃肠,對通道進行重排列并將其寫到一個或者多個矩陣中包个,OpenCV中有很多操作也是這個問題的特殊情況。例如像cv::split()
和cv::merge()
或者cv::cvtColor()
中的部分場景冤留,這些方法的底層都調用了函數(shù)cv::mixChannels()
赃蛛。該函數(shù)的輸入矩陣可以是多通道的恃锉,函數(shù)會按照指定的方式將原始數(shù)據(jù)中的通道映射到輸出矩陣中。函數(shù)的原型如下呕臂。
// srcv:原始數(shù)據(jù)矩陣數(shù)組的地址
// nsrc:原始數(shù)據(jù)矩陣的個數(shù)
// dstv:目標矩陣數(shù)組地址
// ndst:目標矩陣的個數(shù)
// fromTo:映射關系數(shù)組地址破托,每對映射關系包含表示from和to的兩個整型變量,該參數(shù)在下文詳細介紹
// n_pairs:映射關系的個數(shù)(按映射關系對計數(shù))
void cv::mixChannels(const cv::Mat* srcv, int nsrc,
cv::Mat* dstv, int ndst,
const int* fromTo, size_t n_pairs);
// srcv:包含多個原始數(shù)據(jù)矩陣的向量
// dstv:包含多個目標數(shù)據(jù)矩陣的向量
void cv::mixChannels(const vector<cv::Mat>& srcv, vector<cv::Mat>& dstv,
const int* fromTo, size_t n_pairs);
參數(shù)fromTo
控制了通道的映射關系歧蒋,它指向的int型數(shù)組中每兩個元素表示一組映射關系土砂,即將源數(shù)據(jù)中的某個矩陣的某個通道映射到目標數(shù)據(jù)中的某個矩陣的某個通道中。元素數(shù)據(jù)目標矩陣通道的編號分別從輸入和輸出矩陣數(shù)組中的第一個矩陣的第一個通道開始谜洽,從0開始編號萝映,沒隔一個通道,編號加1阐虚。映射關系如下圖所示序臂。
需要注意的是和OpenCV2.1以后的大多數(shù)函數(shù)不同,該函數(shù)不會為輸出矩陣數(shù)組分配內(nèi)存空間实束,在調用該函數(shù)時必須預先分配好合適的內(nèi)存空間奥秆。
cv::mulSpectrums()
該函數(shù)對兩個傅立葉頻譜矩陣執(zhí)行逐元素乘法操作,并將結果寫入到指定的矩陣中咸灿。函數(shù)原型如下构订。
// arr1和arr2:待計算的兩個傅立葉頻譜矩陣,它們需要具有相同的尺寸
// dst:計算結果
// flags:用于標記待計算矩陣時按行向量處理為1維頻譜向量還是二維頻譜矩陣
// 前者該值設置為cv::DFT_ROWS避矢,后者設置為0
// conj:標記是否使用第二個矩陣的共軛矩陣和第一個矩陣進行計算
void cv::mulSpectrums(cv::InputArray arr1, cv::InputArray arr2,
cv::OutputArray dst, int flags, bool conj = false);
cv::multiply()
該函數(shù)逐元素的求兩個矩陣的乘積悼瘾,并在最后施加一個縮放系數(shù)。其原型如下审胸。
// scale:全局縮放系數(shù)
// dtype:輸出矩陣元素的數(shù)據(jù)類型
void cv::multiply(cv::InputArray src1, cv::InputArray src2,
cv::OutputArray dst, double scale = 1.0, int dtype = -1);
cv::mulTransposed()
當參數(shù)aTa
為ture
時亥宿,該函數(shù)計算矩陣轉置和自己的乘積,當參數(shù)aTa
為false
時該函數(shù)計算矩陣和自己轉置的乘積砂沛,其原型如下烫扼。參數(shù)src1
必須是兩維單通道的矩陣,但是基本數(shù)據(jù)類型不限定必須是浮點型尺上。如果參數(shù)dtype
使用默認值材蛛,則計算得到的矩陣基本數(shù)據(jù)類型和輸入矩陣相同圆到,此外dtype
還可以指定為cv::F64
或者為CV_32F
從而指定計算結果矩陣的基本數(shù)據(jù)類型怎抛。
void cv::mulTransposed(cv::InputArray src1, cv::OutputArray dst,
bool aTa, cv::InputArray delta = cv::noArray(),
double scale = 1.0, int dtype = -1);
根據(jù)上面函數(shù)原型中的參數(shù),其計算公式如下芽淡。
cv::norm()
不包含參數(shù)src2
時马绝,該函數(shù)用于求單個矩陣的范數(shù),包含參數(shù)src2
時挣菲,該函數(shù)用于求兩個矩陣之間的距離范數(shù)富稻。另外這些函數(shù)也能處理稀疏矩陣掷邦,需要注意的是此時將忽略值為0的元素。函數(shù)原型如下椭赋。
// normType:需要計算的范數(shù)類型抚岗,詳細見下表
// mask:蒙版矩陣
double cv::norm(cv::InputArray src1, int normType = cv::NORM_L2,
cv::InputArray mask = cv::noArray());
double cv::norm(cv::InputArray src1, cv::InputArray src2,
int normType = cv::NORM_L2,
cv::InputArray mask = cv::noArray());
double cv::norm(const cv::SparseMat& src, int normType = cv::NORM_L2);
對于處理單個矩陣的函數(shù)而言,參數(shù)normType
的可選值及范數(shù)計算公式如下圖哪怔。
對于處理兩個矩陣的函數(shù)而言宣蔚,參數(shù)normType
的可選值及范數(shù)計算公式如下圖。
對于所有的計算范數(shù)的函數(shù)认境,如果輸入矩陣包含多通道胚委,則將上面兩個圖中的計算公式中src1i
或者src2i
表示的都是第i個元素的多個通道之和。另外叉信,在計算兩個矩陣的距離范數(shù)時亩冬,參數(shù)src2
和src1
必須有相同的尺寸和通道數(shù)。
cv::normalize()
該函數(shù)可以將元素矩陣元素的值映射到指定的區(qū)間內(nèi)硼身,如果指定的區(qū)間為[0, 1]硅急,則該操作為標準化操作。輸出矩陣dst
的尺寸和輸入矩陣src
相同鸠姨,在參數(shù)dtype
未指定時它們還有相同的基本數(shù)據(jù)類型铜秆。參數(shù)dtype
可以設置為如CV_32F
等OpenCV的基本數(shù)據(jù)類型。這類函數(shù)的原型如下讶迁。
// alpha和beta根據(jù)參數(shù)normType的不同有不同的含義连茧,具體見下圖
// normType:標準化策略,具體見下圖
// dtype:輸出矩陣的基本數(shù)據(jù)類型
// mask:蒙版矩陣
void cv::normalize(cv::InputArray src1, cv::OutputArray dst,
double alpha = 1, double beta = 0, int normType = cv::NORM_L2,
int dtype = -1, cv::InputArray mask = cv::noArray());
void cv::normalize(const cv::SparseMat& src, cv::SparseMat& dst,
double alpha = 1, int normType = cv::NORM_L2);
參數(shù)normType
表示標準化策略巍糯,其可用的取值和含義如下圖谐鼎。
當參數(shù)normType
指定為cv::NORM_INF
時,矩陣將被縮放至其最大元素的絕對值和參數(shù)alpha
的值相同胧瓜。當參數(shù)normType
指定為cv::NORM_L1
或cv::NORM_L2
時啤覆,矩陣將被縮放至其對應的范數(shù)和參數(shù)alpha
的值相同。當參數(shù)normType
指定為cv::NORM_MINMAX
時宅楞,矩陣將被縮放使得所有的元素都被線性映射至參數(shù)alpha
和beta
指定的閉區(qū)間內(nèi)针姿。需要注意的是在處理稀疏矩陣時cv::NORM_MINMAX
不可用,這是因為該模式會處理稀疏矩陣內(nèi)的值為0元素厌衙,可能使所有元素變?yōu)榉橇阒稻嘁瑢⑾∈杈仃囎優(yōu)榉窍∈杈仃嚕瑥亩绊懢仃囅∈栊浴?/p>
cv::perspectiveTransform()
該函數(shù)計算一些列點的投影變換婶希,其原型如下榕暇。參數(shù)src必須是雙通道或者三通道的矩陣,而參數(shù)mtx
則必須分別是3??3或者4??4的投影矩陣。在計算過程中都會將矩陣src
中的每個元素認為是1個點彤枢,并為其補充1個值為1點通道狰晚,將點的坐標從笛卡爾坐標擴充至齊次坐標系(Homogeneous Coordinates)。然后將每個點和投影矩陣相乘缴啡,并求所有非擴展通道的值和擴展通道值的商壁晒,將得到的結果放入指定的矩陣中。
void cv::perspectiveTransform(cv::InputArray src, cv::OutputArray dst,
cv::InputArray mtx);
每個元素和投影矩陣相乘的公式如下业栅。
需要注意的是該方法用于轉換一系列的點而不是圖像讨衣,如果你想要對一個圖像應用透視變換,實際上是想將其從一個位置移動到另外一個位置式镐,你應該調用函數(shù)cv::warpPerspective()
反镇。如果想要解決投影變換逆問題,即通過一些列轉換前后的點對來找到最有可能的投影矩陣娘汞,可以使用函數(shù)cv::getPerspectiveTransform()
或者cv::findHomography()
歹茶。
cv::phase()
該函數(shù)用于計算在二維向量場上點從笛卡爾坐標向極坐標轉換后的方位角。其原型如下你弦。該向量場又兩個單通道矩陣組成惊豺,即參數(shù)x和y中對應的元素,你可以使用函數(shù)cv::split()
將多通道矩陣拆分為單通道矩陣禽作。這兩個矩陣應該有相同的尺寸尸昧。
// angleInDegrees:計算結果的表示單位
// ture單位為角度,false單位為弧度
void cv::phase(cv::InputArray x, cv::InputArray y,
cv::OutputArray dst, bool angleInDegrees = false);
該函數(shù)內(nèi)部的計算公式如下旷偿。
cv::polarToCart()
該函數(shù)通過兩個輸入矩陣中對應位置的元素組成一個二維向量烹俗,將其表示為一個極坐標,并計算其對應的笛卡爾坐標萍程,將結果保持在兩個輸出矩陣中幢妄。其原型如下。
參數(shù)magnitude
和angle
分別保存極坐標的幅度和角度(角度和弧度通過參數(shù)angleInDegrees
指定茫负,該參數(shù)為ture
時保存的是角度蕉鸳,false
表示保存的是弧度),因此這兩個矩陣需要有相同的尺寸和基本數(shù)據(jù)類型忍法。參數(shù)x和y也具有相同的尺寸潮尝,它們分別保存了笛卡爾坐標的兩個分量。
void cv::polarToCart(cv::InputArray magnitude, cv::InputArray angle,
cv::OutputArray x, cv::OutputArray y,
bool angleInDegrees = false);
該函數(shù)內(nèi)部的計算公式如下饿序。
cv::pow()
該函數(shù)計算矩陣中每個元素的指數(shù)冪勉失,其原型如下。當p為整數(shù)時嗤堰,函數(shù)直接進行冪運算戴质,否則將先求原始數(shù)據(jù)的絕對值,再進行冪運算踢匣,這樣得到的結果一定是實數(shù)告匠。對于一些特殊的p值,如整數(shù)或者±1/2离唬,該函數(shù)內(nèi)部會用到特殊的算法提高運算效率后专。
void cv::pow(cv::InputArray src, double p, cv::OutputArray dst);
cv::randu()
這類函數(shù)用于計算隨機數(shù),第一種形式是一個模版函數(shù)输莺。該函數(shù)會返回指定類型均勻分布的隨機數(shù)戚哎,其取值范圍從為[0, 該類型的最大值) ,對于浮點數(shù)而言取值范圍為[0.0, 1.0)嫂用。需要注意的是該模版函數(shù)返回值只包含單個有效數(shù)型凳,即對cv::randu<Vec4f>
調用該函數(shù)返回值除第一個元素外都為0。該類型函數(shù)原型如下嘱函。
template<typename _Tp>
_Tp randu();
第二種形式可以為一個已經(jīng)分配好內(nèi)存的矩陣填充指定范圍的隨機數(shù)甘畅,參數(shù)low和high表示的矩陣應為1??1的4通道矩陣或者1??4的單通道矩陣,也可以直接傳遞一個cv::Scalar
的實例往弓。得到的隨機數(shù)區(qū)間為[low疏唾,high)。該函數(shù)原型如下函似。另外在創(chuàng)建隨機數(shù)和填充矩陣時可以考慮使用類cv::RNG
槐脏。
void cv::randu(cv::InputOutArray mtx,
cv::InputArray low, cv::InputArray high);
cv::randn()
該函數(shù)使用正太分布的隨機數(shù)填充矩陣,其原型如下撇寞。參數(shù)mean
和stddev
分別指定了隨機變量分布的均值和標準差顿天。參數(shù)mtx
中的每個元素的每個通道會被獨立計算,因此如果參數(shù)mtx
通道數(shù)為4蔑担,則參數(shù)mean
和stddev
應當為1??4單通道露氮,或者1??1四通道矩陣,或者是cv::Scalar
的實例钟沛。
void cv::randn(cv::InputOutArray mtx, cv::InputArray mean, cv::InputArray stddev);
cv::randShuffle()
該函數(shù)隨機選擇一維矩陣中的一對元素畔规,并交換它們的位置,從而隨機化這個矩陣恨统。交換的次數(shù)等于參數(shù)mtx
中的元素個數(shù)和參數(shù)iterFactor
的乘積叁扫。參數(shù)rng
是隨機數(shù)生成器,如果未提供畜埋,該函數(shù)內(nèi)部會調用函數(shù)theRNG()
使用默認的隨機數(shù)生成器莫绣。其原型如下。
void cv::randShuffle(cv::InputOutArray mtx, double iterFactor = 1,
cv::RNG* rng = NULL);
cv::reduce()
該函數(shù)通過指定的不同行或者不同列的合并規(guī)則悠鞍,將矩陣最終簡化為一個n??1或者1??n的向量对室,其原型如下。
void cv::reduce(cv::InputArray src, cv::OutputArray vec,
int dim, int reduceOp = cv::REDUCE_SUM, int dtype = -1);
參數(shù)dim
定義了合并的方式,其可取的值和含義如下表掩宜。
參數(shù)dim的取值 | 含義 |
---|---|
0 | 不同行之間合并蔫骂,最后輸出僅1行的矩陣 |
1 | 不同列之間合并,最后輸出僅1列的矩陣 |
參數(shù)reduceOp
定義了不同元素的合并規(guī)則牺汤,其可取的值和含義如下表辽旋。
參數(shù)reduceOp的取值 | 含義 |
---|---|
cv::REDUCE_SUM | 求和 |
cv::REDUCE_AVG | 計算均值 |
cv::REDUCE_MAX | 取極大值 |
cv::REDUCE_MIN | 取極小值 |
該函數(shù)支持所有基本數(shù)據(jù)類型的多通道的矩陣,在使用cv::REDUCE_SUM
和cv::REDUCE_AVG
合并規(guī)則時將參數(shù)dtype
設置為一個高精度的數(shù)據(jù)類型很有必要檐迟,因為這樣能夠避免在數(shù)據(jù)累加可能出現(xiàn)的溢出類累積問題补胚。
cv::repeat()
該函數(shù)重復拷貝某個矩陣內(nèi)指定的行和列直至達到指定的拷貝次數(shù)。其原型如下追迟。
// src:數(shù)據(jù)源溶其,一個二維矩陣
// nx和ny:在x和y方向上的拷貝次數(shù)
// dst:需要填充的矩陣,他的尺寸和矩陣src無任何關聯(lián)敦间,可以不同
void cv::repeat(cv::InputArray src, int nx, int ny, cv::OutputArray dst);
// 返回值:返回拷貝得到的矩陣
cv::Mat cv::repeat(cv::InputArray src, int nx, int ny);
cv::scaleAdd()
該函數(shù)求兩個矩陣的和握联,其原型如下。
// src1:被加數(shù)每瞒,矩陣src1
// scale:計算時對矩陣src1的縮放值
// src2:加數(shù)
// dst:用于保存計算結果的輸出矩陣
void cv::scaleAdd(cv::InputArray src1, double scale, cv::InputArray src2,
cv::OutputArray dst);
該函數(shù)也可以通過如下矩陣表達式直接實現(xiàn)金闽。
dst = scale * src1 + src2;
cv::setIdentity()
該函數(shù)將矩陣中所有行列索引不相等的元素設置為0,將所有行列索引相等的元素設置為指定的值剿骨,其原型如下代芜。該函數(shù)可以處理包含任意基本數(shù)據(jù)類型,任意尺寸的矩陣浓利。
void cv::setIdentity(cv::InputOutputArray dst,
const cv::Scalar& value = cv::Scalar(1.0));
在處理cv::Ma
t實例時挤庇,求單位矩陣通常使用其成員函數(shù)cv::Mat eye()
。
cv::solve()
該函數(shù)基于函數(shù)cv::invert()
求解一個線性系統(tǒng)贷掖,找到最優(yōu)解嫡秕,其原型如下。
// lhs:線性系統(tǒng)樣本坐標集合苹威,n??n矩陣
// rhs:線性系統(tǒng)右側常量部分昆咽,n??1矩陣
// dst:線性系統(tǒng)系數(shù)的最優(yōu)解,n??1矩陣
// method:求解方法牙甫,稍后詳細介紹
int cv::solve(cv::InputArray lhs, cv::InputArray rhs,
cv::OutputArray dst, int method = cv::DECOMP_LU);
該函數(shù)內(nèi)部的計算公式如下掷酗。
其中A是參數(shù)lhs
傳入的方陣,B是參數(shù)rhs
傳入的向量窟哺,C是該函數(shù)內(nèi)部根據(jù)參數(shù)method
選取的策略計算的一個中間值泻轰,目的是為了尋找最優(yōu)的向量X,向量X將會寫入到參數(shù)dst
中且轨。該函數(shù)只能處理浮點型的數(shù)據(jù)浮声,函數(shù)返回值為非0值時表示該函數(shù)能夠計算該線性系統(tǒng)的解虚婿,反之則不能。參數(shù)method
可能的取值及其含義如下表泳挥。
參數(shù)method的取值 | 含義 |
---|---|
cv::DECOMP_LU | 高斯消元法(LU分解) |
cv::DECOMP_SVD | 奇異值分解(SVD) |
cv::DECOMP_CHOLESKY | 處理對稱正定矩陣 |
cv::DECOMP_EIG | 特征值分解然痊,只能處理對稱矩陣 |
cv::DECOMP_QR | QR因式分解 |
cv::DECOMP_NORMAL | 可選附加標志,表示求解標準方程 |
參數(shù)cv::DECOMP_LU
和cv::DECOMP_CHOLESKY
不能用于處理奇異矩陣羡洁,在使用這兩個參數(shù)時,如果輸入矩陣lhs是奇異矩陣爽丹,則該函數(shù)立即結束并返回0筑煮,否則返回1≡列可以使用cv::DECOMP_QR
或者cv::DECOMP_SVD
找到線性系統(tǒng)的最小二分解(Least-squares solution)從而處理超定線性系統(tǒng)(無解的線性系統(tǒng)真仲,通常使用最優(yōu)解擬合)。這兩種方法可以處理奇異的輸入矩陣lhs
初澎。
上表的前5個選項都是互斥的秸应,但是最后一個選項是可以通過邏輯與符號與前面的任意一個選項疊加。該選項被疊加時碑宴,該函數(shù)會嘗試求標準方程組(Normal Equations)的解软啼,否則求一般方程組(Normal Equations)的解。即未疊加該選項時的標準方程組如下延柠。
未疊加該選項時的一般方程組如下祸挪。
cv::solveCubic()
該函數(shù)用于求解三次多項式的實根,其原型如下贞间。
int cv::solveCubic(cv::InputArray coeffs, cv::OutputArray roots);
如果參數(shù)coeffs包含四個元素贿条,則多項式表示如下。
如果參數(shù)coeffs包含三個元素增热,則多項式表示如下整以。
計算的結果會被寫入到矩陣roots
中,其包含的元素數(shù)取決于多項式實根的個數(shù)峻仇。需要注意在函數(shù)cv::soleveCubic()
和cv::sovePoly()
中公黑,參數(shù)coeffs
中元素和多項式中系數(shù)對應的方式相反,在前者中高階系數(shù)是第一個摄咆,在后者中高階系數(shù)是矩陣coeffs
的最后一個元素帆调。
cv::solvePoly()
該函數(shù)可以求解任意階數(shù)的多項式實根,其原型如下豆同。
// maxlters:計算過程中的最大迭代數(shù)
int cv::solvePoly (cv::InputArray coeffs, cv::OutputArray roots,
int maxIters = 300);
參數(shù)coeffs
表示的多項式如下番刊。
和函數(shù)cv::solveCubic()
不同的是,函數(shù)cv::solvePoly()
會將虛根和實根一并返回影锈。n階多項式會包含n個根芹务,矩陣roots
中元素包含兩個通道蝉绷,基本數(shù)據(jù)類型為雙精度型,雙通道分別表示根的實部和虛部枣抱。
cv::sort()
該函數(shù)對一個二維單通道矩陣排序熔吗,其原型如下。和在微軟的Excel程序中以某列或者某行排序不同佳晶,該函數(shù)會對每行或者每列單獨排序桅狠。并將排序后的數(shù)據(jù)寫入到一個新的矩陣dst中。
// flags:排序策略轿秧,必須從以下兩則規(guī)則中各選一個中跌,使用邏輯與符號連接
// cv::SORT_EVERY_ROW和cv::SORT_EVERY_COLUMN分別表示對每行或者每列進行排序
// cv::SORT_ASCENDING和cv::SORT_DESCENDING分別表示升序和降序
void cv::sort(cv::InputArray src, cv::OutputArray dst, int flags);
cv::sortIdx()
和函數(shù)cv::sort()
一樣,該函數(shù)同樣只能處理單通道的二維數(shù)組菇篡。不同的是函數(shù)cv::sort()
是將排序后的元素寫入到矩陣dst
中漩符,而該函數(shù)是將元素的索引寫入到矩陣dst
中。其原型如下驱还。
// flags:含義和函數(shù)cv::sort()中一致
void cv::sortIdx(cv::InputArray src, cv::OutputArray dst, int flags);
cv::split()
這類函數(shù)是函數(shù)cv::mixChannels()
的一個簡單特例嗜暴。它將一個多通道矩陣分割為多個單通道矩陣。其原型如下议蟆。
// mtx:多通道矩陣
// mv:單通道矩陣數(shù)組地址
// 數(shù)組元素的個數(shù)必須大于等于矩陣mtx的通道數(shù)
// 數(shù)組內(nèi)存必須我們自己分配
void cv::split(const cv::Mat& mtx, cv::Mat* mv);
// mv:單通道矩陣向量的引用
// 該函數(shù)內(nèi)部會自動為矩陣分配內(nèi)存空間
void cv::split(const cv::Mat& mtx, vector<Mat>& mv);
cv::sqrt()
函數(shù)cv::pow
的一個特例闷沥,該函數(shù)計算每個元素的平方根,對于多通道元素將會逐通道計算咐容,其原型如下狐赡。
void cv::sqrt(cv::InputArray src, cv::OutputArray dst);
數(shù)學中有時存在矩陣的平方根,即如果存在矩陣A和B滿足關系BB = A疟丙,如果A是一個正定方陣颖侄,則B存在并只有唯一解。
如果A可以被對角化享郊,則存在以A的特征向量按列組合的矩陣V使得等式 A = VDV-1成立览祖,此處D是一個對角矩陣。由于對角矩陣的平方根等于每個元素的平方根炊琉,因此計算矩陣A的平方根可以通過如下公式計算展蒂。
可以通過如下直接平方的方式來驗證該等式。
根據(jù)該公式寫出求矩陣A的代碼如下苔咪。
void matrix_square_root(const cv::Mat& A, cv::Mat& sqrtA) {
cv::Mat U, V, Vi, E;
cv::eigen(A, E, U);
V = U.T();
// 求正交矩陣V的逆锰悼,假定矩陣A是正定的,否則它的平方根將是復數(shù)
cv::transpose(V, Vi);
cv::sqrt(E, E);
sqrtA = V * Mat::diag(E) * Vi;
}
cv::subtract()
該函數(shù)簡單的將兩個矩陣中的元素逐個作為被減數(shù)和減數(shù)团赏,計算它們的差箕般,其原型如下。
// src1和src2:被減數(shù)矩陣和減數(shù)矩陣
// mask:蒙版矩陣
// dtype:輸出矩陣的基本數(shù)據(jù)類型
void cv::subtract(cv::InputArray src1, cv::InputArray src2, cv::OutputArray dst,
cv::InputArray mask = cv::noArray(), int dtype = -1);
該函數(shù)可以直接使用如下的矩陣表達式替代舔清。
dst = src1 - src2;
dst -= src1;
cv::sum()
該函數(shù)用于計算矩陣中所有元素的和丝里,它可以處理最多四通道矩陣曲初,每個通道將會被單獨求和,并將結果放到cv::Scalar
實例中返回杯聚,其中的每個元素表示每個通道的求和結果臼婆。其原型如下。
cv::Scalar cv::sum(cv::InputArray arr);
cv::trace()
該函數(shù)計算輸入矩陣對角線上所有元素的和幌绍,它可以處理最多四通道的任意尺寸矩陣颁褂,每個通道將會被單獨求和,并將結果放到cv::Scalar
實例中返回傀广,其中的每個元素表示每個通道的求和結果颁独。其原型如下。
cv::Scalar cv::trace(cv::InputArray mat);
cv::transform()
該函數(shù)將輸入矩陣內(nèi)所有元素視為單個列向量主儡,并逐個應用矩陣變換奖唯,其原型如下惨缆。矩陣mtx的尺寸為n??1或者n+1??1糜值,n表示矩陣src
的通道數(shù)。在第二種情況下矩陣src
的每個元素都會被擴展值為1的一個維度坯墨。
void cv::transform(cv::InputArray src, cv::OutputArray dst, cv::InputArray mtx);
這種轉換的含義依賴于輸入矩陣中單個元素不同通道的值的含義寂汇,如果它們的含義為顏色通道,則這種轉換可以視為一種線性顏色空間轉換捣染,如在RGB和YUV顏色空間中轉換骄瓣。如果這些通道表示的是一個點的坐標,則這種轉換可以被理解為這些點點旋轉或者其他幾何變換耍攘。
cv::transpose()
該函數(shù)用于求轉置矩陣榕栏,它可以處理多通道的矩陣,但是需要記住在處理多通道矩陣時蕾各,該函數(shù)不會執(zhí)行復數(shù)共軛運算扒磁。其原型如下。該函數(shù)也可以使用類cv::Mat
的成員函數(shù)cv::Mat t()
實現(xiàn)式曲。
void cv::transpose(cv::InputArray src, cv::OutputArray dst);
3 小結
矩陣對象cv::Mat
是OpenCV中重要的數(shù)據(jù)結構妨托,本章介紹了和其相關的大量函數(shù)。這些函數(shù)包含了從簡單的線性操作到復雜的特征操作,其中部分是處理表示圖像數(shù)據(jù)的矩陣,而其余部分則是處理其他類型數(shù)據(jù)的融痛。在后面的章節(jié)中會介紹到更復雜的算法以實現(xiàn)復雜的計算機視覺效果季眷,而本章的函數(shù)這是這些復雜算法的基礎。