在图像处理领域,阈值处理(Thresholding)是一种简单而有效的技术,用于将灰度图像转化为二值图像(即每个像素点要么是黑色,要么是白色)。这种处理方式常用于分割图像中的前景和背景,或者提取特定的形状或物体。
阈值处理的基本思想是设定一个阈值 T T T,然后遍历图像中的每一个像素。如果像素的灰度值高于阈值,就将其设为白色(通常为255);如果低于阈值,则将其设为黑色(通常为0)。公式如下:
g ( x , y ) = { 255 , i f f ( x , y ) > T 0 , i f f ( x , y ) ≤ T (1) g(x,y)= \begin{cases} 255,if\quad f(x,y)>T\\ 0, if\quad f(x,y)\leq T \end{cases} \tag{1} g(x,y)={255,iff(x,y)>T0,iff(x,y)≤T(1)
其中, f ( x , y ) f(x,y) f(x,y) 是原始图像的灰度值, g ( x , y ) g(x,y) g(x,y) 是处理后的二值图像。
cv2.threshold
。import cv2
# 读取灰度图像
image = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE)
# 全局阈值处理
_, thresh_global = cv2.threshold(image, 127, 255, cv2.THRESH_BINARY)
# 显示结果
cv2.imshow('Global Thresholding', thresh_global)
cv2.waitKey(0)
cv2.destroyAllWindows()
自适应阈值方法会根据图像的局部区域动态计算阈值,因此对于光照不均或对比度较低的图像更有效。自适应阈值根据局部窗口内的像素值计算每个像素的阈值,从而避免了全局阈值对整个图像的统一处理。
自适应阈值(Adaptive Thresholding)的工作原理是根据图像局部区域的特征来动态调整阈值,从而处理光照不均或对比度不够的图像。它的主要思想是对于图像中的每一个像素,根据其周围邻域的像素值来确定一个局部阈值。这样可以避免全局阈值方法可能带来的效果不佳的问题,尤其是在图像的不同区域光照差异较大的情况下。
对于图像中的每一个像素点,自适应阈值方法会考虑该像素点周围的一定范围内的像素值。这些像素值形成了一个局部区域或窗口。
通过计算这个局部区域内的像素值的加权平均(或均值),得到一个阈值。加权平均意味着某些像素对计算结果的影响比其他像素更大,通常是窗口中心的像素权重更高。
计算出的加权平均值(或均值)被用作该像素点的局部阈值。这个阈值代表了该像素所在局部区域的“亮度”水平。
使用计算得到的局部阈值来决定该像素点的类别。具体地说:
如果当前像素的值大于或等于局部阈值,则将其分类为前景(通常设为 255,白色)。
如果当前像素的值小于局部阈值,则将其分类为背景(通常设为 0,黑色)。
1. 局部邻域计算:
2. 局部阈值计算:
对于每个局部区域,计算其局部阈值的常用方法包括均值和高斯加权平均:
均值自适应阈值(Adaptive Mean Thresholding): 阈值等于邻域像素的平均值减去一个常量。公式如下:
公式: T ( x , y ) = m e a n ( I ( x , y ) ) − C T(x,y)=mean(I(x,y))−C T(x,y)=mean(I(x,y))−C
其中:
在这种方法中,阈值是由邻域内像素的均值减去一个常数 C C C计算得到的。常数 C C C用于避免噪声对分割结果的影响。
高斯自适应阈值(Adaptive Gaussian Thresholding): 阈值等于邻域像素的加权平均值(权重为高斯窗口)减去一个常量。公式如下:
在这种方法中,阈值是由邻域内像素的均值减去标准差的 C C C倍计算得到的。这样可以更好地处理局部的光照变化和噪声。
3.二值化处理:
import cv2
# 读取灰度图像
image = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE)
# 自适应均值阈值处理
thresh_mean = cv2.adaptiveThreshold(image, 255, cv2.ADAPTIVE_THRESH_MEAN_C,
cv2.THRESH_BINARY, 11, 2)
# 自适应高斯阈值处理
thresh_gaussian = cv2.adaptiveThreshold(image, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
cv2.THRESH_BINARY, 11, 2)
# 显示结果
cv2.imshow('Adaptive Mean Thresholding', thresh_mean)
cv2.imshow('Adaptive Gaussian Thresholding', thresh_gaussian)
cv2.waitKey(0)
cv2.destroyAllWindows()
自定义实现(不使用 OpenCV)
如果你需要从头开始实现自适应阈值处理,以下是一个简化的 Python 代码示例:
import numpy as np
import cv2
def adaptive_threshold(image, block_size, C):
rows, cols = image.shape
padded_image = np.pad(image, pad_width=block_size//2, mode='constant', constant_values=0)
result = np.zeros_like(image)
for i in range(rows):
for j in range(cols):
block = padded_image[i:i+block_size, j:j+block_size]
mean = np.mean(block)
threshold = mean - C
result[i, j] = 255 if image[i, j] >= threshold else 0
return result
# 读取图像(以灰度模式)
image = cv2.imread('input_image.png', cv2.IMREAD_GRAYSCALE)
# 设置自适应阈值参数
block_size = 11
constant = 2
# 计算自适应阈值
adaptive_thresh = adaptive_threshold(image, block_size, constant)
# 显示结果
cv2.imshow('Original Image', image)
cv2.imshow('Adaptive Threshold', adaptive_thresh)
# 等待按键并销毁窗口
cv2.waitKey(0)
cv2.destroyAllWindows()
# 保存处理后的图像(可选)
cv2.imwrite('adaptive_thresh_custom.png', adaptive_thresh)
Otsu’s 阈值法是一种自动选择阈值的全局方法。它通过分析图像的灰度直方图,找到能够最大化类间方差(前景和背景)的阈值。Otsu’s 方法适用于双峰分布的图像(即前景和背景的灰度值分布相对独立且存在两个峰值)。
最大化类间方差(Between-Class Variance)是 Otsu’s 阈值法的核心概念,旨在选择一个最佳阈值,使得图像的前景和背景之间的差异最大化。这种方法通过分析图像的灰度直方图,找到一个阈值,使得图像被分割成前景和背景后,它们之间的类间方差最大。
Otsu’s 方法遍历所有可能的阈值,并计算每个阈值对应的类间方差,选择使类间方差最大的阈值作为最终的阈值。
公式推导链接:https://blog.csdn.net/leonardohaig/article/details/120269341
OpenCV 中可以通过设置 cv2.THRESH_OTSU
来使用。
import cv2
# 读取灰度图像
image = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE)
# Otsu's 阈值处理
_, thresh_otsu = cv2.threshold(image, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
# 显示结果
cv2.imshow('Otsu Thresholding', thresh_otsu)
cv2.waitKey(0)
cv2.destroyAllWindows()
代码
import cv2
import numpy as np
# 读取图像并转换为灰度图像
image = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE)
# 全局阈值处理
_, thresh_global = cv2.threshold(image, 127, 255, cv2.THRESH_BINARY)
# 自适应阈值处理
thresh_adaptive = cv2.adaptiveThreshold(image, 255, cv2.ADAPTIVE_THRESH_MEAN_C,
cv2.THRESH_BINARY, 11, 2)
# Otsu's 阈值处理
_, thresh_otsu = cv2.threshold(image, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
# 显示结果
cv2.imshow('Global Thresholding', thresh_global)
cv2.imshow('Adaptive Thresholding', thresh_adaptive)
cv2.imshow('Otsu Thresholding', thresh_otsu)
cv2.waitKey(0)
cv2.destroyAllWindows()
阈值处理是图像预处理中常用的步骤,尤其适合对噪声较少、对比度较高的图像进行处理。根据具体应用的需要,可以选择合适的阈值处理方法。