一、点运算
概念:点运算(也称为像素级运算或单像素操作)是指对图像中每一个像素点进行独立、相同的操作,而这些操作不会考虑像素点之间的空间关系。点处理优势也称对比度拉伸、对比度增强或灰度变换等。
目的:点运算在图像处理中广泛应用于对比度增强、亮度调整、直方图均衡化、图像阈值化等方面。通过点运算,可以改善图像的视觉效果,使其更适合于后续的处理和分析。
分类:点运算可分为灰度变换和直方图修正两大方法,其中直方图修正包括直方图均衡化和直方图规范化。
特点:可逆、无法增强图像细节
应用:光度学标定、对比度增强(对比度扩展)、显示标定、轮廓线(例如用点处理进行图像阈值化处理,根据图像的灰度等级把一幅图像划分成一些不连接的区域,这有助于确定图像中对象的边界或定义蒙版)、裁剪(对于8位的灰度图像,在存储每一像素前输出图像的灰度级一定要被裁剪到0~255的范围内)
二、灰度化
概念:灰度化是图像处理中的一个基本步骤,其目的是将彩色图像转换为灰度图像。灰度图像是一种仅包含亮度信息而不包含颜色信息的图像,其像素值通常用一个字节(即0-255的范围)来表示,这个值代表了该像素的灰度等级,也就是亮度。灰度化是许多图像处理任务的第一步,如边缘检测、图像分割、特征提取等,因为灰度图像相对于彩色图像来说,计算量更小,处理速度更快,同时保留了图像的大部分重要信息。
方法:加权平均值法、取最大值法、平均值法等,加权平均值法最为常用
- D=0.299R+0.587G+0.114B
- D=max(R,G,B)
- D=(R+G+B)/3
示例:
import cv2
import numpy as np# 绘图展示
def cv_show(name, img):cv2.imshow(name, img)cv2.waitKey(0)cv2.destroyAllWindows()image = cv2.imread('img\\1.png')
image_cut = image[0:500, 0:500]
cv_show("image_cut", image_cut)
image_cut[:, :, 0] = image_cut[:, :, 0] * 0.114
image_cut[:, :, 1] = image_cut[:, :, 1] * 0.587
image_cut[:, :, 2] = image_cut[:, :, 2] * 0.299
image_cut_gray = np.sum(image_cut, axis=2, dtype=np.uint8)
cv_show('image_copy_cut', image_cut_gray)
结果展示:
优化转化速度:从次到优
Gray=(2989R+5870G+1140B)/10000
Gray=(4898R+9618G+1868B)>>14
Gray=(76R+150G+30B)>>8
三、对比度
概念:画面明亮部分与阴暗部分的灰度比值。对比度越高,图像中物体轮廓越分明可见,越清晰;相反,图像轮廓模糊,图像不太清晰。
四、灰度变换
灰度变换函数:s=T(r)
作用:
- 对比度拉伸:灰度变换可以扩展图像的对比度,使图像在视觉上更加清晰。当图像的灰度值集中在较窄的范围内时,通过灰度变换可以将其扩展到更宽的灰度区间,从而增强图像的细节表现力。
- 细节显示:灰度变换能够突出图像中的细节信息,使原本难以分辨的细节变得清晰可见。这对于医学图像处理、遥感图像处理等领域尤为重要。
- 特征突出:灰度变换可以有选择地突出图像中感兴趣的特征,同时抑制不需要的特征。这对于图像分析、目标检测和识别等任务非常有帮助。
- 直方图均衡化:灰度变换可以有效地改变图像的直方图分布,使像素的分布更为均匀。这有助于改善图像的视觉效果,并提高后续图像处理的效率。
方法:线性灰度变换、分段线性灰度变换、非线性灰度变化(包括对数函数变换和伽马变换)
- 对数变换扩展图像中低灰度区域、压缩图像中高灰度区域,增强图像中暗色区域细节;反对数变换与此相反。同时,还能压缩图像灰度值的动态范围,在傅里叶变换中显示更多变换后的频谱细节。
- 伽马变换用于图像校正,根据参数γ来修正图像中灰度过高(γ>1)或灰度过低(γ<1)的内容。
线性灰度变换:
公式:g=kf+b,其中k为斜率,b为为截距(k表示图像对比度变化,b表示图像亮度变化)。
参数:
- 当k>1,输出图像对比度增大;
- 当k<1,输出图像对比度减小;
- 当k=1且b≠0,所有图像灰度值上移或下移,整个图像更暗或更亮;
- 当k=1、b=0,图像无变化;
- 当k=-1,b=255,输出图像灰度反转;
- 当k<0且b>0,暗区域变亮,亮区域变暗,点运算完成了图像求补运算。
分段线性灰度变换:
将原图像灰度区间划分为多个,对每一个区间使用不同k和b值的线性灰度变换。
对数变换和反对数变换:
公式:s=c*log(1+r),其中,c为常数,r≥0。
伽马变换:
公式:s=crγ,其中c和γ为正常数。
五、直方图修正
直方图:灰度直方图是将数字图像中的所有像素,按照灰度值的大小,统计其出现的频率。它是灰度级的函数,表示图像中具有某种灰度级的像素的个数,反映了图像中某种灰度出现的频率。如果将图像总像素亮度(灰度级别)看成是一个随机变量,则其分布情况就反映了图像的统计特性,这可用probability density function (PDF)来刻画和描述,表现为灰度直方图。
API:
cv2.calcHist(images, channels, mask, histSize, ranges[, hist[, accumulate]])
images
:源图像,应该放在方括号中,如[img]
。channels
:要计算其直方图的通道索引。对于灰度图像,它总是[0]
。mask
:图像掩模。如果为None
,则计算整个图像的直方图。histSize
:直方图的大小,放在方括号中,如[256]
。ranges
:像素值范围,通常为[0, 256]
。
示例:
import cv2
import numpy as np
import matplotlib.pyplot as plt# 绘图展示
def cv_show(name, img):cv2.imshow(name, img)cv2.waitKey(0)cv2.destroyAllWindows()image = cv2.imread('img\\1.png', 0)
cv_show("image_cut", image)
hist = cv2.calcHist(image, [0], None, [256], [0, 255])
# 使用matplotlib绘制直方图
plt.figure(figsize=(10, 6))
plt.plot(hist)
plt.title("Grayscale Histogram")
plt.xlabel("Bins")
plt.ylabel("# of Pixels")
plt.grid(True)
plt.show()
直方图均衡化:采用的是累计分布函数,具体不做讲解。
API:
cv2.equalizeHist(src[, dst])
- src:输入图像,必须是8位单通道图像(即灰度图)。
- dst(可选):输出图像,与输入图像具有相同的尺寸和类型。
示例:
import cv2
import numpy as np
import matplotlib.pyplot as plt# 绘图展示
def cv_show(name, img):cv2.imshow(name, img)cv2.waitKey(0)cv2.destroyAllWindows()image = cv2.imread('img\\1.png', 0)
image_cut = image[0:500, 0:500]
cv_show("image_cut", image_cut)
image_eq = cv2.equalizeHist(image_cut)
image_hstack = np.hstack((image_cut, image_eq))
cv_show('img', image_hstack)
结果展示:
局部自适应直方图均衡化(CLAHE):全局直方图均衡化可能会导致图像的某些区域过亮或过暗,失去细节。为了解决这个问题,可以使用局部自适应直方图均衡化(Contrast Limited Adaptive Histogram Equalization, CLAHE)。在OpenCV中,可以通过cv2.createCLAHE()
函数创建一个CLAHE对象,然后使用其apply()
方法对图像进行均衡化。
API:
cv2.createCLAHE([, clipLimit[, tileGridSize[, clipNoise]]])
- clipLimit(可选):颜色对比度的阈值,默认为40。用于限制对比度的放大程度,以避免过度放大噪声。
- tileGridSize(可选):均衡化时使用的网格大小,默认为(8, 8)。较大的网格可以减少噪声的放大,但可能会降低对比度增强的效果。
- clipNoise(可选):是否裁剪噪声,对于噪声图像很有用。
示例:
import cv2
import numpy as np
import matplotlib.pyplot as plt# 绘图展示
def cv_show(name, img):cv2.imshow(name, img)cv2.waitKey(0)cv2.destroyAllWindows()image = cv2.imread('img\\1.png', 0)
image_cut = image[0:500, 0:500]
cv_show("image_cut", image_cut)
"""全局"""
image_eq = cv2.equalizeHist(image_cut)
"""自适应"""
# 创建CLAHE对象
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
# 应用CLAHE
image_clahe = clahe.apply(image_cut)
"""图像合并展示"""
image_hstack = np.hstack((image_cut, image_eq, image_clahe))
cv_show('img', image_hstack)
结果展示:
最右为局部自适应直方图均衡化效果。
实验原图
链接跳转:
章节一、OpenCV||超细节的基本操作
章节二、OpenCV||超简略的Numpy小tip
章节三、OpenCV||超详细的图像处理模块
章节五、OpenCV||超详细的图像平滑
章节六、OpenCV||超详细的几何变换