OpenCV-Python教程:直方图均衡(equalizeHist,createCLAHE)

原文链接:http://www.juzicode.com/opencv-python-equalizehist-createclahe

返回Opencv-Python教程

直方图均衡就是让图像的像素个数多的灰度级拉的更宽,对像素个数少的灰度级进行压缩,从而达到提高图像的对比度的目的。从直方图的直观效果来看,就是让y轴比较高的位置变矮在x轴方向膨胀,y轴比较矮的位置变高并在x轴方向压缩。

1、直方图均衡equalizeHist

equalizeHist()可以实现图像的直方图均衡,它是一种全局直方图均衡,考量的对象是整幅图像。

接口形式:

cv2.equalizeHist(src[, dst]) ->dst
  • 参数含义:
  • src:输入图像,8bit单通道;
  • dst:均衡后的输出图像,类型同src;

下面这个例子读入图像后做直方图均衡,然后对比其直方图:

import numpy as np
import matplotlib.pyplot as plt
import cv2
print('VX公众号: 桔子code / juzicode.com')
print('cv2.__version__:',cv2.__version__)
plt.rc('font',family='Youyuan',size='9')
plt.rc('axes',unicode_minus='False')

img_src = cv2.imread('..\\samples\\data\\fruits.jpg',0) 
img_dst = cv2.equalizeHist(img_src) 

histSize = 512
histRange = (0, 256)  
hist_src = cv2.calcHist([img_src], [0], None, [histSize], histRange) 
hist_dst = cv2.calcHist([img_dst], [0], None, [histSize], histRange)  

#显示图像
fig,ax = plt.subplots(2,2)
ax[0,0].set_title('hist_src')
ax[0,0].plot(hist_src) 
ax[0,1].set_title('hist_dst')
ax[0,1].plot(hist_dst)
ax[1,0].set_title('src')
ax[1,0].imshow(cv2.cvtColor( img_src, cv2.COLOR_BGR2RGB),'gray')
ax[1,1].set_title('dst') 
ax[1,1].imshow(cv2.cvtColor(img_dst,cv2.COLOR_BGR2RGB),'gray')  
#ax[0,0].axis('off');ax[0,1].axis('off');
ax[1,0].axis('off');ax[1,1].axis('off')#关闭坐标轴显示
plt.show()  

运行结果:

从运行结果看,原来整体较暗的图像,经过直方图均衡后,整体要亮一些。这点也和直方图显示的效果是一样的,原图的直方图整体要偏左,而经过直方图均衡后的直方图在x轴上分布更均匀。

2、自适应直方图均衡createCLAHE

equalizeHist()方法是一种全局直方图均衡方法,在某些场合可能会导致原本对比度高的区域反而变得更低,像下面这个例子中原图上半部分的树叶对比度高,但是下半部分对比度低,如果使用equalizeHist()方法得到的图片如下图右下部分所示:

直方图均衡处理后虽然树叶下半部分的细节都呈现出来了 ,但是上半部分却因为过亮导致丢失了很多细节。

CLAHE是对比度抑制自适应直方图均衡(Contrast Limited Adaptive Histogram Equalization)的简称,不同于普通的直方图均衡,它是一种局部直方图均衡方法。

调用接口分2步,先创建实例,再调用apply()方法:

cv2.createCLAHE([, clipLimit[, tileGridSize]]) ->retval
dst=retval.apply(src)
  • 参数含义:
  • clipLimit:对比对限制阈值,默认为40;
  • tileGridSize:直方图均衡的栅格尺寸,输入图像将会按照该尺寸分隔后进行局部直方图均衡,默认是8×8大小;
  • src:输入图像,8bit单通道;
  • dst:均衡后的输出图像,类型同src;

下面这个例子将普通直方图均衡和自适应直方图均衡做对比:

import numpy as np
import matplotlib.pyplot as plt
import cv2
print('VX公众号: 桔子code / juzicode.com')
print('cv2.__version__:',cv2.__version__)
plt.rc('font',family='Youyuan',size='9')
plt.rc('axes',unicode_minus='False')

img_src = cv2.imread('..\\samples\\picture\\leaf2.jpeg',0) 
#普通直方图均衡
img_dst = cv2.equalizeHist(img_src)
#自适应直方图均衡 
clahe = cv2.createCLAHE(clipLimit=5.0, tileGridSize=(8,8))
img_dst_clahe = clahe.apply(img_src)

histSize = 256
histRange = (0, 256) 
hist_src = cv2.calcHist([img_src], [0], None, [histSize], histRange) 
hist_dst = cv2.calcHist([img_dst], [0], None, [histSize], histRange)  
hist_dst_clahe = cv2.calcHist([img_dst_clahe], [0], None, [histSize], histRange)  

#显示图像
fig,ax = plt.subplots(2,3)
ax[0,0].set_title('hist_src')
ax[0,0].plot(hist_src) 
ax[0,1].set_title('hist_dst')
ax[0,1].plot(hist_dst)
ax[0,2].set_title('hist_dst_clahe')
ax[0,2].plot(hist_dst_clahe)
ax[1,0].set_title('img_src')
ax[1,0].imshow(cv2.cvtColor( img_src, cv2.COLOR_BGR2RGB),'gray')
ax[1,1].set_title('img_dst') 
ax[1,1].imshow(cv2.cvtColor(img_dst,cv2.COLOR_BGR2RGB),'gray')  
ax[1,2].set_title('img_dst_clahe') 
ax[1,2].imshow(cv2.cvtColor(img_dst_clahe,cv2.COLOR_BGR2RGB),'gray')  
#ax[0,0].axis('off');ax[0,1].axis('off');
ax[1,0].axis('off');ax[1,1].axis('off');ax[1,2].axis('off')#关闭坐标轴显示
plt.show()  

运行结果:

从运行结果可以看到,使用自适应直方图均衡后,不但树叶下半部分的细节呈现出来了 ,而且上半部分的细节也得到了保留。

扩展阅读:

  1. OpenCV-Python教程
  2. OpenCV-Python教程:直方图(calcHist)与绘制

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注