博客
关于我
直方图均衡化算法原理与c++实现
阅读量:798 次
发布时间: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/

你可能感兴趣的文章
MQ 重复消费如何解决?
查看>>
mqtt broker服务端
查看>>
MQTT 保留消息
查看>>
MQTT 持久会话与 Clean Session 详解
查看>>
MQTT工作笔记0007---剩余长度
查看>>
MQTT工作笔记0009---订阅主题和订阅确认
查看>>
Mqtt搭建代理服务器进行通信-浅析
查看>>
MS Edge浏览器“STATUS_INVALID_IMAGE_HASH“兼容性问题
查看>>
ms sql server 2008 sp2更新异常
查看>>
MS UC 2013-0-Prepare Tool
查看>>
MSBuild 教程(2)
查看>>
msbuild发布web应用程序
查看>>
MSB与LSB
查看>>
MSCRM调用外部JS文件
查看>>
MSCRM调用外部JS文件
查看>>
MSEdgeDriver (Chromium) 不适用于版本 >= 79.0.313 (Canary)
查看>>
MsEdgeTTS开源项目使用教程
查看>>
msf
查看>>
MSSQL数据库查询优化(一)
查看>>
MSSQL数据库迁移到Oracle(二)
查看>>