Table of Contents
函数原型
参数说明
不同norm_type下的计算公式
NORM_L1
NORM_L2
NORM_INF
NORM_MINMAX
参考文章
代码实例
代码输出
Python代码使用normalize
图像输出
笔者备注
void cv::normalize ( InputArray src,
InputOutputArray dst,
double alpha = 1,
double beta = 0,
int norm_type = NORM_L2,
int dtype = -1,
InputArray mask = noArray()
)
笔者说明:这个函数的作用就是把需要处理的数据通过某种算法限制在你需要的一定范围内。
参数 | 英文说明 | 笔者翻译及说明 |
src | input array. | 输入矩阵 |
dst | output array of the same size as src . | 输出矩阵,与输入矩阵尺寸相同 |
alpha | norm value to normalize to or the lower range boundary in case of the range normalization. |
如果norm_type为NORM_MINMAX ,则alpha为最小值或最大值;如果norm_type为其他类型,则为归一化要乘的系数【重点】 |
beta | upper range boundary in case of the range normalization; it is not used for the norm normalization. |
如果norm_type为NORM_MINMAX ,则beta为最小值或最大值;如果norm_type为其他类型,beta被忽略,此处不会被用到,一般传入0【重点】 |
norm_type | normalization type (see cv::NormTypes). | 归一化类型,常见的有NORM_L1, NORM_L2, NORM_INF, NORM_MINMAX |
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). |
如果取负值时,dst与src同样的类型;否则,dst和src有同样的通道数,且此时图像深度为CV_MAT_DEPTH(dtype) |
mask | optional operation mask. | 可选操作掩膜 |
以数列{ 2.0, 6.0, 7.0, 8.0, 10.0 }为例, alpha=5, beta=100
1.先求出norm
公式:L1_norm = ∥src1∥L1=∑I|src1(I)|,即各数的绝对值之和
norm = |2.0| + |6.0| + |7.0| + |8.0| + |10.0| = 33
2. 再求dst
公式:dst = alpha*src/L1_norm
dst[0] = 5 * 2.0/ 33 = 0.303
剩下的以此类推,具体结果请参考最后的代码输出表格。
1.先求出norm
公式:L2_norm = 矩阵中各元素的平方和的开方(欧几里德)(L2-范数)
2. 再求dst
公式:dst = alpha*src/L2_norm
dst[0] = 5 * 2.0/ 15.906 = 0.629
剩下的以此类推,具体结果请参考最后的代码输出表格。
1.先求出norm
INF_norm = 矩阵中所有元素的最大值max
以上数列中 max = 10
PS: 图片处理时可以使用函数 void minMaxLoc(...);求出
2. 再求dst
公式:dst = alpha*src/INF_norm
dst[0] = 5 * 2.0/ 10 = 1
剩下的以此类推,具体结果请参考最后的代码输出表格。
1. alpha、beta分别为归一化后的最小值、最大值
函数会自动判断哪个为最大值,最小值
2. 再求dst
公式如下:
b = max(alpha, beta)
a = min(alpha, beta)
alpha=5, beta=100
b = max(alpha, beta) = 100
a = min(alpha, beta) = 5
dst[0] = (100-5) * (2-2)/ (10-2) +5 = 2
dst[1] = (100-5) * (6-2)/ (10-2) +5 = 52.5
剩下的以此类推,具体结果请参考最后的代码输出表格。
https://docs.opencv.org/3.2.0/d2/de8/group__core__array.html#ga87eef7ee3970f86906d69a92cbf064bd
#include //头文件
#include
using namespace cv; //包含cv命名空间
using namespace std;
int main(int argc, char ** argv)
{
vector positiveData = { 2.0, 6.0, 7.0, 8.0, 10.0 };
vector normalizedData_l1, normalizedData_l2, normalizedData_inf, normalizedData_minmax;
// Norm to probability (total count)
// sum(numbers) = 23.0
normalize(positiveData, normalizedData_l1, 5.0, 100.0, NORM_L1);
cout <<"*normalizedData_l1*:" << endl;
//method#1 C operatator[] - FASTEST
//cout << "\n*C operatator[]*:" << endl;
for (size_t i = 0; i < normalizedData_l1.size(); i++)
{
cout << normalizedData_l1[i] << ",\t";
}
//method#2 C iterator - 2nd fast
//cout << "*iterator*:" << endl;
//for (vector::iterator pd= normalizedData_l1.begin(); pd != normalizedData_l1.end();pd++)
//{
// cout << *pd << "\t";
//}
//method#3 at -- 3rd fast
//cout << "\n*at*:" << endl;
//for (size_t i = 0; i < normalizedData_l1.size(); i++)
//{
// cout << normalizedData_l1.at(i)<< ",\t";
//}
// Norm to unit vector: ||positiveData|| = 1.0
normalize(positiveData, normalizedData_l2, 5.0, 100.0, NORM_L2);
cout << "\n*normalizedData_l2*:" << endl;
for (size_t i = 0; i < normalizedData_l2.size(); i++)
{
cout << normalizedData_l2[i] << ",\t";
}
// Norm to max element
normalize(positiveData, normalizedData_inf, 5.0, 100.0, NORM_INF);
cout << "\n*normalizedData_inf*:" << endl;
for (size_t i = 0; i < normalizedData_inf.size(); i++)
{
cout << normalizedData_inf[i] << ",\t";
}
// Norm to range [5.0;100.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, 5.0, 100.0, NORM_MINMAX);
cout << "\n*normalizedData_minmax*:" << endl;
for (size_t i = 0; i < normalizedData_inf.size(); i++)
{
cout << normalizedData_minmax[i] << ",\t";
}
cout << endl;
// 【3】等待任意按键按下
waitKey(0);
return 0;
}
我对alpha, beta取了三种情况,输出结果如下:
alpha=1, beta=0 | ||||
Original | NORM_L1 | NORM_L2 | NORM_INF | NORM_MINMAX |
2.00 | 0.060606061 | 0.125738923 | 0.2 | 0 |
6.00 | 0.181818182 | 0.377216768 | 0.6 | 0.5 |
7.00 | 0.212121212 | 0.440086229 | 0.7 | 0.625 |
8.00 | 0.242424242 | 0.502955691 | 0.8 | 0.75 |
10.00 | 0.303030303 | 0.628694613 | 1 | 1 |
alpha=3, beta=7 | ||||
Original | NORM_L1 | NORM_L2 | NORM_INF | NORM_MINMAX |
2.00 | 0.181818182 | 0.377216768 | 0.6 | 3 |
6.00 | 0.545454545 | 1.131650304 | 1.8 | 5 |
7.00 | 0.636363636 | 1.320258688 | 2.1 | 5.5 |
8.00 | 0.727272727 | 1.508867072 | 2.4 | 6 |
10.00 | 0.909090909 | 1.88608384 | 3 | 7 |
alpha=5, beta=100 | ||||
Original | NORM_L1 | NORM_L2 | NORM_INF | NORM_MINMAX |
2.00 | 0.30303 | 0.628695 | 1 | 5 |
6.00 | 0.909091 | 1.88608 | 3 | 52.5 |
7.00 | 1.06061 | 2.20043 | 3.5 | 64.375 |
8.00 | 1.21212 | 2.51478 | 4 | 76.25 |
10.00 | 1.51515 | 3.14347 | 5 | 100 |
#! /usr/bin/env python
# -*- coding: utf-8 -*-
import cv2
import sys
if __name__ == '__main__':
if len(sys.argv) > 1:
src = cv2.imread(sys.argv[1], cv2.IMREAD_ANYCOLOR)
else:
print("Usage:python normalize.py imageFile")
cv2.imshow("src", src) # 显示图片
# 直方图归一化/正规化
# 方法一:
# dst = cv2.normalize(src, src, 0, 255, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_8U)
# 方法二:
dst = cv2.normalize(src, None, 0, 255, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_8U)
cv2.imshow("dst", dst) # 显示图片
cv2.waitKey(0) # 等待用户输入,按任意键即可
可以看出输出图像比原来的对比度有增强
如果选择NORM_MINMAX类型,通常将alpha设定为最小值,将beta设定为最大值。
比如,需要将数据范围限定在[0, 400],可以这么使用
normalize(src, dst, 0, 400.0, NORM_MINMAX);
如果选择其他三种类型,beta设定为0,alpha按需求设定。