opencv学习-011-图像像素归一化(normalize)
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main(int argc, const char *argv[])
{
Mat src = imread("E:/Desktop/y.jpg");
if (src.empty()) {
printf("could not load image...\n");
return -1;
}
namedWindow("input", WINDOW_AUTOSIZE);
imshow("input", src);
Mat gray, gray_f;
cvtColor(src, gray, COLOR_BGR2GRAY);
// 转换为浮点数类型数组
gray.convertTo(gray, CV_32F);
// scale and shift by NORM_MINMAX
Mat dst = Mat::zeros(gray.size(), CV_32FC1);
normalize(gray, 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(gray, 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(gray, dst, 1.0, 0, NORM_L1);
result = dst * 10000000;
result.convertTo(dst, CV_8UC1);
imshow("NORM_L1", dst);
// scale and shift by NORM_L2
normalize(gray, dst, 1.0, 0, NORM_L2);
result = dst * 10000;
result.convertTo(dst, CV_8UC1);
imshow("NORM_L2", dst);
waitKey(0);
return 0;
}
首先概述下什么是图像归一化,其实就是通过一系列变换, 将待处理的原始图像转换成相应的唯一标准形式(该标准形式图像对平移、旋转、缩放等仿射变换具有不变特性)。图像归一化使得图像可以抵抗几何变换的攻击,它能够找出图像中的那些不变量,从而得知这些图像原本就是一样的或者一个系列的。
其性质:
- 归一化处理并没有改变图像的对比度
- 归一化处理很简单,假设原图像是8位灰度图像,那么读入的像素矩阵最大值为256,最小值为1,定义矩阵为I,J=I/256,就是归一化的图像矩阵,就是说归一化之后所有的像素值都在[0,1]区间内。
void normalize( InputArray src, // 输入图像
InputOutputArray dst, // 输出图像
double alpha = 1, // NORM_MINMAX时候低值,1,用来规范值,2.规范范围,并且是下限;
double beta = 0, // NORM_MINMAX时候高值,只用来规范范围并且是上限;
int norm_type = NORM_L2, // 只有alpha
int dtype = -1, // 当为负,输出在大小深度通道数都等于输入,当为正,输出只在深度与输如不同,不同的地方由dtype决定;
InputArray mask = noArray() // mask默认值为空
)
norm_type
提供了四种归一化的方法
NORM_MINMAX
NORM_INF
NORM_L1
NORM_L2
最常用的就是NORM_MINMAX
归一化方法。
归一化选择的数学公式类型介绍(norm_type) :
设数组中原有{A1,A2,A3…An}
NORM_L1:
NORM_INF:
NORM_L2:
NORM_MINMAX:(AK不属于{max(Ai)},min(Ai),当AK等于max(Ai)时p=1,等于min(Ai)时p=0)
举例说明:
最后dst * 255代表还原为图像的像素值,因为图像像素值为0~255