pixelSequence = img.reshape([h * w, ])
numberBins = 256
histogram, bins, patch = plt.hist(pixelSequence, numberBins,
facecolor=‘black’, histtype=‘bar’)
plt.xlabel(“gray label”)
plt.ylabel(“number of pixels”)
plt.axis([0, 255, 0, np.max(histogram)])
plt.show()
cv.imshow(“img”, img)
cv.waitKey()

图像的对比度是通过灰度级范围来度量的,而灰度级范围可通过观察灰度直方图得到,灰度级范围越大代表对比度越高;反之对比度越低,低对比度的图像在视觉上给人的感觉是看起来不够清晰,所以通过算法调整图像的灰度值,从而调整图像的对比度是有必要的。最简单的一种对比度增强的方法是通过灰度值的线性变换实现的。
### 2.线性变换
假设输入图像为,宽为,高为,输出图像记为,图像的线性变换可以用以下公式定义:

如下图所示,当a=1,b=0时,为的一个副本;如果a>1,则输出图像的对比度比有所增大;如果0<a<1,则的对比度比有所减小。而b值的改变,影响的是输出图像的亮度,当b>0时,亮度增加;当b<0时,亮度减小。下面代码实现:
import numpy as np
a = np.array([[0, 200], [23, 4]], np.uint8)
b = 2 * a
print(b.dtype)
print(b)
‘’’
uint8
[[ 0 144]
[ 46 8]]
‘’’
在上面代码中,输入的是一个uint8类型的ndarray,用数字2乘以该数组,返回的ndarray的数据类型是uint8。注意输出第0行第1列,200\*2应该等于400,但是400超出了uint8的数据范围,Numpy是通过模运算归到uint8范围的,即400%256=144,从而转换成uint8类型。如果将常数2改为2.0,虽然这个常数只是整型和浮点型的区别,但是结果却不一样。代码如下:
import numpy as np
a = np.array([[0, 200], [23, 4]], np.uint8)
b = 2.0 * a
print(b.dtype)
print(b)
‘’’
float64
[[ 0. 400.]
[ 46. 8.]]
‘’’
可以发现返回的ndarray的数据类型变成了float64,也就是说,相乘的常数是2和2.0会导致返回的ndarray的数据类型不一样,就会造成200\*2的返回值是144,而200\*2.0的值却是400;而对8位图进行对比度增强来说,线性变换计算出的输出值可能要大于255,需要将这些值截断为255,而不是取模运算,所以不能简单地只是用“\*”运算来实现线性变换。具体代码如下:
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt