简介
对于前面的几篇文章的了解之后,相信大家已经对opencv的使用不再陌生了。还记得之前说过,opencv是多模块结构的嘛?我们之前所涉及的都是一些opencv的基本操作。在接下来的文章中,我们将讨论opencv中的另一个模块,imgproc模块。顾名思义,这就是opencv中的图像处理模块。即它中封装了许多关于图像处理的一些函数。今天我们所讲的直方图均衡化,就是图像处理中一个比较基础的方法。在开始之前,我们首先需要明白几个概念。
我们知道对于一个图像来说,它可以表示成为f(x, y)。而对于一个灰度图像来说,它的每一个值即为对应行(x),列(y)的强度。它的取值为(0-255)。而直方图就是图像中像素强度分布的图形表示方式。如下所示:
就像上图所表示的那样,它统计了一张图像中,每一个强度值(0-255)所对应像素的个数。
了解了直方图的含义之后,那么什么是均衡化呢?
所谓直方图均衡化,就是通过拉伸像素强度分布范围,从而增强图像对比度,获得更好地视觉效果的一种方法。如下图所示:
从上图可以看到,我们看到由第一张图的像素强度范围主要集中在中间部分,被扩展到了全部的强度范围。从而提高了图像的对比度。而这一结果正是直方图均衡化所要达到的。
至于直方图均衡化的原理,简单的可以看成是通过一个变化函数来把原来的强度值映射成为一个新的强度值,可以表示成g(x, y) = T(f(x, y)。f(x, y)为原始图像,而g(x, y)即为通过变化函数T(也成变化算子)所得到的新图像。至于变化函数T的类型在这里不再赘述。有兴趣可以参考任何一本图像处理教程。
OpenCV为我们提供了equalizeHist()函数来完成均衡化这一功能。其参数非常简单,只需传入原始图像以及要存储的输出图像。
示例:
#include <opencv2\highgui\highgui.hpp>
#include <opencv2\imgproc\imgproc.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main( int argc, char ** argv )
{
if( argc != 2 )
{
cout << "输入参数个数错误!" << endl;
return -1;
}
Mat src, dst;
char * source_window = "Source image";
char * equalized_window = "Equalized Image";
src = imread( argv[1], CV_LOAD_IMAGE_GRAYSCALE );
if( !src.data )
{
cout <<"图像加载失败!" << endl;
}
equalizeHist( src, dst );
namedWindow( source_window, CV_WINDOW_NORMAL );
namedWindow( equalized_window, CV_WINDOW_NORMAL );
imshow( source_window, src );
imshow( equalized_window, dst );
waitKey(0);
return 0;
}
(注:我们可以在上述imread函数中,通过第二个参数,选择CV_LOAD_IMAGE_GRAYSCALE来获得一个灰度图像,也可以利用我们在第二篇文章中所讲的cvtColor()函数来得到一个灰度图像)。
运行结果: