OpenCV 直方图均衡化的实现原理解析

 更新时间:2022年01月25日 09:27:57   作者:流楚丶格念  
直方图均衡化是通过拉伸像素强度分布范围来增强图像对比度的一种方法,今天通过本文给大家介绍OpenCV 直方图均衡化的实现原理解析,感兴趣的朋友跟随小编一起看看吧

直方图均衡化介绍

图像的直方图是什么?

图像直方图,是指对整个图像像在灰度范围内的像素值(0~255)统计出现频率次数,据此生成的直方图,称为图像直方图-直方图。直方图反映了图像灰度的分布情况。是图像的统计学特征。

简单来说:直方图是图像中像素强度分布的图形表达方式,它统计了每一个强度值所具有的像素个数。

例如下面这张图片,左图为灰度图,右图统计了这张图的所有像素值(0~255)对应的像素个数

在这里插入图片描述

更形象解释

更形象的来说,将下面像素格子对等为如上图的图像

假设有该图像数据8x8,像素值范围0~14共15个灰度等级,统计得到各个等级出现次数及直方图如下图所示:

在这里插入图片描述

则对上面抽象出来的图像(像素格子)进行像素与出现次数的统计得到下图左侧的表格,做出频率图如右图所示:

在这里插入图片描述

什么是直方图均衡化?

是一种提高图像对比度的方法,拉伸图像灰度值范围。

简单来说, 以上面狗狗的的直方图为例, 你可以看到像素主要集中在中间的一些强度值上。直方图均衡化要做的就是 拉伸 这个范围。就是下面蓝框框出来的范围就是像素主要几种区间。

在这里插入图片描述

见下图:绿圈 圈出了 像素分布率较低像素值,对其应用均衡化后(将中间蓝框像素分布较高的区间拉伸), 得到了中间图所示的直方图。均衡化的图像见下面右图.

在这里插入图片描述

直方图均衡化是如何实现的?

通过remap我们知道可以将图像灰度分布从一个分布映射到另外一个分布,然后在得到映射后的像素值即可。

映射关系如下:

在这里插入图片描述

其中源直方图 H(i), 累积分布 H’(i)函数,equalized()为重映射后的图像

直方图均衡化的作用

因为直方图均衡化处理之后,原来比较少像素的灰度会被分配到别的灰度去,像素相对集中, 处理后灰度范围变大,对比度变大,清晰度变大,所以能有效增强图像。

直方图均衡化是图像处理领域中利用图像直方图对对比度进行调整的方法。这种方法通常用来增加许多图像的局部对比度,尤其是当图像的有用数据的对比度相当接近的时候。通过这种方法,亮度可以更好地在直方图上分布。这样就可以用于增强局部的对比度而不影响整体的对比度,直方图均衡化通过有效地扩展常用的亮度来实现这种功能。

总的来说,直方图均衡化是用来增强对比度的

直方图均衡化步骤

  1. 加载源图像
  2. 转为灰度图
  3. EqualizeHist 对直方图均衡化
  4. 显示均衡化后图像.

相关API

equalizeHist

cv::equalizeHist(
	InputArray src,	// 输入图像,必须是8-bit的单通道图像
	OutputArray dst	// 输出结果
)

代码示例

灰度图均值化

在这里插入图片描述

#include <iostream>
#include <math.h>
#include <opencv2/opencv.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/highgui/highgui_c.h> 

using namespace cv;
int main(int argc, char** argv) 
{
	Mat src, dst;
	src = imread("./test2.jpg");
	if (!src.data) {
		printf("could not load image...\n");
		return -1;
	}
	cvtColor(src, src, CV_BGR2GRAY);
	equalizeHist(src, dst);
	char INPUT_T[] = "input image";
	char OUTPUT_T[] = "result image";
	namedWindow(INPUT_T, CV_WINDOW_AUTOSIZE);
	namedWindow(OUTPUT_T, CV_WINDOW_AUTOSIZE);
	imshow(INPUT_T, src);
	imshow(OUTPUT_T, dst);
	waitKey(0);
	return 0;
}

彩色图均值化

在这里插入图片描述

#include <iostream>
#include <math.h>
#include <opencv2/opencv.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/highgui/highgui_c.h> 

using namespace cv;
using namespace std;
int main(int argc, char*argv)
{
	Mat src, dst, dst1;
	src = imread("./test2.jpg");
	if (!src.data)
	{
		printf("could not load image...\n");
		return -1;
	}
	char input[] = "input image";
	char output[] = "histogram iamge";
	namedWindow(input, CV_WINDOW_AUTOSIZE);
	namedWindow(output, CV_WINDOW_AUTOSIZE);
	imshow(input, src);
	// 分割通道
	vector<Mat>channels;
	split(src, channels);
	Mat blue, green, red;
	blue = channels.at(0);
	green = channels.at(1);
	red = channels.at(2);
	// 分别对BGR通道做直方图均衡化
	equalizeHist(blue, blue);
	equalizeHist(green, green);
	equalizeHist(red, red);
	// 合并通道
	merge(channels, dst);
	imshow(output, dst);
	waitKey(0);
	return 0;
}

到此这篇关于OpenCV 直方图均衡化的文章就介绍到这了,更多相关OpenCV 直方图均衡化内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • c语言实现两个值互相交换的函数

    c语言实现两个值互相交换的函数

    本文通过代码给大家介绍c语言实现两个值互相交换的函数,通过实例代码给大家讲解的很详细,具有一定的参考借鉴价值,对c语言两个值互换函数相关知识感兴趣的朋友一起看看吧
    2021-05-05
  • C++面试八股文之STL标准模板库使用详解

    C++面试八股文之STL标准模板库使用详解

    这篇文章主要为大家介绍了C++面试八股文之STL标准模板库使用详解,<BR>有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-06-06
  • C语言 智能指针 shared_ptr 和 weak_ptr

    C语言 智能指针 shared_ptr 和 weak_ptr

    这篇文章主要介绍了C语言 智能指针 shared_ptr 和 weak_ptr,weak_ptr引入可以解决shared_ptr交叉引用时无法释放资源的问题,下面来学习具体相关内容吧,需要的朋友可以参考一下
    2022-04-04
  • c语言5个常用的排序算法实例代码

    c语言5个常用的排序算法实例代码

    这篇文章主要介绍了c语言5个常用的排序算法实例代码,分享了相关代码示例,小编觉得还是挺不错的,具有一定借鉴价值,需要的朋友可以参考下
    2018-02-02
  • 超详细讲解C++的三种函数传递方式

    超详细讲解C++的三种函数传递方式

    这个文章我将把我学习的有关函数传递形式的知识做个总结,相信很多刚入门的同学看到许多文章五花八门的形参会感到头疼,但本质上无非就是我要说的三种传递形式,快来跟我一起学习吧
    2022-05-05
  • C++实现词法分析器

    C++实现词法分析器

    这篇文章主要为大家详细介绍了C++实现词法分析器的相关代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-01-01
  • C语言之浮点数的表示与储存方式

    C语言之浮点数的表示与储存方式

    这篇文章主要介绍了C语言之浮点数的表示与储存方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-03-03
  • C++ 容器 Vector 的使用方法

    C++ 容器 Vector 的使用方法

    这篇文章主要介绍了C++ 容器 Vector 的使用方法,Vector 是一个能够存放任意类型的动态数组,有点类似数组,是一个连续地址空间,下文更多详细内容的介绍,需要的小伙伴可以参考一下
    2022-06-06
  • Linux管道揭秘之匿名管道连接进程世界的方法

    Linux管道揭秘之匿名管道连接进程世界的方法

    文章介绍了Linux中的管道(Pipe)概念,包括其定义、作用、类型、工作原理以及如何在父子进程间使用,匿名管道是进程间通信的一种机制,通过pipe()系统调用创建,具有读端和写端文件描述符,文章详细解释了匿名管道的创建、使用流程、4种情况和5种特性
    2024-11-11
  • GCC编译过程(预处理,编译,汇编,链接)及GCC命令详解

    GCC编译过程(预处理,编译,汇编,链接)及GCC命令详解

    文章详细介绍了GCC编译器的工作原理,包括预处理、编译、汇编和链接四个主要阶段,每个阶段都有其特定的任务和输出文件,文章还解释了如何使用GCC命令选项来查看每个阶段的输出,以及如何通过调整编译选项来优化程序性能或调试问题,感兴趣的朋友跟随小编一起看看吧
    2024-11-11

最新评论