5. openCV中常用函數學習


一、前言

經過兩個星期的努力,一邊學習,一邊寫代碼,初步完成了畢業論文系統的界面和一些基本功能,主要包括:1 數據的讀寫和顯示,及相關的基本操作(放大、縮小和移動);2 樣本數據的選擇;3 數據歸一化處理;4 繪制光譜曲線;5 獲取波段信息。接下來的工作主要是完成遙感影像分類的相關算法。這部分主要是數學計算,尤其是矩陣的相關運算和操作。為此,系統的學習和了解了openCV庫中常用的矩陣操作函數,記錄下來,方便以后查閱。

二、openCV函數

1 reshape

1 C++: Mat Mat::reshape(int cn, int rows=0) const

官方解釋:能夠改變二維數組的通道和形式,並且並不拷貝數據(只是創建矩陣的信息頭)。

參數:int cn : 變換后通道數(0表示保持原通道數);

        int rows : 變換后行數(0表示行數不變),列數更具以上兩個參數自動確定。

對於遙感影像來說,我們常常將通道數據(波段數據)作為特征用作后續數據的處理,為此,我們總希望將通道數變為行或列數,對此我們可以使用如下的方法:

 1 int main(int argc, char *argv[])
 2 {
 3     QCoreApplication a(argc, argv);
 4 
 5     cv::Mat img = cv::imread("F:\\paperSystem\\openCV\\2.tif");
 6     cv::Mat tmpB;
 7     tmpB = img.reshape(1,img.rows*img.cols); // 將通道數變成列數,每一行可表示每一個樣本數據
 8     qDebug()<<img.channels()<<tmpB.cols;  //  通道個數
 9     qDebug()<<img.at<cv::Vec3b>(0,0)[0]<<tmpB.at<uchar>(0,0);
10     qDebug()<<img.at<cv::Vec3b>(0,0)[1]<<tmpB.at<uchar>(0,1);
11     qDebug()<<img.at<cv::Vec3b>(0,0)[2]<<tmpB.at<uchar>(0,2);
12     return a.exec();
13 }

顯示如下:

2 norm

1 C++: double norm(InputArray src1, int normType=NORM_L2, InputArray mask=noArray())  // 計算矩陣src1的范數,主要包括1,2,inf范數 NORM_L1/NORM_L2/NORM_INF
2 C++: double norm(InputArray src1, InputArray src2, int normType=NORM_L2, InputArray mask=noArray()) // 計算矩陣(src1-src2)的1、2、inf范數 NORM_L1/NORM_L2/NORM_INF (對於normType = NORM_RELATIVE_INF/NORM_RELATIVE_L1/NORM_RELATIVE_L2,則計算(src1-src2)的范數與src1的相應范數之商
3 C++: double norm(const SparseMat& src, int normType)

參數:大家都知道

 1 int main(int argc, char *argv[])
 2 {
 3     QCoreApplication a(argc, argv);
 4 
 5     cv::Mat img = cv::imread("F:\\paperSystem\\openCV\\2.tif");
 6     std::vector<cv::Mat>splitImg(img.channels());
 7     cv::split(img,splitImg);
 8 
 9     cv::Mat tmp = img.reshape(1,img.rows*img.cols);
10 
11     double norm1_splitImg = cv::norm(splitImg[0],cv::NORM_L1);
12     double norm2_splitImg = cv::norm(splitImg[0],cv::NORM_L2);
13     double normInf_splitImg = cv::norm(splitImg[0],cv::NORM_INF);
14 
15     double norm1_img = cv::norm(img,cv::NORM_L1);
16     double norm2_img = cv::norm(img,cv::NORM_L2);
17     double normInf_img = cv::norm(img,cv::NORM_INF);
18 
19     double norm1_tmp = cv::norm(tmp,cv::NORM_L1);
20     double norm2_tmp = cv::norm(tmp,cv::NORM_L2);
21     double normInf_tmp = cv::norm(tmp,cv::NORM_INF);
22 
23     qDebug()<<norm1_splitImg<<"  "<<norm1_img<<"  "<<norm1_tmp;
24     qDebug()<<norm2_splitImg<<"  "<<norm2_img<<"  "<<norm2_tmp;
25     qDebug()<<normInf_splitImg<<"  "<<normInf_img<<"  "<<normInf_tmp;
26     return a.exec();
27 }

顯示如下:對於多通道數據是變成單通道后處理的,全部通道數據都加入計算。

3 normalize

1 C++: void normalize(InputArray src, OutputArray dst, double alpha=1, double beta=0, int norm_type=NORM_L2, int dtype=-1, InputArray mask=noArray())
2 C++: void normalize(const SparseMat& src, SparseMat& dst, double alpha, int normType)

參數: InputArray src:輸入的矩陣;

         OutputArray dst:輸出矩陣;

         double alpha:將矩陣規則化到aipha,或者是規則化后矩陣的最小值;

         double beta:矩陣元素規則化的上界;當前面alpha規則化到某個值時,不使用

        。。。。。。。

cv::normalize(splitImg[0],tmp,0,255,cv::NORM_MINMAX);  // 關於這個函數我還不是很理解,將矩陣元素歸一化到一個區間可以,可是為何將矩陣的某個范數歸一化到一個值卻一直不行

有知道的請幫忙。

4 reduce

1 C++: void reduce(InputArray src, OutputArray dst, int dim, int rtype, int dtype=-1 )

這個函數功能很強大,可以實現矩陣的列求和、均值、最大、最小。

參數:int dim:0  --- 行      

        int rtype:  CV_REDUCE_SUM   CV_REDUCE_AVG  CV_REDUCE_MAX  CV_REDUCE_MIN

        int dtypr:默認為原始數據的類型,注意:對於求和和均值之類要改變數據類型,尤其是求和,不然數據大小超過原始數據類型會報錯

5 repeat

1 C++: void repeat(InputArray src, int ny, int nx, OutputArray dst)
2 C++: Mat repeat(const Mat& src, int ny, int nx)

這個代碼和Matlab中的repmat一樣

 

總結:openCV幾乎具有MatLab中相似的矩陣操作函數,看來接下來將MatLab的代碼轉化為opencCV格式不是那么難  哈哈。。。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM