实质上是对图像进行非线性拉伸,重新分配图像象元值,使一定灰度范围内象元值的数量大致相等。这样,原来直方图中间的峰顶部分对比度得到增强,而两侧的谷底部分对比度降低,输出图像的直方图是一个较平的分段直方图:如果输出数据分段值较小的话,会产生粗略分类的视觉效果。
直方图是表示数字图像中每一灰度出现频率的统计关系。
直方图能给出图像灰度范围、每个灰度的频度和灰度的分布、整幅图像的平均明暗和对比度等概貌性描述。
灰度直方图是灰度级的函数, 反映的是图像中具有该灰度级像素的个数,其横坐标是灰度级r, 纵坐标是该灰度级出现的频率( 即像素的个数) pr( r) ,
整个坐标系描述的是图像灰度级的分布情况,由此可以看出图像的灰度分布特性,
即若大部分像素集中在低灰度区域, 图像呈现暗的特性; 若像素集中在高灰度区域, 图像呈现亮的特性。
图1所示就是直方图均衡化, 即将随机分布的图像直方图修改成均匀分布的直方图。
基本思想是对原始图像的像素灰度做某种映射变换, 使变换后图像灰度的概率密度呈均匀分布。
这就意味着图像灰度的动态范围得到了增加, 提高了图像的对比度。
图1 直方图均衡化
彩色lena图像的直方图均衡化实现:
#include
#include
#include
using namespace cv;
int main(int argc, const char * argv[])
{
Mat image = imread("/Users/shandiangou/Downloads/lena.png");
Mat gray;
if(image.empty())
{
std::cout <<"图片打开失败"<(i);
int intensity = cvRound(bin_val*hist_height/max_val);
rectangle(hist_img, Point(i*scale, hist_height-1), Point((i+1)*scale-1, hist_height-intensity), CV_RGB(255,255,255));
}
imshow("原图灰度直方图",hist_img);
waitKey();
Mat gray1, imageRGB[3];
split(image, imageRGB);
for (int i =0;i<3;i++)
{equalizeHist(imageRGB[i],imageRGB[i]);
}
merge(imageRGB, 3, image);
imshow("直方图均衡化后lena",image);
waitKey();
cvtColor(image, gray1, CV_RGB2GRAY);
calcHist(&gray1, 1, channels, Mat(), hist, 1, hist_size, ranges, true, false);
minMaxLoc(hist, 0,&max_val, 0,0);
for(int i=1;i(i);
int intensity = cvRound(bin_val*hist_height/max_val);
rectangle(hist_img, Point(i*scale, hist_height-1), Point((i+1)*scale-1, hist_height-intensity), CV_RGB(255,255,255));
}
imshow("均衡后灰度直方图",hist_img);
waitKey();
return 0;
}
结果图分别是原图、原图的灰度直方图、直方图均衡化后图、直方图均衡化后图的灰度直方图;可以清楚的看到直方图均衡的效果。
二、基于拉普拉斯算子的图像增强;
#include
#include
#include
using namespace cv;
int main(int argc, char *argv[])
{
Mat image = imread("/Users/shandiangou/Downloads/lena.png");
if (image.empty())
{
std::cout << "打开图片失败,请检查" << std::endl;
return -1;
}
imshow("原图像", image);
waitKey();
Mat imageEnhance;
Mat kernel = (Mat_(3, 3) << 0, -1, 0, 0, 5, 0, 0, -1, 0);
filter2D(image, imageEnhance, CV_8UC3, kernel);
imshow("拉普拉斯算子图像增强效果", imageEnhance);
waitKey();
return 0;
}
伽马变换主要用于图像的校正,将灰度过高或者灰度过低的图片进行修正,增强对比度。变换公式就是对原图像上每一个像素值做乘积运算:
伽马变换对图像的修正作用其实就是通过增强低灰度或高灰度的细节实现的,从伽马曲线可以直观理解:
γ值以1为分界,值越小,对图像低灰度部分的扩展作用就越强,值越大,对图像高灰度部分的扩展作用就越强,通过不同的γ值,就可以达到增强低灰度或高灰度部分细节的作用。
伽马变换对于图像对比度偏低,并且整体亮度值偏高(对于于相机过曝)情况下的图像增强效果明显,此时gamma值>1。#include
#include
#include
#include
using namespace cv;
using namespace std;
// Normalizes a given image into a value range between 0 and 255.
Mat norm_0_255(const Mat& src) {
// Create and return normalized image:
Mat dst;
switch(src.channels()) {
case 1:
cv::normalize(src, dst, 0, 255, NORM_MINMAX, CV_8UC1);
break;
case 3:
cv::normalize(src, dst, 0, 255, NORM_MINMAX, CV_8UC3);
break;
default:
src.copyTo(dst);
break;
}
return dst;
}
int main(int argc, const char *argv[]) {
// Get filename to the source image:
// Load image & get skin proportions:
Mat image = imread("/Users/shandiangou/Downloads/guobao.jpeg");
// Convert to floating point:
Mat X;
image.convertTo(X, CV_32FC1);
//image.convertTo(X, CV_32F);
// Start preprocessing:
Mat I;
float gamma = 3;
pow(X, gamma, I);
// Draw it on screen:
imshow("Original Image", image);
waitKey();
imshow("Gamma correction image", norm_0_255(I));
// Show the images:
waitKey();
// Success!
return 0;
}