对于以像素存储的数字图像来讲,可对像素进行相应的操做,可获得处理事后的图像。而对像素邻域进行计算的的叫滤波,对单像素进行变换的叫映射,而这个映射关系就是变换函数。html
本文主要介绍的一些主要的灰度变换函数。web
反转变换可将图像的灰度级进行反转,公式可参考下式:
数组
void inverse(Mat &img) { // 初始化图像迭代器 MatIterator_<uchar> srcIterStart = img.begin<uchar>(); MatIterator_<uchar> srcIterEnd = img.end<uchar>(); while (srcIterStart != srcIterEnd) { *srcIterStart = 255 - *srcIterStart; srcIterStart++; } }
反转图像的使用场景通常用于对原始图像难以分析出不一样之处,例如分析乳房组织时,用反转图像更易观察。app
对数变换可分为对数变换和反对数变换,而反对数变换是属于伽马变化(幂律变换)的范围。对数变换公式可参考下列公式:
svg
void log_image(Mat &img, uchar rate = 1) { // 初始化图像迭代器 MatIterator_<uchar> srcIterStart = img.begin<uchar>(); MatIterator_<uchar> srcIterEnd = img.end<uchar>(); while (srcIterStart != srcIterEnd) { *srcIterStart = static_cast <uchar> (rate * log(1 + *srcIterStart)); srcIterStart++; } } // 单通道图像标定 Mat standardImageSingle(Mat &src, int rank = 255) { Mat dst = src.clone(); // 查找数组内的最大值与最小值 int min = 255, max = 0; for (int i = 0; i < src.rows; i++) for (int j = 0; j < src.cols; j++) { if (dst.at<uchar>(i, j) < min) min = dst.at<uchar>(i, j); if (dst.at<uchar>(i, j) > max) max = dst.at<uchar>(i, j); // cout << num[i*src.rows + j] <<endl; } // 对图像像素值进行标定 for (int i = 0; i < src.rows; i++) for (int j = 0; j < src.cols; j++) { dst.at<uchar>(i, j) = saturate_cast<int>(rank * ((dst.at<uchar>(i, j) - min) * 1.0 / (max - min))); } return dst; }
对数变换通常不用于图像的明暗拉伸变换,主要用于傅里叶频谱的缩放,保证低频细节不会被线性缩放丢失,使得频谱可见细节更加明显。所以,对数变换主要用于频谱的标定。函数
伽马变换是一种经常使用的变换函数,其公式主要参考下列公式:
spa
// 单通道图像标定——数组存储 void standardImageSingleArray(Mat &src, double* num, int rank = 255) { // 查找数组内的最大值与最小值 double min = 1000000000, max = -1000000000; for (int i = 0; i < src.rows; i++) for (int j = 0; j < src.cols; j++) { if (num[i*src.cols + j] < min) min = num[i*src.cols + j]; if (num[i*src.cols + j] > max) max = num[i*src.cols + j]; // cout << num[i*src.cols + j] <<endl; } // 对图像像素值进行标定 for (int i = 0; i < src.rows; i++) for (int j = 0; j < src.cols; j++) { src.at<uchar>(i, j) = saturate_cast<int>(rank * ((num[i*src.cols + j] - min) / (max - min))); } } void gama_image(Mat &img, double gama, double rate = 1) { double* num = new double[img.rows*img.cols]; int n = 0; // 初始化图像迭代器 MatIterator_<uchar> srcIterStart = img.begin<uchar>(); MatIterator_<uchar> srcIterEnd = img.end<uchar>(); while (srcIterStart != srcIterEnd) { if (*srcIterStart == 0) num[n] = 1.0; else num[n] = rate * pow(*srcIterStart, gama); n++; srcIterStart++; } standardImageSingleArray(img, num); }
伽马变换通常用于明暗变换,加强对比度, 将暗像素图像变换到亮像素图像,将亮像素图像变换到安像素图像。用于获取,显示图像的各类设备通常都是根据幂律来产生相应的,此现象称之为幂律相应现象。而幂律相应会致使获取或显示的图像过于阴暗(通常幂律响应的指数大于1),因此就须要进行伽马变换,这一操做一般称之为伽马校订。通常各种显示器件中都会内置伽马校订。code
上图中,原图就比如输入,经 的变换至关于器件类的幂律响应。可见比原图要阴暗的多。
在原图的基础上先进行 的变换至关于先进行伽马校订,可见图像明显变明亮了许多,以后再通过幂律响应后,图像效果对比未通过校订的图像要明亮一些。xml
像素值一般以8bit、16比特、32bit、64bit来存储像素值的,而每一个比特都至关于以一个通道,咱们能够获取每一个比特平面的图像,下列实验以8bit图像为例为你们展现。咱们能够经过与操做获取相应的比特平面值。htm
// 获取图像细节 Mat getImageDetails(Mat src, uchar bite = 1) { Mat dst = src.clone(); for (int i = 0; i < src.rows; i++) for (int j = 0; j < src.cols; j++) { dst.at<uchar>(i, j) = src.at<uchar>(i, j) & bite; } return dst; }
各比特平面效果图:
比特平面叠加效果图:
上图中低比特平面是图像的细节部分,高比特是轮廓部分。图像叠加高四层比特平面后的图像与原图像差异不大,由于丢失的细节部分对于人类的视觉来讲基本是不可见的,所以此项实验可得出,对于图像的存储可只存储高四层比特平面,减小了50%的存储空间。