OpenCV自学笔记25. 直方图均衡化
1、直方图均衡化的原理
直方图均衡化往往能够使图像的对比度增强,它增强了靠近直方图极大值附近的对比度,减小了极小值附近的对比度。
它的数学原理如下(摘自维基百科):
跳过数学原理,其实直方图均衡化的步骤非常简单,看一个例子很容易明白。
下文引用自:http://www.cnblogs.com/tianyalu/p/5687782.html,原作者写得非常清楚,所以就直接引用了
2、直方图均衡化的实现
在实现部分,我分别通过OpenCV中提供的api,以及自己用python写这两种方式验证了直方图均衡化的原理,完整的程序如下。
注:我用python写的代码比较差,直接用循环比较好理解,也没有用numpy,所以运行起来比较慢。
- opencv实现
- python自己动手实现
先来看看效果吧,第一张图是原始的灰度图,第二张是采用OpenCV提供的equalizeHist方法得到的效果图,第三张是自己编写python的效果图。
myhistogram.py
# -*- coding:utf-8 -*-
import cv2
import numpy as np
'''
替换像素
old_val : 原始像素值
new_val : 新像素值
image : 要替换像素的图片
'''
def replace(old_val, new_val, image):
for i in range(image.shape[0]):
for j in range(image.shape[1]):
if image[i][j] == old_val:
image[i][j] = new_val
# 读入图片
image = cv2.imread("images/my_wife2.jpg", 0) # 363 236
cv2.imshow("image", image) # 显示原始图片
# 用OpenCV 提供的equalizeHist方法,进行直方图均衡化
eq = cv2.equalizeHist(image)
cv2.imshow("Histogram Equalization", np.hstack([eq]))
# 下面自己写直方图均衡化
rows = image.shape[0]
cols = image.shape[1]
nums = rows * cols
bin = [0] * 256 # 分为256个bin,类似桶排序的思想
# 统计个数
for i in range(rows):
for j in range(cols):
bin[image[i][j]] += 1
# 根据累积概率计算新的灰度值,并替换旧的灰度值
p = 0
for i in range(0, 256):
p += bin[i] / nums
val = (int)(p * 255)
replace(i, val, image)
# 显示直方图均衡化后的图像
cv2.imshow("after histogram", image)
cv2.waitKey(0)
然后,我绘制了这三张结果图的直方图,如下。可见直方图均衡化相当于将直方图拉伸抻平了。
绘制直方图的代码为:
from matplotlib import pyplot as plt
'''
绘制直方图 代码参考自
http://blog.youkuaiyun.com/jnulzl/article/details/47171549
'''
def drawHist(image):
# 图像直方图
hist = cv2.calcHist([image], [0], None, [256], [0, 256])
plt.figure() # 新建一个图像
plt.title("Grayscale Histogram") # 图像的标题
plt.xlabel("Bins") # X轴标签
plt.ylabel("# of Pixels") # Y轴标签
plt.plot(hist) # 画图
plt.xlim([0, 256]) # 设置x坐标轴范围
plt.show() # 显示图像
参考:
http://www.cnblogs.com/tianyalu/p/5687782.html
http://blog.youkuaiyun.com/superjunenaruto/article/details/52431941
http://blog.youkuaiyun.com/jnulzl/article/details/47171549
就这样,拜拜~