Opencv-Python学习笔记七——图像直方图|Opencv-Python学习笔记七——图像直方图 calcHist,直方图均衡化equalizeHist
图像直方图
tutorial_py_histogram
直方图是对图像像素的统计分布,它统计了每个像素(0到L-1)的数量。
直方图均衡化就是将原始的直方图拉伸,使之均匀分布在全部灰度范围内,从而增强图像的对比度。
直方图均衡化的中心思想是把原始图像的的灰度直方图从比较集中的某个区域变成在全部灰度范围内的均匀分布。
cv2.calcHist(images, channels, mask, histSize, ranges[, hist[, accumulate ]]) #返回hist
- 第一个参数必须用方括号括起来。
- 第二个参数是用于计算直方图的通道,这里使用灰度图计算直方图,所以就直接使用第一个通道;
- 第三个参数是Mask,这里没有使用,所以用None。
- 第四个参数是histSize,表示这个直方图分成多少份(即多少个直方柱)。第二个例子将绘出直方图,到时候会清楚一点。
- 第五个参数是表示直方图中各个像素的值,[0.0, 256.0]表示直方图能表示像素值从0.0到256的像素。
【Opencv-Python学习笔记七——图像直方图|Opencv-Python学习笔记七——图像直方图 calcHist,直方图均衡化equalizeHist】要理解直方图,绕不开“亮度”这个概念。人们把照片的亮度分为0到255共256个数值,数值越大,代表的亮度越高。其中0代表纯黑色的最暗区域,255表示最亮的纯白色,而中间的数字就是不同亮度的灰色。人们还进一步把这些亮度分为了5个区域,分别是黑色,阴影,中间调,高光和白色。
直方图中柱子的高度,代表了画面中有多少像素是那个亮度,其实就可以看出来画面中亮度的分布和比例.
文章图片
直方图 灰度直方图
%matplotlib inline
from matplotlib import pyplot as plt
import cv2
import numpy as npimg = cv2.imread('dark.jpg')img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)plt.imshow(img_gray, cmap=plt.cm.gray)hist = cv2.calcHist([img], [0], None, [256], [0, 256])plt.figure()
plt.title("Grayscale Histogram")
plt.xlabel("Bins")
plt.ylabel("# of Pixels")
plt.plot(hist)
plt.xlim([0, 256])
plt.show()
文章图片
灰度直方图 颜色直方图
%matplotlib inline
from matplotlib import pyplot as plt
import cv2
import numpy as npimg = cv2.imread('image800.jpg')chans = cv2.split(img)
colors = ('b', 'g', 'r')plt.figure()
plt.title("’Flattened’ Color Histogram")
plt.xlabel("Bins")
plt.ylabel("# of Pixels")for (chan, color) in zip(chans, colors):
hist = cv2.calcHist([chan], [0], None, [256], [0, 256])
plt.plot(hist, color = color)
plt.xlim([0, 256])
plt.show()
文章图片
calcHist 多通道的直方图
%matplotlib inline
from matplotlib import pyplot as plt
import cv2
import numpy as npimg = cv2.imread('person.jpg')# Matplotlib有一个绘制直方图的函数:matplotlib.pyplot.hist()
plt.hist(img.ravel(),256,[0,256])
plt.show()chans = cv2.split(img)
colors = ('b', 'g', 'r')fig = plt.figure(figsize=(15, 5))
ax = fig.add_subplot(131)
hist = cv2.calcHist([chans[1], chans[0]], [0, 1], None,
[32, 32], [0, 256, 0, 256])
p = ax.imshow(hist, interpolation = "nearest")
ax.set_title("2D Color Histogram for G and B")
plt.colorbar(p)ax = fig.add_subplot(132)
hist = cv2.calcHist([chans[1], chans[2]], [0, 1], None,
[32, 32], [0, 256, 0, 256])
p = ax.imshow(hist, interpolation = "nearest")
ax.set_title("2D Color Histogram for G and R")
plt.colorbar(p)ax = fig.add_subplot(133)
hist = cv2.calcHist([chans[0], chans[2]], [0, 1], None,
[32, 32], [0, 256, 0, 256])
p = ax.imshow(hist, interpolation = "nearest")
ax.set_title("2D Color Histogram for B and R")
plt.colorbar(p)print("2D histogram shape: {}, with {} values".format(hist.shape, hist.flatten().shape[0]))hist = cv2.calcHist([img], [0, 1, 2],
None, [8, 8, 8], [0, 256, 0, 256, 0, 256])
print("3D histogram shape: {}, with {} values".format(hist.shape, hist.flatten().shape[0]))
文章图片
2D histogram 掩膜直方图
%matplotlib inline
import cv2 as cv
import numpy as np
from matplotlib import pyplot as pltimg = cv.imread('dark.jpg', 0)
# create a mask应用遮罩
mask = np.zeros(img.shape[:2], np.uint8)
mask[100:300, 100:400] = 255
masked_img = cv.bitwise_and(img, img, mask=mask)
#Calculate histogram with mask and without mask
# Check third argument for mask
"""
蒙板(掩模)
将要统计的部分设置成白色,其他部分设置成黑色,就构成了蒙板。然后传递给原图像即可
"""
hist_full = cv.calcHist([img], [0], None, [256], [0,256])
hist_mask = cv.calcHist([img], [0], mask, [256], [0,256])
plt.subplot(221), plt.imshow(img, 'gray')
plt.subplot(222), plt.imshow(mask,'gray')
plt.subplot(223), plt.imshow(masked_img, 'gray')
plt.subplot(224), plt.plot(hist_full, color='r'), plt.plot(hist_mask, color='b')
plt.xlim([0,256])
plt.tight_layout()
plt.show()
文章图片
mask-histogram 通过方法计算彩色图片的各通道直方图
# 彩色图像不同通道的直方图
%matplotlib inline
import cv2
import numpy as npimg = cv2.imread("person.jpg")
b, g, r = cv2.split(img) def calcAndDrawHist(image, color):
hist= cv2.calcHist([image], [0], None, [256], [0.0,255.0])
minVal, maxVal, minLoc, maxLoc = cv2.minMaxLoc(hist)
histImg = np.zeros([256,256,3], np.uint8)
hpt = int(0.9* 256);
for h in range(256):
intensity = int(hist[h]*hpt/maxVal)
cv2.line(histImg,(h,256), (h,256-intensity), color)return histImg;
histImgB = calcAndDrawHist(b, [255, 0, 0])
histImgG = calcAndDrawHist(g, [0, 255, 0])
histImgR = calcAndDrawHist(r, [0, 0, 255])plt.figure(figsize=(8, 6))
plt.subplot(221)
plt.imshow(img[:,:,::-1]);
plt.title('origin')
plt.subplot(222)
plt.imshow(histImgB[:,:,::-1]);
plt.title('histImgB')
plt.subplot(223)
plt.imshow(histImgG[:,:,::-1]);
plt.title('histImgG')
plt.subplot(224)
plt.imshow(histImgR[:,:,::-1]);
plt.title('histImgR')plt.tight_layout()
plt.show()
文章图片
image.png 直方图均衡
cv2.equalizeHist()直方图均衡化就是将原始的直方图拉伸,使之均匀分布在全部灰度范围内,从而增强图像的对比度。
直方图均衡化的中心思想是把原始图像的的灰度直方图从比较集中的某个区域变成在全部灰度范围内的均匀分布。旨在使得图像整体效果均匀,黑与白之间的各个像素级之间的点更均匀一点。
文章图片
image.png 灰度直方图均衡
%matplotlib inline
import cv2
import numpy as np
from matplotlib import pyplot as pltimg = cv2.imread('dark.jpg',0)
# histogram equalization
equ = cv2.equalizeHist(img)
# 两个图片的像素分布连接在一起,拍成一维数组
res = np.hstack((img,equ))plt.figure(figsize=(8, 6))
ax1 = plt.subplot2grid((2,2),(0, 0))
ax1.imshow(img, cmap=plt.cm.gray)
ax1.set_title('orignal image')ax1 = plt.subplot2grid((2, 2), (0, 1))
ax1.imshow(equ, cmap=plt.cm.gray)
ax1.set_title('equalization')ax1 = plt.subplot2grid((2, 2), (1, 0), colspan=3, rowspan=1)
ax1.imshow(res, cmap=plt.cm.gray)
ax1.set_title('horizational')plt.tight_layout()
plt.show()
文章图片
gray_equalizeHist 彩色图像直方图均衡
在OpenCV中,彩色的图像其实是用一个多通道数组来存储的,每个单通道数组中的元素的取值范围都是0到255。这与灰度图中像素的变化范围是相同的。因此对彩色图像进行直方图均衡化只要先将彩色图像分解成若干通道,然后这些通道分别进行直方图均衡化,最后合并所有通道即可。
%matplotlib inline
import cv2
import numpy as np
from matplotlib import pyplot as pltdef hisEqulColor(img):
ycrcb = cv2.cvtColor(img, cv2.COLOR_BGR2YCR_CB)
channels = cv2.split(ycrcb)
print(len(channels))
cv2.equalizeHist(channels[0], channels[0])
cv2.merge(channels, ycrcb)
cv2.cvtColor(ycrcb, cv2.COLOR_YCR_CB2BGR, img)
return imgimg = cv2.imread('dark.jpg')equ = hisEqulColor(im)h_stack_img = np.hstack((img, equ))plt.figure(figsize=(10, 8))
ax1 = plt.subplot2grid((2,2),(0, 0))
ax1.imshow(img[:,:,::-1])
ax1.set_title('orignal image')ax1 = plt.subplot2grid((2, 2), (0, 1))
ax1.imshow(equ[:,:,::-1])
ax1.set_title('equalization')ax1 = plt.subplot2grid((2, 2), (1, 0), colspan=3, rowspan=1)
ax1.imshow(h_stack_img[:,:,::-1])
ax1.set_title('horizational')plt.tight_layout()
plt.show()
文章图片
image.png
推荐阅读
- EffectiveObjective-C2.0|EffectiveObjective-C2.0 笔记 - 第二部分
- 由浅入深理解AOP
- 继续努力,自主学习家庭Day135(20181015)
- python学习之|python学习之 实现QQ自动发送消息
- Android中的AES加密-下
- 一起来学习C语言的字符串转换函数
- 定制一套英文学习方案
- 漫画初学者如何学习漫画背景的透视画法(这篇教程请收藏好了!)
- 《深度倾听》第5天──「RIA学习力」便签输出第16期
- 如何更好的去学习