目录
一、图像直方图
1、什么是图像直方图
2、作用
1)分析图像的亮度分布
2)判断图像的对比度
3)检测图像的亮度和色彩偏移
4)图像增强和调整
5)阈值分割
3、举例
二、直方图用法
1、函数用法
2、参数解析
1)image
2)channel
3)mask
4)histSize
5)ranges
3、代码实现
运行结果:
三、mask掩码图像
1、什么是掩码图像
2、参数解析
1)用法
2)src1、src2
3)dst
4)mask
3、案例
运行结果:
四、直方图均衡化
1、什么是直方图均衡化
2、步骤
3、案例实现
运行结果:
4、自适应直方图均衡化
1)概念
2)步骤
3)代码展示
运行结果:
一、图像直方图
1、什么是图像直方图
图像直方图是描述图像像素值分布情况的统计图形。它表示了图像中不同像素值的数量或频率。
在图像直方图中,横轴表示像素值的范围,通常为0-255,纵轴表示像素值的数量或频率。直方图的每一个条柱代表某个像素值范围内像素的数量或频率。例如,柱子的高度表示图像中具有该像素值的像素的数量或出现的频率。
2、作用
1)分析图像的亮度分布
通过直方图可以了解图像中不同亮度值的像素数量,从而判断图像的亮度分布情况。例如,如果直方图中灰度级别集中在低亮度区域,说明图像较暗;如果直方图分布在高亮度区域,则说明图像较亮。
2)判断图像的对比度
直方图的宽度反映了图像的对比度。直方图宽度越大,表示图像中像素值分布越分散,对比度越高;相反,直方图宽度越窄,表示图像中像素值分布越集中,对比度越低。
3)检测图像的亮度和色彩偏移
通过比较不同颜色通道的直方图,可以判断图像是否存在亮度或色彩偏移。例如,如果红色通道的直方图偏向左侧,则说明图像偏向较暗的红色,存在亮度偏移。
4)图像增强和调整
通过分析直方图,可以根据图像的特点进行增强和调整。例如,可以通过直方图均衡化来增强图像的对比度;可以通过直方图匹配来调整图像的色彩和亮度分布。
5)阈值分割
直方图可以用于确定图像的阈值,用于分割图像中的目标物体和背景。通过直方图的谷底或者双峰可以确定一个适合的阈值值,将图像分成两个部分。
3、举例
灰度值在0 - 255范围之间总共 256 个值,可以将我们的范围划分为子部分(称为bins),例
二、直方图用法
1、函数用法
cv2.calcHist(images,channels,mask,histsize,ranges) 计算图像的直方图,用于表示图像中像素灰度级别的分布情况。
cv2.calcHist()函数是OpenCV中的一种直方图计算方法,用于计算图像的直方图。它可以计算输入图像中每个通道的直方图,并将其存储在一个单独的数组中。
2、参数解析
1)image
输入图像的列表。如果只有一幅图像,则传递一个包含该图像的列表。如果有多幅图像,则传递一个包含所有图像的列表。
2)channel
要计算直方图的通道索引。对于灰度图像,传递[0]表示计算灰度直方图。对于彩色图像,可以使用[0]表示蓝色通道的直方图,[1]表示绿色通道的直方图,[2]表示红色通道的直方图。
3)mask
可选参数,用于指定计算直方图的掩码图像。只有掩码图像中像素值为非零的像素才会被考虑在内。
4)histSize
直方图的大小。对于灰度图像,传递一个整数表示直方图的bin数目。对于彩色图像,传递一个包含每个通道的bin数目的列表。
5)ranges
直方图的范围。对于灰度图像,传递一个包含最小值和最大值的元组。对于彩色图像,传递一个包含每个通道的最小值和最大值的元组。
3、代码实现
import cv2
import matplotlib.pyplot as plt
import numpy as np
phone = cv2.imread('phone.png',cv2.IMREAD_GRAYSCALE) # 灰度图读取,将图像转换为一维数组
a = phone.ravel() # 这里使用了 numpy 的 ravel 函数,将多维数组拉成一维数组。
# 绘制直方图
plt.hist(a,bins=256) # 使用 matplotlib 的 hist 的数绘制直方图。
# -a:一维数组,即图像的像素值组成的数组。
# - bins=256:指定直方图的条数,即灰度级的数量。
plt.show() # 显示直方图
phone_hist = cv2.calcHist([phone],[0],None,[16],[0,256]) # 表示对图形phone绘制直方图,[0]表示为灰度图,none表示没有用掩码图像,直方图bins数目为16,范围是【0,256】
plt.plot(phone_hist) # 使用calcHist的值绘制曲线图
plt.show()
img = cv2.imread('phone.png') # 直接读取猜测图片
color = ('b','g','r') # 定义通道颜色
for i,col in enumerate(color): # enumerate对可迭代对象生成索引和数值
histr = cv2.calcHist([img], [i],None, [256], [0, 256])
plt.plot(histr,color=col) # 表示绘制的图线颜色为三通道图像的折线
plt.show()
运行结果:
三、mask掩码图像
1、什么是掩码图像
掩码图像(Mask Image)是一种与原图像具有相同尺寸的二进制图像,其中像素值为0或255(或其他非零值)。掩码图像用于指示在应用某些图像处理操作时要处理的特定区域。在掩码图像中,像素值为0的位置表示不需要处理的区域,而像素值为255的位置表示需要处理的区域。
通过将掩码图像与原图像进行逐像素逻辑运算,可以实现对特定区域进行掩模(遮罩),只对感兴趣的区域进行处理,而不影响其他区域。掩码图像在图像分割、图像修复、图像特征提取等图像处理任务中很常见,它可以用来指定感兴趣的区域,从而在处理过程中对特定区域进行操作或分析。
2、参数解析
1)用法
bitwise_and(src1,src2,dst=None, mask=None)
对图像(灰度图像或彩色图像均可)每个像素值进行二进制"与"操作,1&1=1,1&0=0,0&1=0,O&G
2)src1、src2
输入图像或标量,标src1和src2相与。
3)dst
可选输出变量,如果需要使用非None则要先定义,且其大小与输入变量相同
4)mask
图像掩膜,可选参数,用于指定要更改的输出图像数组的元素,mask为0的值,src1和src2相与的值都为0
3、案例
import cv2
import numpy as np
import matplotlib.pyplot as plt
phone = cv2.imread('phone.png',cv2.IMREAD_GRAYSCALE) # 读取灰度图
cv2.imshow('phone',phone) # 展示原图的灰度图形式
cv2.waitKey(0)
mask = np.zeros(phone.shape[:2],np.uint8) # 通过np生成一个全0矩阵,长短为原图的宽和高,值为0表示纯黑图像,用于制作mask蒙板
mask[50:350,100:470] = 255 # 切片,将数组中的宽度50-350与高度100-470这块面积内的值全部更改为255,表示纯白色
cv2.imshow('mask',mask) # 使用OpenCV以图像形式展示数组内容
cv2.waitKey(0)
phone_mask = cv2.bitwise_and(phone,phone,mask=mask) # 使用掩码图像mask将原图与自身进行按位与操作,得到只有掩码区域保留原图像像素值的掩码图像phone_mask
cv2.imshow('phone_mask',phone_mask)
cv2.waitKey(0)
phone_hist_mask = cv2.calcHist([phone],[0],mask,[256],[0,256]) # 展示原图像带掩码图像的像素直方图
plt.plot(phone_hist_mask)
plt.show()
运行结果:
四、直方图均衡化
1、什么是直方图均衡化
直方图均衡化是一种图像增强的方法,通过重新分布图像的像素值,使得图像的整体对比度增强,细节得到更好的展示。
在图像中,像素值的分布情况可以用直方图表示。直方图均衡化的目标是将图像的直方图变成一个均匀分布的直方图,从而使得图像中的像素值范围更广泛地利用,并增强图像的对比度。
2、步骤
1)计算图像的累积直方图,即将每个灰度级别的像素值累加起来得到的直方图。
2)根据累积直方图,将原图像中每个像素的灰度值映射为新的像素值,使得新的像素值均匀分布,可以使用以下公式计算新的像素值:
new_pixel = (cumulative_hist[old_pixel]/total_pixels) * (num_bins-1)
其中,cumulative_hist 是累积直方图,old_pixel 是原图像中的像素值,total_pixels 是原图像的总像素数,num_bins 是灰度级别的总数。
3)根据映射后的像素值,得到均衡化后的图像。
3、案例实现
import cv2
import numpy as np
import matplotlib.pyplot as plt
phone = cv2.imread('woman.png',cv2.IMREAD_GRAYSCALE) # 读取彩色图片的灰度图
# phone_hist = cv2.calcHist([phone],[0],None,[256],[0,256])
plt.hist(phone.ravel(),bins=256) # 绘制直方图,numpy中的ravel将多维数组转变成一维数组,256表示将像素值范围划分为256个区间
plt.show()
phone_equalize = cv2.equalizeHist(phone)
plt.hist(phone_equalize.ravel(),bins=256) # numpy中的ravel将数组多维度拉成一维数组
plt.show()
res = np.hstack((phone,phone_equalize)) # 横向拼接,将多个数组按水平方向(列顺序)堆叠成一个新的数组。
cv2.imshow('phone_equalize',res)
cv2.waitKey(0)
运行结果:
4、自适应直方图均衡化
1)概念
传统的直方图均衡化方法是将整个图像的直方图变成均匀分布,但在某些情况下,图像的局部区域可能存在过亮或过暗的问题。自适应直方图均衡化通过将图像分成多个小的局部区域,并对每个局部区域进行直方图均衡化,从而避免了全局均衡化带来的问题。
2)步骤
• 将图像分成多个不重叠的小块,每个小块称为一个局部区域。
• 对每个局部区域进行直方图均衡化,得到均衡化后的局部区域。
• 将均衡化后的局部区域重新拼合,得到最终的均衡化图像。
3)代码展示
(此处衔接上述代码)
clahe = cv2.createCLAHE(clipLimit=1,tileGridSize=(16,16)) # 通过类创建了一个均衡化对象
# clipLimit表示对比度的限制,tileGridSize表示图像均匀划分的小块大小
phone_clahe = clahe.apply(phone) # 将均衡化对象应用到图片phone上得到均衡化处理后的图片phone_clahe
res = np.hstack((phone,phone_equalize,phone_clahe)) # 将原图、直方图均衡化后的图像、自适应直方图均衡化后的图像,水平方向合并
cv2.imshow("phone_equalize",res)
cv2.waitKey(0)