jashliao 用 VC++ 實現 fanfuhan OpenCV 教學011 ~ opencv-011-圖像(像素)資料預先處理[ 歸一化 normalize()]
jashliao 用 VC++ 實現 fanfuhan OpenCV 教學011 ~ opencv-011-圖像(像素)資料預先處理[ 歸一化 normalize()]
資料來源: https://fanfuhan.github.io/
https://fanfuhan.github.io/2019/03/25/opencv-011/
GITHUB:https://github.com/jash-git/fanfuhan_ML_OpenCV
https://github.com/jash-git/jashliao-implements-FANFUHAN-OPENCV-with-VC
★前言:
★主題:
OPENC提供資料歸一化 normalize()函數,其運算方式條列如下:
NORM_MINMAX : 陣列的數值被平移或縮放到一個指定的範圍,線性歸一化,一般較常用。
NORM_INF : 此型別的定義沒有查到,根據opencv 1的對應項,可能是歸一化陣列的C-範數(絕對值的最大值)
NORM_L1 : 歸一化陣列的L1-範數(絕對值的和)
NORM_L2 : 歸一化陣列的(歐幾里德)L2-範數
PS.最常用的就是NORM_MINMAX归一化方法.
歸一化的功能目的:
歸一化就是要把需要處理的資料經過處理後(通過某種演算法)限制在你需要的一定範圍內。
首先歸一化是為了後面資料處理的方便,其次是保證程式運行時收斂加快。
歸一化的具體作用是歸納統一樣本的統計分佈性。歸一化在0-1之間是統計的概率分佈,歸一化在某個區間上是統計的座標分佈。
歸一化有同一、統一和合一的意思。
歸一化的目的,是使得沒有可比性的資料變得具有可比性,同時又保持相比較的兩個資料之間的相對關係,如大小關係;或是為了作圖,原來很難在一張圖上作出來,歸一化後就可以很方便的給出圖上的相對位置等。
★C++
// VC_FANFUHAN_OPENCV011.cpp : 定義主控台應用程式的進入點。 /* // Debug | x32 通用屬性 | C/C++ | | 一般 | | 其他 Include 目錄 -> C:\opencv\build\include | | 連結器 | |一一般 | | 其他程式庫目錄 -> C:\opencv\build\x64\vc15\lib | | |一輸入 | | 其他相依性 -> opencv_world411d.lib;%(AdditionalDependencies) // Releas | x64 組態屬性 | C/C++ | | 一般 | | 其他 Include 目錄 -> C:\opencv\build\include | | 連結器 | |一般 | | 其他程式庫目錄 -> C:\opencv\build\x64\vc15\lib | | |一輸入 | | 其他相依性 -> opencv_world411.lib;%(AdditionalDependencies) */ #include "stdafx.h" #include <iostream> #include <opencv2/opencv.hpp> #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> using namespace std; using namespace cv; void pause() { printf("Press Enter key to continue..."); fgetc(stdin); } int main() { Mat src_bgr = imread("../../images/test.png"); if (src_bgr.empty()) { cout << "could not load image.." << endl; pause(); return -1; } else { imshow("input_bgr", src_bgr); Mat gray; cvtColor(src_bgr, gray, COLOR_BGR2GRAY); imshow("input_gray", gray); // 计算灰度图像的最大最小值 double minVal00, maxVal00; Point minLoc00, maxLoc00;//座標位置 /* 1 minMaxLoc尋找矩陣(一維陣列當作向量,用Mat定義) 中最小值和最大值的位置. 2 參數若不需要,則置為NULL或者0,即可. 3 minMaxLoc針對Mat和MatND的重載中 ,第5個參數是可選的(optional),不使用不傳遞即可. */ minMaxLoc(gray, &minVal00, &maxVal00, &minLoc00, &maxLoc00);//搜尋灰階影像中的最大與最小值 cout << "paramenters of gray:" << endl; printf("min:%.2f, max:%.2f \n", minVal00, maxVal00); printf("min loc: (%d, %d) \n", minLoc00.x, minLoc00.y); printf("max loc: (%d, %d) \n\n", maxLoc00.x, maxLoc00.y); /* 歸一化 normalize() NORM_MINMAX : 陣列的數值被平移或縮放到一個指定的範圍,線性歸一化,一般較常用。 NORM_INF : 此型別的定義沒有查到,根據opencv 1的對應項,可能是歸一化陣列的C-範數(絕對值的最大值) NORM_L1 : 歸一化陣列的L1-範數(絕對值的和) NORM_L2 : 歸一化陣列的(歐幾里德)L2-範數 PS.最常用的就是NORM_MINMAX归一化方法. 歸一化就是要把需要處理的資料經過處理後(通過某種演算法)限制在你需要的一定範圍內。 首先歸一化是為了後面資料處理的方便,其次是保證程式運行時收斂加快。 歸一化的具體作用是歸納統一樣本的統計分佈性。歸一化在0-1之間是統計的概率分佈,歸一化在某個區間上是統計的座標分佈。 歸一化有同一、統一和合一的意思。 歸一化的目的,是使得沒有可比性的資料變得具有可比性,同時又保持相比較的兩個資料之間的相對關係,如大小關係;或是為了作圖,原來很難在一張圖上作出來,歸一化後就可以很方便的給出圖上的相對位置等。 */ // 显示图像用uchar类型,计算时转为float类型 gray.convertTo(gray, CV_32F); // NORM_MINMAX Mat dst = Mat::zeros(gray.size(), CV_32FC1); normalize(gray, dst, 1.0, 0, NORM_MINMAX); Mat res = dst * 255; res.convertTo(dst, CV_8UC1); // 显示图像用uchar类型 imshow("NORM_MINMAX", dst); // 计算灰度图像的最大最小值 double minVal01, maxVal01; Point minLoc01, maxLoc01;//座標位置 /* 1 minMaxLoc尋找矩陣(一維陣列當作向量,用Mat定義) 中最小值和最大值的位置. 2 參數若不需要,則置為NULL或者0,即可. 3 minMaxLoc針對Mat和MatND的重載中 ,第5個參數是可選的(optional),不使用不傳遞即可. */ minMaxLoc(dst, &minVal01, &maxVal01, &minLoc01, &maxLoc01);//搜尋灰階影像中的最大與最小值 cout << "NORM_MINMAX:" << endl; printf("min:%.2f, max:%.2f \n", minVal01, maxVal01); printf("min loc: (%d, %d) \n", minLoc01.x, minLoc01.y); printf("max loc: (%d, %d) \n\n", maxLoc01.x, maxLoc01.y); // scale and shift by NORM_INF normalize(gray, dst, 1.0, 0, NORM_INF); res = dst * 255; res.convertTo(dst, CV_8UC1); imshow("NORM_INF", dst); // scale and shift by NORM_L1 normalize(gray, dst, 1.0, 0, NORM_L1); res = dst * 10000000; res.convertTo(dst, CV_8UC1); imshow("NORM_L1", dst); // scale and shift by NORM_L2 normalize(gray, dst, 1.0, 0, NORM_L2); res = dst * 10000; res.convertTo(dst, CV_8UC1); imshow("NORM_L2", dst); waitKey(0); } return 0; }
★Python
import cv2 as cv import numpy as np src = cv.imread("D:/vcprojects/images/test.png") cv.namedWindow("input", cv.WINDOW_AUTOSIZE) cv.imshow("input", src) gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY) # 转换为浮点数类型数组 gray = np.float32(gray) print(gray) # scale and shift by NORM_MINMAX dst = np.zeros(gray.shape, dtype=np.float32) cv.normalize(gray, dst=dst, alpha=0, beta=1.0, norm_type=cv.NORM_MINMAX) print(dst) cv.imshow("NORM_MINMAX", np.uint8(dst*255)) # scale and shift by NORM_INF dst = np.zeros(gray.shape, dtype=np.float32) cv.normalize(gray, dst=dst, alpha=1.0, beta=0, norm_type=cv.NORM_INF) print(dst) cv.imshow("NORM_INF", np.uint8(dst*255)) # scale and shift by NORM_L1 dst = np.zeros(gray.shape, dtype=np.float32) cv.normalize(gray, dst=dst, alpha=1.0, beta=0, norm_type=cv.NORM_L1) print(dst) cv.imshow("NORM_L1", np.uint8(dst*10000000)) # scale and shift by NORM_L2 dst = np.zeros(gray.shape, dtype=np.float32) cv.normalize(gray, dst=dst, alpha=1.0, beta=0, norm_type=cv.NORM_L2) print(dst) cv.imshow("NORM_L2", np.uint8(dst*10000)) cv.waitKey(0) cv.destroyAllWindows()
★結果圖:
★延伸說明/重點回顧:
由於灰階圖像的數值本來就介於0~255,因此當使用線性歸一化就不會有太明顯的變化,因此個人認為在影像處理中歸一化函數並沒有太明顯的作用