一、直方图的定义、意义和特征
- 定义
在统计学中,直方图是一种对数据分布情况的图形表示,是一种二维统计图表,他的两个坐标分别是统计样本(图像、视频帧)和样本的某种属性(亮度,像素值,梯度,方向,色彩等等任何特征)。
1
2
意义
(1)直方图是图像中像素强度分布的图形表达方式。
(2)直方图统计了每一个强度值所具有的像素个数。特征
(1)直方图不再表征任何的图像纹理信息,而是对图像像素的统计。
(2)由于同一物体无论是旋转还是平移在图像中都具有相同的灰度值,因此直方图具有平移不变性、放缩不变性等优点。方法和参数
cv2.calcHist(images, channels, mask, histSize, ranges[hist[, accumulate]])
(1)images : 整型类型(uint8和float32)的原图(list形式显示)。
(2)channels : 通道的索引,例如:[0]代表灰度图片,[0],[1],[2]代表多通道。
(3)mask : 计算图片指定区域的直方图。如果mask为none,那么计算整张图。
(4)histSize( bins ) : 每个色调值(范围: 0 ~ 255)对应的像素数量/频率。[这256个值中的每一个都被称为bin,它的取值有8,16,32,64,128,256。在OpenCV中,用histSize表示bins。]
(5)range : 强度值的范围,[0, 256]。
# 1导入库
import cv2
import matplotlib.pyplot as plt
import numpy as np
# 2 方法:显示图片
def show_image(image, title, pos):
#顺序转换:BGR TO RGB
image_RGB = image[:,:,::-1] # shape:(height, width, channel)
# 显示标题
plt.title(title)
plt.subplot(2, 3, pos) # 定位
plt.imshow(image_RGB)
# 3 方法:显示图片的灰度直方图
def show_histogram(hist, title, pos, color):
# 显示标题
plt.title(title)
plt.subplot(2, 3, pos) # 定位图片
plt.xlabel('Bins') # 横轴信息
plt.ylabel('Pixels') # 纵轴信息
plt.xlim([0, 256]) # 范围
plt.plot(hist, color = color) #绘制直方图
# 主函数 main()
def main():
# 5 创建画布
plt.figure(figsize=(15, 6)
# , frameon=True
) # 画布大小和边框显示
# 设置标题形式
plt.suptitle("Gray Image Histogram", fontsize = 14, fontweight = 'bold')
# 6 加载图片
img = cv2.imread('./image/a.jpg')
# 7 灰度转换
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 8 计算灰度图的直方图
hist_img = cv2.calcHist([img_gray], [0], None, [256], [0, 256])
# 9 展示灰度直方图
# 灰度图转换成BGR格式图片
img_BGR = cv2.cvtColor(img_gray, cv2.COLOR_GRAY2BGR)
show_image(img_BGR, "BGR", 1)
show_histogram(hist_img, 'gray image histgoram', 5, 'r')
plt.show()
if __name__=='__main':
main()
# 1 导入库
import cv2
import matplotlib.pyplot as plt
import numpy as np
# 2 方法:显示图片
def show_image(image, title, pos):
# 顺序转换:BGR TO RGB
image_RGB = image[:, :, ::-1] # shape : (height, width, channel)
# 显示标题
plt.title(title)
plt.subplot(2, 3, pos) # 定位
plt.imshow(image_RGB)
# 3 方法:显示图片的灰度直方图
def show_histogram(hist, title, pos, color):
# 显示标题
plt.title(title)
plt.subplot(2, 3, pos) # 定位图片
plt.xlabel("Bins") # 横轴信息
plt.ylabel("Pixels") # 纵轴信息
plt.xlim([0, 256]) # 范围
plt.plot(hist, color=color) # 绘制直方图
# 4 主函数 main()
def main():
# 5 创建画布
plt.figure(figsize=(15, 6)) # 画布大小
plt.suptitle("Gray Image Histogram", fontsize=14, fontweight="bold") # 设置标题形式
# 6 加载图片
img = cv2.imread("children.jpg")
# 7 灰度转换
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 8 计算灰度图的直方图
hist_img = cv2.calcHist([img_gray], [0], None, [256], [0, 256])
# 9 展示灰度直方图
# 灰度图转换成BGR格式图片
img_BGR = cv2.cvtColor(img_gray, cv2.COLOR_GRAY2BGR)
show_image(img_BGR, "BGR image", 1)
show_histogram(hist_img, "gray image histogram", 4, "m")
# 10 对图片中的每个像素值增加50个像素
M = np.ones(img_gray.shape, np.uint8) * 50 # 构建矩阵
added_img = cv2.add(img_gray, M)
add_img_hist = cv2.calcHist([added_img], [0], None, [256], [0, 256]) # 计算直方图
added_img_BGR = cv2.cvtColor(added_img, cv2.COLOR_GRAY2BGR)
show_image(added_img_BGR, "added image", 2)
show_histogram(add_img_hist, "added image hist", 5, "m")
# 11 对图片中的每个像素值减去50个像素
subtract_img = cv2.subtract(img_gray, M)
subtract_img_hist = cv2.calcHist([subtract_img], [0], None, [256], [0, 256]) # 计算直方图
subtract_img_BGR = cv2.cvtColor(subtract_img, cv2.COLOR_GRAY2BGR)
show_image(subtract_img_BGR, "subtracted image", 3)
show_histogram(subtract_img_hist, "subtracted image hist", 6, "m")
plt.show()
if __name__ == '__main__':
main()
gray_image_add_subtract.png