直方图概念
如图:下面黑色图为上面图的直方图
横坐标:图像中各个像素点的灰度级
纵坐标:具有该灰度级的像素个数。
![](https://i-blog.csdnimg.cn/blog_migrate/ffeeec8be06fc62ebc9d46f1d426b05c.png)
归一化直方图
横坐标:图像中各个像素点的灰度级
纵坐标:出现该灰度级的概率。
DIMS:使用参数的数量
dims=1:灰度直方图,仅仅考虑灰度的情况。
还有其他考虑亮度的
BINS:参数子集的数目
bins=256: 如灰度是256. 表示0-255
缩小数字表示将临近值合并。
![](https://i-blog.csdnimg.cn/blog_migrate/f01f050df8b3973957ac49091ac3e5c8.png)
RANGE:统计灰度值的范围,一般为[0-255]
最小值0:黑色
最大值255:白色
直方图绘制
python+opencv
1.使用matplotlib绘制直方图
函数:hist(数据源,像素级)
数据源:图像,必须是一维数组
像素级:一般是256,指[0-255]
np.raval()可以实现多维数组转一维。
import cv2
import matplotlib.pyplot as plt
o=cv2.imread("boat.jpg")
cv2.imshow("original",o)
plt.hist(o.ravel(),256)#o.ravel()将像素数组转一维
plt.show()
cv2.waitKey()
cv2.destroyAllWindows()
像素直方图
2.使用opencv绘制直方图
hist=cv2.calcHist(images,channels,mask,histsize,ranges,accumulate)
hist:直方图
images:原始图像,格式[src],需要用中括号括起来
channels:通道,灰色直接[0],BGR对应[0],[1],[2]
mask:掩码图像。如果一个图很大,需要计算部分图的直方图,需要掩码。
histsize:BINS的数量,需要用中括号括起来。一般是[256]
ranges:像素值范围,一般[0,255]
accumulate:累积标识。可选参数、默认false,设为true为计算好几幅图的直方图。
绘制灰度图像直方图
不使用掩码
import cv2
import matplotlib.pyplot as plt
o=cv2.imread("boatGray.bmp")
histb = cv2.calcHist([o],[0],None,[256],[0,255])
print("type:",type(histb))
print('szie:',histb.size)
print('shape:',histb.shape)
plt.plot(histb,color='r')
plt.show()
绘制彩色图像直方图
不使用掩膜
注意012,是BGR,非RGB
import cv2
import matplotlib.pyplot as plt
o=cv2.imread("girl.bmp")
histb = cv2.calcHist([o],[0],None,[256],[0,255])
histg = cv2.calcHist([o],[1],None,[256],[0,255])
histr = cv2.calcHist([o],[2],None,[256],[0,255])
plt.plot(histb,color='b')
plt.plot(histg,color='g')
plt.plot(histr,color='r')
plt.show()
3.使用掩膜的直方图
生成掩膜
mask=np.zeros(image.shape,np.unit8)#生成全黑图像
mask[200:400,200:400]=255#部分取白
把生成的掩膜传入下列函数的mask中,即完成。
hist=cv2.calcHist(images,channels,mask,histsize,ranges,accumulate)
import cv2
import numpy as np
import matplotlib.pyplot as plt
image=cv2.imread("girl.bmp",cv2.IMREAD_GRAYSCALE)
mask=np.zeros(image.shape,np.uint8)
mask[200:400,200:400]=255
histMI=cv2.calcHist([image],[0],mask,[256],[0,255])#使用掩膜,只对第一通道
histImage=cv2.calcHist([image],[0],None,[256],[0,255])#不适用掩膜,只对第一通道
plt.plot(histImage,'r')
plt.plot(histMI)
plt.show()
原图
蓝色为使用掩膜的直方图
掩膜处理
黑色为0,其他色为1.将掩膜与原始图像进行与操作。得到处理结果。
使用方法
计算结果=cv2.bitwise_and(原始图像,掩膜)
bitwise:按位操作
and:与运算
import cv2
import numpy as np
import matplotlib.pyplot as plt
image=cv2.imread("boat.bmp",0)
mask=np.zeros(image.shape,np.uint8)
mask[200:400,200:400]=255
mi=cv2.bitwise_and(image,mask)
cv2.imshow('original',image)
cv2.imshow('mask',mask)
cv2.imshow('mi',mi)
cv2.waitKey()
cv2.destroyAllWindows()
直方图均衡化
应用场合:图像过亮或者过暗。如车牌识别
![](https://i-blog.csdnimg.cn/blog_migrate/381a39ce6cf500ba959d874d8dba1f7d.png)
![](https://i-blog.csdnimg.cn/blog_migrate/59601d204f96ec4e24075ada26cbee60.png)
理论前提:如果一个图像占有全部可能的灰度级,并且均匀分布。
结论:该图像具有高对比度和多变的灰度色调。读取的是灰度图
外观:图像细节丰富,质量更高。
算法
1.计算累积直方图
2.将累积直方图进行区间转换
3.在累积直方图中,概率相近的原始值,会被处理成相同的值。
1.计算累积直方图
2.将累积直方图进行区间转换
累积直方图:对前面求和。1的值=0和1的值的和
3.在累积直方图中,概率相近的原始值,会被处理成相同的值。
7是因为给出的示例是三维的二进制,范围是0-7,如果是np.unit9,应是255。
四舍五入得到新的值:原先是0的像素变成1,原始是1的像素变成3…。
新的像素有1,3,4,5,6,7。是因为合并如原先的45都变成了5。
换成255的数示例
方法
dst=cv2.equalizeHist(src)
dst:处理结果
src:源图像。
直方图对比
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('equ.bmp',cv2.IMREAD_GRAYSCALE)
equ = cv2.equalizeHist(img)
plt.hist(img.ravel(),256)
plt.figure()
plt.hist(equ.ravel(),256)
plt.show()
原始
处理后
示例:
处理的是灰度图,需要读取灰色图
import cv2
import numpy as np
import matplotlib.pyplot as plt
o=cv2.imread("equ.bmp",cv2.IMREAD_GRAYSCALE)#读取灰色图像
r=cv2.equalizeHist(o)
cv2.imshow("original",o)
cv2.imshow("result",r)
cv2.waitKey()
cv2.destroyAllWindows()
import cv2
import matplotlib.pyplot as plt
img = cv2.imread('boat.bmp',cv2.IMREAD_GRAYSCALE)
equ = cv2.equalizeHist(img)
plt.subplot(221)
plt.imshow(img,cmap=plt.cm.gray),plt.axis('off')
plt.subplot(222)
plt.imshow(equ,cmap=plt.cm.gray),plt.axis('off')
plt.subplot(223)
plt.hist(img.ravel(),256)
plt.subplot(224)
plt.hist(equ.ravel(),256)
plt.show()
总目录链接:
python3+opencv学习笔记汇总目录(适合基础入门学习)
电气专业的计算机小白,写博文不容易。如果你觉得本文不错,请点个赞支持下。谢谢。