OpenCV||超详细的灰度变换和直方图修正

一、点运算

概念:点运算(也称为像素级运算或单像素操作)是指对图像中每一个像素点进行独立、相同的操作,而这些操作不会考虑像素点之间的空间关系。点处理优势也称对比度拉伸、对比度增强或灰度变换等。

目的:点运算在图像处理中广泛应用于对比度增强、亮度调整、直方图均衡化、图像阈值化等方面。通过点运算,可以改善图像的视觉效果,使其更适合于后续的处理和分析。

分类:点运算可分为灰度变换和直方图修正两大方法,其中直方图修正包括直方图均衡化和直方图规范化。

特点:可逆、无法增强图像细节

应用:光度学标定、对比度增强(对比度扩展)、显示标定、轮廓线(例如用点处理进行图像阈值化处理,根据图像的灰度等级把一幅图像划分成一些不连接的区域,这有助于确定图像中对象的边界或定义蒙版)、裁剪(对于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||超详细的几何变换

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值