'''
1 问 题:图像不清晰
2 解决方法:图像增强。图像增强是指按特定的需要突出一幅图像中的某些信息,并同时削弱或去除某些不需要的信息。
3 图像增强分类:
(1)频域处理法:傅里叶变换、小波变换、卷积。
(2)空域处理法:处理灰度图像像素。eg:直方图增强
4 灰度直方图:灰度直方图反应不同灰度级的分布情况。图像的视觉效果和其直方图有对应关系,通 过调整或变换其直方图的形状会对图像的显示效果有很大影响。
5 直方图均衡化:用于增强灰度值动态范围偏小的图像的对比度,它的基本思想是把原始 图像的灰度统计直方图变换为均匀分布形式,这样就增加了像素灰度值的动态范围,从而达到 增强图像整体对比度的效果。
6 直方图均衡化步骤:
(1)输入图像,计算该图像的直方图。
(2)根据输入图像的直方图计算灰度值变换表。
(3)执行变换 x'=H(x)。
7 直方图均衡化代码流程如下:
'''
# ## histeq(im,nbr_bins=256) :img --> counts/total -->.cumsum() --> cumsum*255
def get_pdf(img):
total = img.size
return [np.sum(img == i)/total for i in range(256)]
def histeq_01(img):
pr = get_pdf(img)
img0 = img.copy()
y_points = []
cum = 0.
for i in range(256):
cum = cum + pr[i]
img0[img==i] = cum * 255.
y_points.append(cum * 255.)
return img0, y_points
if __name__ == '__main__':
import numpy as np
from pylab import *
from PIL import Image
img = np.array(Image.open('luna.png').convert('L'))
img0, y_points = histeq_01(img)
img00 = Image.fromarray(np.uint8(img0))
subplot(121)
imshow(img, cmap='gray')
subplot(122)
imshow(img00,cmap='gray')
show()
'''
cv2.calcHist(images,channels,mask,histSize,ranges[,hist[,accumulate]])
images: 原图像。当传入函数时应该用中括号 [] 括起来,例如:[img]。
channels: 如果输入图像是灰度图,它的值就是 [0];如果是彩色图像的话,传入的参数可以是 [0],[1],[2] 它们分别对应着通道 B,G,R。
mask: 掩模图像。要统计整幅图像的直方图就把它设为 None。但是如果你想统计图像某一部分的直方图的话,你就需要制作一个掩模图像,并使用它。(后边有例子)
histSize:BIN 的数目。也应该用中括号括起来,例如:[256]。
ranges: 像素值范围,通常为 [0,256]
'''
import numpy as np
import cv2
from matplotlib import pyplot as plt
img = cv2.imread('bg.png',0)
hist = cv2.calcHist([img],[0],None,[256],[0,256])
plt.plot(hist)
plt.show()
掩膜的主要是用来提取感兴趣区域。
import numpy as np
import cv2
from PIL import Image
from matplotlib import pyplot as plt
img = cv2.imread('bg.png',0) # (493, 600)
mask = np.zeros(img.shape[:2],np.uint8)
mask[200:350,300:500] = 255
mask_img = cv2.bitwise_and(img,img,mask)
mask_histr = cv2.calcHist([img],[0],mask,[256],[0,256])
plt.subplot(131)
plt.plot(img)
plt.subplot(132)
plt.plot(mask_img)
plt.subplot(133)
plt.plot(mask_img)
plt.show()
'''
dst = cv2.equalizeHist(img)
img: 灰度图像
dst : 均衡化后的结果
'''
import numpy as np
import cv2
from PIL import Image
from matplotlib import pyplot as plt
img = cv2.imread('bg.png',0) # (493, 600)
dst = cv2.equalizeHist(img)
plt.subplot(121)
plt.plot(img)
plt.subplot(122)
plt.plot(dst)
plt.show()
将整幅图像分成很多小块,然后再对每一个小块分别进行直方图均衡化,最后进行拼接。
'''
cv2.createCLAHE(clipLimit, tileGridSize)
clipLimit: 对比度限制,默认是40
tileGridSize: 分块的大小,默认为8*8
'''
import cv2
from PIL import Image
from matplotlib import pyplot as plt
img = cv2.imread('bg.png',0) # (493, 600)
dst = cv2.createCLAHE(clipLimit=10.0, tileGridSize=(8,8)).apply(img)
plt.subplot(121)
plt.plot(img)
plt.subplot(122)
plt.plot(dst)
plt.show()
全 局直方图处理通过对 RGB 图像的 R、G、B 三层通道分别进行直方图均衡化,再整合到新的图 像的方式进行。
import numpy as np
import cv2
from PIL import Image
from matplotlib import pyplot as plt
img = cv2.imread('bg.png') # (493, 600)
dst0 = cv2.equalizeHist(img[...,0])
dst1 = cv2.equalizeHist(img[...,1])
dst2 = cv2.equalizeHist(img[...,2])
dst = img.copy()
dst[...,0] = dst0
dst[...,1] = dst1
dst[...,2] = dst2
plt.subplot(121)
plt.plot(img)
plt.subplot(122)
plt.plot(dst)
plt.show()
# Image._show(Image.fromarray(img))
import numpy as np
import cv2
from PIL import Image
from matplotlib import pyplot as plt
img = cv2.imread('bg.png') # (493, 600)
clp = cv2.createCLAHE(clipLimit=6.0, tileGridSize=(8,8))
dst0 = clp.apply(img[...,0])
dst1 = clp.apply(img[...,1])
dst2 = clp.apply(img[...,2])
dst = img.copy()
dst[...,0] = dst0
dst[...,1] = dst1
dst[...,2] = dst2
plt.subplot(121)
plt.plot(img)
plt.subplot(122)
plt.plot(dst)
plt.show()