效用:
直方图是多种空域处理技术的基础,直方图操作能有效地用于图像增强。
原理:
对图像进行非线性拉伸,使得变换后的图像直方图分布均匀。
计算步骤:
1)计算原图像的直方图
2)根据直方图计算各灰度出现的概率
3)计算原图象的关于各个灰度级的累积分布函数
4)根据公式求取像素映射关系
5)灰度映射
代码 1:
//不支持OpenCV的ROI
void GetHistogram(const Mat &image, int *histogram)
{
memset(histogram, 0, 256 * sizeof(int));
//计算直方图
int pixelCount = image.cols*image.rows;
uchar *imageData = image.data;
for (int i = 0; i <= pixelCount - 1; ++i)
{
int gray = imageData[i];
histogram[gray]++;
}
}
void EqualizeHistogram(const Mat &srcImage, Mat &dstImage)
{
CV_Assert(srcImage.type() == CV_8UC1);
dstImage.create(srcImage.size(), srcImage.type());
// 计算直方图
int histogram[256];
GetHistogram(srcImage, histogram);
// 计算分布函数(也就是变换函数f(x))
int numberOfPixel = srcImage.rows*srcImage.cols;
int LUT[256];
LUT[0] = 1.0*histogram[0] / numberOfPixel*255;
int sum = histogram[0];
for (int i = 1; i <= 255; ++i)
{
sum += histogram[i];
LUT[i] = 1.0*sum / numberOfPixel * 255;
}
// 灰度变换
uchar *dataOfSrc = srcImage.data;
uchar *dataOfDst = dstImage.data;
for (int i = 0; i <= numberOfPixel - 1; ++i)
dataOfDst[i] = LUT[dataOfSrc[i]];
}
代码 2:
// opencv 库函数调用
equalizeHist(src, dst);