1、直方图
1.1基本理论
横坐标:图像中各个像素点的灰度级。灰度级:就是灰度数的等级:0-255
纵坐标:具有该灰度级的像素个数。例:灰度级5:就是像素为5的像素个数
如下图:方框里面的数字代表像素灰度级,y是数每个灰度级的个数。
然后根据数据,进行绘制直方图
归一化直方图
横坐标:图像中各个像素点的灰度级。
纵坐标:出现这个灰度级的概率。
如下图:纵坐标便是概率了。
DIMS:使用参数的数量,即绘制直方图的时候要考虑那些信息。
dims=: 1 一般为1
一般只考虑一个即灰度直方图,仅仅考虑灰度的情况
BINS:参数子集的数目。
bins=5
bins=3
如下图
例:某图片灰度级为0-255,便可使用bins分级显示,0-15一组,16-31,一组[0,255] = [0,15]∪[16,31] U …U [240,255]范围=bin1∪bin2∪… U bin16
如下图
RANGE:统计灰度值的范围,一般为[0,255]。
最小值:0,黑色
最大值: 255,白色
1.2 绘制直方图
使用Matplotlib当中的pyplot进行绘制
import matplotlib.pyplot as plt
函数hist 功能:根据数据源和像素级绘制直方图。
hist(数据源,像素级)
数据源:图像,必须是一维数组
像素级:一般是256,指[0,255]
要将二维转换成一维 使用函数ravel()
例:图像a是二维数组,转换成b一维数组
b=a.ravel()
一维数组=多维数组.ravel()
import cv2
import matplotlib.pyplot as plt
img=cv2.imread(" imagel\boat.jpg' ")
plt.hist(img.ravel(),256)
1.3 使用OpenCV统计直方图
使用下面这个函数
函数calcHist
hist = cv2.calcHist(images,channels,mask,histSize,ranges,accumulate)
hist:直方图 返回的直方图,是一个二维数组。
images:原始图像 图像需要使用“[ ]”括起来使用。
channels:指定通道 通道编号需要用中括号括起来:灰度图是[0],彩色是[0],[1],[2]对应B、G、R
mask:掩码图像 统计整幅图像的直方图,设为None。统计图像某一部分的直方图时,需要掩码图像。
histSize: BINS的数量 需要用中括号括起来,例如: [256]
ranges:像素值范围RANGE 像素值范围,例如: [0, 255]
accumulate:累计标识:(可选)
默认值为false。
如果被设置为true,则直方图在开始分配时不会被清零。
该参数允许从多个对象中计算单个直方图,或者用于实时更新直方图。
多个直方图的累积结果,用于对一-组图像计算直方图。
hist = cv2.calcHist([img],[O],None,[256],[0,255])
import cv2
import numpy as np
import matplotlib.pyplot as plt
#绘制灰度图像
o=cv2.imread(r'D:\image\boats.bmp')
hist=cv2.calcHist([o],[0],None,[256],[0,255])
plt.plot(hist,color='r')
#绘制彩色图像
o1=cv2.imread(r'D:\image\girl.bmp')
histB=cv2.calcHist([o1],[0],None,[256],[0,255])
histG=cv2.calcHist([o1],[1],None,[256],[0,255])
histR=cv2.calcHist([o1],[2],None,[256],[0,255])
plt.plot(histB,color='b')
plt.plot(histG,color='g')
plt.plot(histR,color='r')
1.4 使用掩膜的直方图
掩膜:是一个只有黑色和白色的图像,白色称为透明,黑色称为不透明
将掩膜图像放入原图像,黑色会被盖住,白色会显示
如下图
生成掩膜图像
先生成全黑的
mask= np.zeros(image.shape,np.uint8) 大小与原图像相同
再生成白色的
mask[200:400,200:400]=255
import cv2
import numpy as np
import matplotlib pyplot as plt
image=cv2.imread("image\\girl.bmp" ,cv2.IMREAD. _GRAYSCALE)
mask=np.zeros(image.shape,np.uint8)
mask[200:400,200:400]=255
histMl=cv2.calcHist([image][0],mask,[256],[0,255])
histlmage=cv2.calcHist([image][0],None,[256],[0,255])
掩膜原理演示
“或”和“与”原理
“与”
1and1=1
1and0=0
0and1=0
0and0=0
此时用的是“与”,掩膜图像和原图像进行叠加,像素全是1的值才会显示
1.5 直方图均衡化原理
前提:如果一幅图像占有全部可能的灰度级,并且均匀分布。
结论:该图像具有高对比度和多变的灰度色调。
外观:图像细节丰富,质量更高。
算法:
1.计算累计直方图
2.将累计直方图进行区间转换
3.在累计直方图中,概率相近的原始值,会被处理为相同的值。
计算过程如下:
1.原始图像进行统计直方图
2.统计直方图进行归一化(计算每个像素所占的比例)
3.归一化直方图进行累计直方图(每一个像素累加上一个像素,最后一个像素结果应该是1)
4.累计直方图乘以该直方图最大的像素级,得到均衡化直方图(四舍五入)
如下图
上图,若直方图的像素级最大是255,则最后一步便是乘255
直方图均衡化函数equalizeHist
dst = cv2.equalizeHist(src)
src :源图像
dst :目标图像,处理结果
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread(r'D:\image\airplaneU2.bmp',cv2.IMREAD_GRAYSCALE) #以灰度图像读入
equ = cv2.equalizeHist(img) #均衡化
#绘制直方图
plt.hist(img.ravel(),256) #ravel():将二维转化成一维
plt.figure() #新建一个另外的窗口
plt.hist(equ.ravel(),256)
#看图像对比
import cv2
import numpy as np
img = cv2.imread(r'D:\image\airplaneU2.bmp',cv2.IMREAD_GRAYSCALE)
equ=cv2.equalizeHist(img)
cv2.imshow('o',img)
cv2.imshow('r',equ)
cv2.waitKey()
cv2.destroyAllWindows()
subplot函数使用
可以在同一个窗口内显示多个图片
函数subplot()
subplot(nrows,ncols,plot_number)
nrows:行数(显示图片的行数)
ncols:列数 (显示图片的列数)
plot_number:窗口序号
例:
subplot(2,3,4)
表示将窗口设置成2行3列的窗口,可以显示6个图片;4:表示现在要绘制第四个窗口
如下图
特例:当每一个参数都小于10时,可以直接书写三个数字,
表示为“subplot(234)”
img = cv2.imread('imagel\boatGray .bmp' ,cv2.IMREAD_ GRAYSCALE)
equ = cv2.equalizeHist(img)
plt.subplot(121),plt.hist(img.ravel(),256)
plt.subplot(122).plt.hist(equ.ravel(),256)
例:
import cv2
import numpy as np
import matplotlib.pyplot as plt
o=cv2.imread(r'D:\image\boats.bmp',cv2.IMREAD_GRAYSCALE)
e=cv2.equalizeHist(o)
plt.subplot(121)
plt.hist(o.ravel(),256)
plt.subplot(122)
plt.hist(e.ravel(),256)
matplotlib.pyploy.imshow函数
imshow(X, cmap= None)
X:要绘制的图像
cmap : colormap,颜色图谱,默认为RGB(A)颜色空间
灰度图像:cmap= plt.cm.gray 必须转换成灰度显示
彩色图像:默认为RGB(A)颜色空间,若使用opencv读入图像,默认空间为BGR,必须调整为RGB
import cv2
import matplotlib.pyplot as plt
o = cv2.imread(r'D:\image\girl.bmp')
g=cv2.cvtColor(o,cv2.COLOR_BGR2GRAY) #将图像转换成灰色
plt.subplot(221) #在同一窗口2行2列的第一个窗口显示
plt.imshow(o),plt.axis('off') #直接显示彩色图像,将坐标轴关闭
plt.subplot(222) #在同一窗口,2行2列的第二个窗口显示
plt.imshow(o,cmap=plt.cm.gray),plt.axis('off') #以灰度形式显色彩色图像
plt.subplot(223) #在同一窗口,2行2列的第三个窗口显示
plt.imshow(g),plt.axis('off')#使用默认值显示灰色图像
plt.subplot(224)
plt.imshow(g,cmap=plt.cm.gray),plt.axis('off') #以灰度形式显示灰度图像
上图只有第四个图像为正确图像,必须是灰色图像,灰色显示
import cv2
import matplotlib.pyplot as plt
img = cv2.imread(r'D:\image\girl.bmp')
b,g,r=cv2.split(img) #重组数据通道
img2=cv2.merge([r,g,b])
plt.subplot(121) #以BGR显示
plt.imshow(img),plt.axis('off')
plt.subplot(122) #以RGB显示
plt.imshow(img2),plt.axis('off')
直方图均衡化对比
import cv2
import matplotlib.pyplot as plt
img = cv2.imread(r'D:\image\boats.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)