1 前備知識
歸一化:把數據變成(0,1)或者(1,1)之間的小數,主要是為了方便數據處理。歸一化是一種簡化計算的方式,即將有量綱的表達式,經過變換,化為無量綱的表達式,成為純量。有以下幾種方式:
(1)x' = (x-x_min)/(x_max-x_min)
其中,x是歸一化前的值,x'是歸一化后的值,x_max、x_min分別是樣本的最大最小值;
(2)平均歸一化:x' = (x-u)/(x_max-x_min)
其中,x是歸一化前的值,x'是歸一化后的值,u是樣本的均值,x_max、x_min分別是樣本的最大最小值;
*注:(1)和(2)有一個缺陷就是當有新數據加入時,可能導致max和min的變化,需要重新定義。
(3)非線性歸一化
1)對數函數轉換:y = log10(x)
2)反余切函數轉換:y = atan(x) * 2 / π
3)經常用在數據分化比較大的場景,有些數值很大,有些很小。通過一些數學函數,將原始值進行映射。該方法包括 log、指數,正切等。需要根據數據分布的情況,決定非線性函數的曲線,比如log(V, 2)還是log(V, 10)等。
/** @brief Normalizes the norm or value range of an array.
The function cv::normalize normalizes scale and shift the input array elements so that
\f[\| \texttt{dst} \| _{L_p}= \texttt{alpha}\f]
(where p=Inf, 1 or 2) when normType=NORM_INF, NORM_L1, or NORM_L2, respectively; or so that
\f[\min _I \texttt{dst} (I)= \texttt{alpha} , \, \, \max _I \texttt{dst} (I)= \texttt{beta}\f]
when normType=NORM_MINMAX (for dense arrays only). The optional mask specifies a sub-array to be
normalized. This means that the norm or min-n-max are calculated over the sub-array, and then this
sub-array is modified to be normalized. If you want to only use the mask to calculate the norm or
min-max but modify the whole array, you can use norm and Mat::convertTo.
In case of sparse matrices, only the non-zero values are analyzed and transformed. Because of this,
the range transformation for sparse matrices is not allowed since it can shift the zero level.
Possible usage with some positive example data:
@code{.cpp}
vector<double> positiveData = { 2.0, 8.0, 10.0 };
vector<double> normalizedData_l1, normalizedData_l2, normalizedData_inf, normalizedData_minmax;
// Norm to probability (total count)
// sum(numbers) = 20.0
// 2.0 0.1 (2.0/20.0)
// 8.0 0.4 (8.0/20.0)
// 10.0 0.5 (10.0/20.0)
normalize(positiveData, normalizedData_l1, 1.0, 0.0, NORM_L1);
// Norm to unit vector: ||positiveData|| = 1.0
// 2.0 0.15
// 8.0 0.62
// 10.0 0.77
normalize(positiveData, normalizedData_l2, 1.0, 0.0, NORM_L2);
// Norm to max element
// 2.0 0.2 (2.0/10.0)
// 8.0 0.8 (8.0/10.0)
// 10.0 1.0 (10.0/10.0)
normalize(positiveData, normalizedData_inf, 1.0, 0.0, NORM_INF);
// Norm to range [0.0;1.0]
// 2.0 0.0 (shift to left border)
// 8.0 0.75 (6.0/8.0)
// 10.0 1.0 (shift to right border)
normalize(positiveData, normalizedData_minmax, 1.0, 0.0, NORM_MINMAX);
@endcode
@param src input array.
@param dst output array of the same size as src .
@param alpha norm value to normalize to or the lower range boundary in case of the range
normalization.
@param beta upper range boundary in case of the range normalization; it is not used for the norm
normalization.
@param norm_type normalization type (see cv::NormTypes).
@param dtype when negative, the output array has the same type as src; otherwise, it has the same
number of channels as src and the depth =CV_MAT_DEPTH(dtype).
@param mask optional operation mask.
@sa norm, Mat::convertTo, SparseMat::convertTo
*/
CV_EXPORTS_W void normalize( InputArray src, InputOutputArray dst, double alpha = 1, double beta = 0, int norm_type = NORM_L2, int dtype = -1, InputArray mask = noArray());
/** @overload
@param src input array.
@param dst output array of the same size as src .
@param alpha norm value to normalize to or the lower range boundary in case of the range
normalization.
@param normType normalization type (see cv::NormTypes).
*/
CV_EXPORTS void normalize( const SparseMat& src, SparseMat& dst, double alpha, int normType );
//程序DEMO流程: //讀取圖片--》判斷並顯示圖片--》轉換為灰度圖--》轉換為浮點數類型數組--》四種歸一化方式 //1)scale and shift by NORM_MINMAX //2)scale and shift by NORM_INF //3)scale and shift by NORM_L1 //4)scale and shift by NORM_L2 //--》歸一化的范圍設置為1.0 - 0 //--》不同的歸一化方式結果出來要乘以對應的數值 //--》將結果轉換為CV_8UC1 //--》顯示圖片 #include"opencv2\opencv.hpp" #include"iostream" using namespace std; using namespace cv; int main(int argc, char** argv) { Mat src = imread("G:\\CVworkstudy\\program_wwx\\研習社140課時\\ZhaiZhigang140\\colormap.png"); if (src.empty()) { printf("Could not load image...\n"); return -1; } imshow("srcImg", src); Mat src_gray, src_gray_f; cvtColor(src, src_gray, CV_RGB2GRAY);//轉換為灰度圖 src_gray.convertTo(src_gray_f, CV_32F);//轉換為浮點數類型數組 //scale and shift by NORM_MINMAX Mat dst = Mat::zeros(src_gray.size(), CV_32FC1); normalize(src_gray_f, dst, 1.0, 0, NORM_MINMAX); Mat result = dst * 255; result.convertTo(dst, CV_8UC1); imshow("NORM_MINMAX", dst); //scale and shift by NORM_INF normalize(src_gray_f, dst, 1.0, 0, NORM_INF); result = dst * 255; result.convertTo(dst, CV_8UC1); imshow("NORM_INF", dst); //scale and shift by NORM_L1 normalize(src_gray_f, dst,1.0, 0, NORM_L1); result = dst * 100000000; result.convertTo(dst, CV_8UC1); imshow("NORM_L1", dst); //scale and shift by NORM_L2 normalize(src_gray_f, dst, 1.0, 0, NORM_L2); result = dst * 10000; result.convertTo(dst, CV_8UC1); imshow("NORM_L2", dst); waitKey(0); return 0; }
4 運行結果
5 擴展及注意事項
null