图像像素的类型转换与归一化
在计算机中,图像的默认存储格式是8位,在OpenCV中,可以将图像的数据类型进行转换,也可以将数据的取值空间进行转换,即将0-255的范围压缩为0-1的范围内,称为归一化。
数据类型的转化和归一化的关系
实际上数据类型转换是为归一化做准备的,试想一下,将一个整形的数据(0-255)压缩为0-1的范围,那么势必会出现变成浮点数,而这个时候如果数据的类型还是整形,那么小数点后的内容就会被省略,归一化就无法完成了,数据类型的转换就是为了这种情况准备的。
以下是Mat的数据类型和常规类型对照
Mat_<uchar>---------CV_8U
Mat<char>-----------CV_8S
Nat_<short>---------CV_16S
Mat_<ushort>--------CV_16U
Mat_<int>-----------CV_32S
Mat_<float>----------CV_32F
Mat_<double>--------CV_64F
CV_8U 8位无符号整数 (0…..255)
CV_8S 8 位符号整数 (-128…..127)
CV_16U 16 位无符号整数 (0……65535)
CV_16S 16 位符号整数 (-32768…..32767)
CV_32S 32 位符号整数 (-2147483648……2147483647)
CV_32F 32 位浮点数 (-FLT_MAX ………FLT_MAX,INF,NAN)
CV_64F 64 位浮点数 (-DBL_MAX ……….DBL_MAX,INF,NAN)
数据类型转换和归一化
Mat dst;
image.convertTo(image,CV_32F);//将image转换为其他类型
normalize(image, dst, 1.0, 0, NORM_MINMAX);
//输入图像,输出图像,(double)高值,(double)低值,norm_type(归一化方法)
通过convertTo()函数即可转换数据类型,通过normaliz()函数可以归一化
其中归一化方法有如下几种
NORM_INF = 1,
NORM_L1 = 2,
NORM_L2 = 4,
NORM_L2SQR = 5,
NORM_HAMMING = 6,
NORM_HAMMING2 = 7,
NORM_TYPE_MASK = 7,
NORM_RELATIVE = 8,
NORM_MINMAX = 32,
在归一化前,一定要将数据转换,这两个操作时绑定在一起的。
图像的放缩与插值
最常见的四种插值算法
INTER_NEAREST = 0;
INTER_LINEAR = 1;
INTER_CUBIC = 2;
INTER_LANCZOS4 = 4;
具体实现:
void Demo::resize_demo(Mat &image) {
Mat zoomin, zoomout;
int w = image.cols;
int h = image.rows;
resize(image, zoomout, Size(w/2, h/2), 0, 0, INTER_LINEAR);
resize(image, zoomin, Size(w * 2, h * 2), 0, 0, INTER_LINEAR);
//输入,输出,目标尺寸,fx(水平方向与原图比例),fy(垂直方向与原图比例),插值方式
//注:目标尺寸和(fx,fy)不能同时为0
imshow("缩小", zoomout);
imshow("放大", zoomin);
}
图像的翻转与旋转
翻转十分简单,一个函数即可实现
flip(image, dst01, 0);//翻转
//s输入,输出,翻转参数(0为上下翻转,1为左右翻转,-1为对角线翻转)
旋转相对复杂一些,需要首先获得旋转矩阵,然后根据矩阵进行变换
Mat M;//旋转矩阵
int w = image.cols;
int h = image.rows;
M = getRotationMatrix2D(Point2f(w / 2, h / 2),45,1.0);
//获取旋转矩阵(旋转中心,旋转角度,放缩比例)
warpAffine(image, dst02, M, image.size(), 1, 0,Scalar(255,0,0));
//输入,输出,旋转矩阵,图片尺寸,插值方法,边界处理方法,背景颜色
其中图片尺寸可以通过数学计算得到精确的新图片尺寸值
计算方法如下:
double sin = abs(M.at<double>(0, 0));
double cos = abs(M.at<double>(0, 1));
int nw = cos * w + sin * h;
int nh = cos * h + sin * w;