Python+OpenCV之Bernsens局部自适应阈值法

本文介绍了Bernsens局部自适应阈值算法,该算法将窗口中像素灰度级最值平均值作为中心像素阈值,适应性广,不受非均匀光照影响。给出编程思路,包括输入转灰、遍历像素、计算窗口阈值和二值化。实验显示该算法简单实用,但干扰点较多。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原理分析:
Bernsens算法是一种典型的局部阈值算法,其将窗口中各个四昂素灰度级最大值和最小值的平均值作为一个窗口的中心像素的阈值,因此此方法不存在预定阈值,适应性较整体阈值法广,不受非均匀光照条件等情况的影响。
设图像在像素点 (i,j) 处的灰度值 f(i,j) ,考虑以像素点(i,j)为中心的 (2w+1)*(2w+1) 窗口,其中2w+1表示窗口的边长,则Bernsen算法可以描述为:
计算图像中各个像素点 (i,j) 的阈值 T(i,j)
在这里插入图片描述
图像中各个像素点 (i,j)用 b(i,j) 值逐点进行二值化
在这里插入图片描述
以上内容摘自论文《局部自适应二值化方法研究》(王序哲)

编程思路:
(1)输入图像并转灰;
(2)对灰度图进行像素点遍历:
(3)以遍历到的像素点为中心,以3*3矩阵为局部窗口,找出窗口中像素级最大值和最小值之和的均值,将其计为窗口阈值;
(4)比较遍历到的像素点灰度级与窗口阈值大小,并进行二值化。

代码:

import cv2 as cv
import numpy as np

def rgb2gray(img):
    h=img.shape[0]
    w=img.shape[1]
    grayimg=np.zeros((h,w),np.uint8)
    for i in range (h):
        for j in range (w):
            grayimg[i,j]=0.144*img[i,j,0]+0.587*img[i,j,1]+0.299*img[i,j,2]
    return grayimg

def bernsens(img):
    h=img.shape[0]
    w=img.shape[1]
    img1=np.zeros((h,w),np.uint8)
    for i in range (1,h-1):
        for j in range (1,w-1):
            matrix=np.zeros((3,3),np.uint8)
            for k in range (-1,2):
                for l in range (-1,2):
                    matrix[k+1,l+1]=img[i+k,j+l]
            threshold=(np.max(matrix)+np.min(matrix))/2
            if img[i,j]>=threshold:
                img1[i,j]=255
            else:
                img1[i,j]=0
    return img1

image=cv.imread("D:/Testdata/a.png")
grayimage=rgb2gray(image)
thresholdimage=bernsens(grayimage)
cv.imshow("image",image)
cv.imshow("grayimage",grayimage)
cv.imshow("thresholdimage",thresholdimage)
cv.waitKey(0)
cv.destroyAllWindows()

实验结果:
灰度图如下:
在这里插入图片描述
二值化图如下:
在这里插入图片描述
Bernsens算法相较其它局部自适应二值化算法相对简单,而且对图像处理不受光照影响,但效果显而易见,干扰点较多,看着并不理想,总之还算比较实用吧。

### Python 中实现局部自适应阈值法 在图像处理领域,局部自适应阈值法是一种重要的技术,尤其适用于非均匀光照条件下或背景复杂的场景。以下是基于 OpenCV 和 NumPy 库,在 Python 中实现局部自适应阈值法方法。 #### 方法概述 局部自适应阈值法的核心思想是以每个像素为中心定义一个小区域(通常是一个矩形窗口),并计算该区域内像素的统计特性来决定当前像素的阈值。这种方法能够有效应对全局亮度变化带来的影响[^3]。 #### 实现步骤说明 以下代码展示了如何通过 `cv2` 和 `numpy` 来实现 Bernsen 自适应阈值算法: ```python import cv2 import numpy as np def bernsen_threshold(image, window_size=15, threshold_difference=15): """ 使用 Bernsen 算法实现局部自适应阈值法。 参数: image: 输入灰度图像 (ndarray) window_size: 邻域窗口大小,默认为 15x15 threshold_difference: 判断是否应用固定阈值的标准差 返回: result_image: 处理后的二值化图像 """ height, width = image.shape[:2] result_image = np.zeros((height, width), dtype=np.uint8) pad_width = int(window_size / 2) padded_image = cv2.copyMakeBorder(image, pad_width, pad_width, pad_width, pad_width, borderType=cv2.BORDER_CONSTANT, value=0) for i in range(height): for j in range(width): local_window = padded_image[i:i + window_size, j:j + window_size] min_val = np.min(local_window) max_val = np.max(local_window) if (max_val - min_val) >= threshold_difference: threshold = (min_val + max_val) / 2 result_image[i][j] = 255 if image[i][j] > threshold else 0 else: result_image[i][j] = 255 # 如果对比度过低,则视为前景 return result_image # 加载原始图像并转换为灰度图 original_image = cv2.imread('input.jpg', cv2.IMREAD_GRAYSCALE) if original_image is None: raise ValueError("无法加载输入图片") # 调整图像尺寸以加快处理速度 resized_image = cv2.resize(original_image, None, fx=0.5, fy=0.5, interpolation=cv2.INTER_AREA)[^2] # 执行 Bernsen 自适应阈值处理 thresholded_image = bernsen_threshold(resized_image, window_size=15, threshold_difference=15) # 显示结果 cv2.imshow('Original Image', resized_image) cv2.imshow('Thresholded Image', thresholded_image) cv2.waitKey(0) cv2.destroyAllWindows() ``` 上述代码实现了 Bernsen 局部自适应阈值法,并允许调整窗口大小和对比度差异参数。对于复杂环境下的图像分割任务非常有用。 #### 关键点解析 - **邻域窗口**: 定义了一个方形滑动窗口用于提取局部特征。窗口越大,计算成本越高,但能更好地平滑噪声;反之则更敏感于细节。 - **动态阈值计算**: 对每个像素位置分别求取其周围区域的最大值与最小值作为依据设定个体化的阈值标准。 - **性能优化建议**: 若目标图像较大可先缩小比例再执行操作从而减少运算量[^2]。 ---
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值