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,因此當使用線性歸一化就不會有太明顯的變化,因此個人認為在影像處理中歸一化函數並沒有太明顯的作用