图像直方图是一种对图像空间域内色彩灰阶的分布情况的图形表示, 以便更好地理解颜色分布.
核心函数
hist=cv.calcHist(images, channels, mask, histSize, ranges[, hist[, accumulate]])
- imaes:输入的图像
- channels:用于计算图像直方图的通道列表。
- mask:掩膜,是一个大小和image一样的np数组,其中把需要处理的部分指定为1,不需要处理的部分指定为0,一般设置为None,表示处理整幅图像
- histSize:使用多少个bin(柱子),一般为256
- ranges:像素值的范围,一般为[0,255]表示0~255
代码显示
# -*- coding:utf-8 -*-
import cv2
import numpy as np
def hist_curve(im):
"""
以曲线模式绘制直方图
"""
h = np.zeros((300, 256, 3))
if len(im.shape) == 2:
color = [(255, 255, 255)]
elif im.shape[2] == 3:
color = [(255, 0, 0), (0, 255, 0), (0, 0, 255)]
for ch, col in enumerate(color):
# 计算直方图
hist_item = cv2.calcHist([im], [ch], None, [256], [0, 255])
# 直方图归一化
cv2.normalize(hist_item, hist_item, 0, 255, cv2.NORM_MINMAX)
# 直方图取整, 绘图需int
hist = np.int32(np.around(hist_item))
bins = np.arange(256).reshape(256, 1)
# 生成点坐标
# np.column_stack将矩阵按列合并
pts = np.int32(np.column_stack((bins, hist)))
# 绘制多边形曲线
cv2.polylines(h, [pts], False, col)
# 将图片上下翻转
y = np.flipud(h)
return y
def hist_lines(im):
"""
以线条模式绘制直方图(适用灰度图)
"""
h = np.zeros((300, 256, 3))
if len(im.shape) != 2:
im = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
hist_item = cv2.calcHist([im], [0], None, [256], [0, 255])
# 直方图归一化
cv2.normalize(hist_item, hist_item, 0, 255, cv2.NORM_MINMAX)
hist = np.int32(np.around(hist_item))
# 绘制直线
for x, y in enumerate(hist):
cv2.line(h, (x, 0), (x, y), (255, 255, 255))
# 将图片上下翻转
y = np.flipud(h)
return y
def main(image_path):
im = cv2.imread(image_path)
if im is None:
raise Exception('加载图片失败')
gray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
print(''' 直方图绘制 \n
Keymap :\n
a - show 对彩色图片用曲线模式绘制直方图 \n
b - show 对图片(第一通道)用柱状(bin)模式绘制直方图 \n
c - show 对灰度图片用曲线模式绘制直方图 \n
d - show 对归一化后的图片用曲线模式绘制直方图 \n
Esc - exit \n
''')
cv2.imshow('image', im)
while True:
k = cv2.waitKey(0)
if k == ord('a'):
curve = hist_curve(im)
cv2.imshow('histogram', curve)
cv2.imshow('image', im)
print('a')
elif k == ord('b'):
print('b')
lines = hist_lines(im)
cv2.imshow('histogram', lines)
cv2.imshow('image', gray)
elif k == ord('c'):
print('c')
curve = hist_curve(gray)
cv2.imshow('histogram', curve)
cv2.imshow('image', gray)
elif k == ord('d'):
print('d')
# 对图片归一化
norm = cv2.normalize(gray, gray, alpha=0, beta=255, norm_type=cv2.NORM_MINMAX)
lines = hist_lines(norm)
cv2.imshow('histogram', lines)
cv2.imshow('image', norm)
elif k == 27:
print('ESC')
cv2.destroyAllWindows()
break
print('Done')
if __name__ == '__main__':
main('/home/pi/PycharmProjects/learn/learn_opencv/copy_of_lena_color.jpg')
cv2.destroyAllWindows()
效果展示