博客
关于我
直方图均衡化算法原理与c++实现
阅读量:799 次
发布时间:2023-04-15

本文共 2416 字,大约阅读时间需要 8 分钟。

直方图均衡是一种基础的图像增强算法,核心目标是通过非线性拉伸,使图像的灰度级分布更加均匀,从而提升图像的对比度。理解这一算法的优势与局限,对于实际应用至关重要。

优势分析

直方图均衡在处理对比度不足的图像时表现尤为突出。特别是在背景和前景都较亮或较暗的场景中,能够显著增强细节对比度。在技术实现上,该算法计算量较小,完全符合实时处理要求。此外,该算法是可逆的,意味着一旦掌握均衡化函数,就可以准确恢复原始图像。

局限性考量

尽管直方图均衡具有显著的应用价值,但其单一性也带来了局限性。该算法对图像进行处理时,通常会忽略对某些特定区域的精细控制,这可能导致背景噪声增强或重要细节对比度降低。因此,在对特征提取要求较高的场景中,应当谨慎应用这一技术。

算法原理

直方图均衡的核心在于设计一个灰度变换函数f(x),确保输出灰度级不低于输入,同时保持输出灰度范围与输入一致。根据冈萨雷斯的描述,一个经典的变换函数能够满足这一条件,具体推导过程涉及概率论知识。

该变换函数通过直方图数据计算每个灰度级的累积频率,最终确定输出灰度值。这种方法能够有效均衡图像的灰度分布,使其更具对比度。

代码实现

以下是基于OpenCV的直方图均衡实现代码:

#include 
#include
#include
void Histogram_equalization(cv::Mat& src, cv::Mat& dst) { CV_Assert(src.depth() == CV_8U); src.copyTo(dst); int nr = src.rows; int nc = src.cols; int pixnum = nr * nc; if (src.channels() == 1) { int gray[256] = { 0 }; for (int i = 0; i < nr; ++i) { const uchar* ptr = src.ptr
(i); for (int j = 0; j < nc; ++j) { gray[ptr[j]]++; } } int LUT[256]; int sum = 0; for (int k = 0; k < 256; ++k) { sum += gray[k]; LUT[k] = 255 * sum / pixnum; } for (int i = 0; i < nr; ++i) { const uchar* ptr_src = src.ptr
(i); uchar* ptr_dst = dst.ptr
(i); for (int j = 0; j < nc; ++j) { ptr_dst[j] = LUT[ptr_src[j]]; } } } else { int B[256] = { 0 }; int G[256] = { 0 }; int R[256] = { 0 }; for (int i = 0; i < nr; ++i) { for (int j = 0; j < nc; ++j) { B[src.at
(i, j)[0]]++; G[src.at
(i, j)[1]]++; R[src.at
(i, j)[2]]++; } } int LUT_B[256], LUT_G[256], LUT_R[256]; int sum_B = 0, sum_G = 0, sum_R = 0; for (int k = 0; k < 256; ++k) { sum_B += B[k]; sum_G += G[k]; sum_R += R[k]; LUT_B[k] = 255 * sum_B / pixnum; LUT_G[k] = 255 * sum_G / pixnum; LUT_R[k] = 255 * sum_R / pixnum; } for (int i = 0; i < nr; ++i) { for (int j = 0; j < nc; ++j) { dst.at
(i, j)[0] = LUT_B[src.at
(i, j)[0]]; dst.at
(i, j)[1] = LUT_G[src.at
(i, j)[1]]; dst.at
(i, j)[2] = LUT_R[src.at
(i, j)[2]]; } } }}int main() { cv::Mat src = cv::imread("art.jpg"); if (src.empty()) { return -1; } cv::cvtColor(src, src, CV_RGB2GRAY); cv::Mat dst; Histogram_equalization(src, dst); cv::namedWindow("src"); cv::imshow("src", src); cv::namedWindow("dst"); cv::imshow("dst", dst); cv::waitKey(0);}

效果展示

通过上述代码处理后的结果清晰可见,原图与输出图像的对比度得到显著提升,细节更加丰富,图像整体效果更具视觉吸引力。

转载地址:http://frrfk.baihongyu.com/

你可能感兴趣的文章
MySQL中的IO问题分析与优化
查看>>
MySQL中的ON DUPLICATE KEY UPDATE详解与应用
查看>>
mysql中的rbs,SharePoint RBS:即使启用了RBS,内容数据库也在不断增长
查看>>
mysql中的undo log、redo log 、binlog大致概要
查看>>
Mysql中的using
查看>>
MySQL中的关键字深入比较:UNION vs UNION ALL
查看>>
mysql中的四大运算符种类汇总20多项,用了三天三夜来整理的,还不赶快收藏
查看>>
mysql中的字段如何选择合适的数据类型呢?
查看>>
MySQL中的字符集陷阱:为何避免使用UTF-8
查看>>
mysql中的数据导入与导出
查看>>
MySQL中的时间函数
查看>>
mysql中的约束
查看>>
MySQL中的表是什么?
查看>>
mysql中穿件函数时候delimiter的用法
查看>>
Mysql中索引的分类、增删改查与存储引擎对应关系
查看>>
Mysql中索引的最左前缀原则图文剖析(全)
查看>>
MySql中给视图添加注释怎么添加_默认不支持_可以这样取巧---MySql工作笔记002
查看>>
Mysql中获取所有表名以及表名带时间字符串使用BetweenAnd筛选区间范围
查看>>
Mysql中视图的使用以及常见运算符的使用示例和优先级
查看>>
Mysql中触发器的使用示例
查看>>