python+opencv+pycharm绘制直方图及其均衡化 及 对图像进行高斯滤波处理
什么是图像直方图
灰度级范围为[0,L-1]的数字图像的直方图是离散函数h(rk)=nk,其中rk是第k级灰度值,nk是图像中灰度为rk的像素个数。在实践中,经常用乘积MN表示的图像像素的总数除它的每个分量来归一化直方图,通常M和N是图像的行和列的维数。因此,归一化后的直方图由p(rk)=nk/MN给出,其中k=0,1,…,L-1。简单来说,p(rk)是灰度级rk在图像中出现的概率的一个估计。归一化直方图的所有分量之和应等于1。
在直方图中,暗图像集中分布在灰度级的低端;亮图像集中分布在灰度级的高端。低对比度图像具有较窄的直方图,且集中于灰度级的中部;高对比度图像的直方图分量则覆盖了很宽的灰度级范围。
灰度图像直方图
代码实现
from matplotlib import pyplot as plt
import cv2
image = cv2.imread("miao.jpg")
image_path = "miao.jpg"
# 读取图片,格式为BGR
# == 显示图片 ==
# 缩放图片
width = int(image.shape[0])
height = int(image.shape[1])
image = cv2.resize(image, (height, width), interpolation=cv2.INTER_CUBIC)
# 显示图片
cv2.imshow('pic_bgr', image)
# == 转为灰度图,并显示灰度图片 ==
# 转为灰度图像
image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 显示图片
cv2.imshow('pic_gray', image)
cv2.waitKey(0)
cv2.imshow("Original",image)
#图像直方图
hist = cv2.calcHist([image],[0],None,[256],[0,256])
plt.figure()#新建一个图像
plt.title("Grayscale Histogram")#图像的标题
plt.xlabel("Bins")#X轴标签
plt.ylabel("# of Pixels")#Y轴标签
plt.plot(hist)#画图
plt.xlim([0,256])#设置x坐标轴范围
plt.show()#显示图像
运行结果
转换灰度图像:
绘制灰度图像的直方图:
RGB图像直方图
代码实现
from matplotlib import pyplot as plt
import numpy as np
import cv2
image = cv2.imread("miao.jpg")
cv2.imshow("Original",image)
#cv2.waitKey(0)
chans = cv2.split(image)
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()
运行结果
绘制RGB图像的直方图:
直方图均衡化原理
直方图均衡化(Histogram Equalization)又称直方图平坦化,实质上是对图像进行非线性拉伸,重新分配图像象元值,使一定灰度范围内象元值的数量大致相等。这样,原来直方图中间的峰顶部分对比度得到增强,而两侧的谷底部分对比度降低,输出图像的直方图是一个较平的分段直方图:如果输出数据分段值较小的话,会产生粗略分类的视觉效果。
直方图是表示数字图像中每一灰度出现频率的统计关系。直方图能给出图像灰度范围、每个灰度的频度和灰度的分布、整幅图像的平均明暗和对比度等概貌性描述。灰度直方图是灰度级的函数, 反映的是图像中具有该灰度级像素的个数, 其横坐标是灰度级r, 纵坐标是该灰度级出现的频率( 即像素的个数) pr( r) , 整个坐标系描述的是图像灰度级的分布情况, 由此可以看出图像的灰度分布特性, 即若大部分像素集中在低灰度区域, 图像呈现暗的特性; 若像素集中在高灰度区域, 图像呈现亮的特性。
直方图均衡化
代码实现
import numpy as np
import cv2
image = cv2.imread("miao.jpg",0)#读取图像
cv2.imshow("Original",image)
cv2.waitKey(0)
eq = cv2.equalizeHist(image)#灰度图像直方图均衡化
cv2.imshow("Histogram Equalization", np.hstack([image, eq]))
cv2.waitKey(0)
运行结果
直方图均衡化的实现:
高斯滤波原理
高斯滤波是一种线性平滑滤波,适用于消除高斯噪声,广泛应用于图像处理的减噪过程。通俗的讲,高斯滤波就是对整幅图像进行加权平均的过程,每一个像素点的值,都由其本身和邻域内的其他像素值经过加权平均后得到。高斯滤波的具体操作是:用一个模板(或称卷积、掩模)扫描图像中的每一个像素,用模板确定的邻域内像素的加权平均灰度值去替代模板中心像素点的值。
高斯滤波处理图像
代码实现
对图像先添加高斯噪声,再用高斯滤波进行处理
import cv2 as cv
import numpy as np
def clamp(pv):
#防止溢出
if pv > 255:
return 255
elif pv < 0:
return 0
else:
return pv
#对原图添加高斯噪声
def gaussian_noise_demo(image):
h, w, c = image.shape
for row in range(0, h):
for col in range(0, w):
s = np.random.normal(0, 15, 3) # 产生随机数,每次产生三个
b = image[row, col, 0] # blue
g = image[row, col, 1] # green
r = image[row, col, 2] # red
image[row, col, 0] = clamp(b +
s[0])
image[row, col, 1] = clamp(g + s[1])
image[row, col, 2] = clamp(r + s[2])
cv.imshow("noise img", image)
src = cv.imread('miao.jpg') # 读取图片
cv.imshow("src demo", src)
# 高斯模糊抑制高斯噪声
gaussian_noise_demo(src)
dst = cv.GaussianBlur(src, (5, 5), 0)
# (5, 5)表示高斯矩阵的长与宽都是5,标准差取0
# OpenCV会根据高斯矩阵的尺寸自己计算,两个参数设置一个即可。
# 高斯矩阵的尺寸越大,标准差越大,处理过的图像模糊程度越大
cv.imshow("gaussian blur img",
dst)
cv.waitKey(0)
cv.destroyAllWindows()
运行结果
原图:
添加高斯噪声后的图像 vs 对其进行高斯滤波处理后的图像