大津法图像分割 python手写算法 没用cv2

1. 基本概念

用大津法最终会得到一个阈值,使用该阈值将图像进行二值化。大于这个阈值的,像素值变成1;小于阈值的,像素值变成0。 原本图像的像素范围是从0~255,大津法的思想很简单,就是遍历这256个阈值,对每个阈值,都进行一次二值化。最终看哪个阈值下二值化的结果最合适。接下来就介绍遍历的公式。

2. 公式

这里我将像素值为1的称作前景,像素值为0的称作后景。
大津法的最终公式为很多小的计算拼起来的,如下

2.1 后景像素比w0

ω 0 = 后景像素数量 图像宽 ∗ 图像高 (1) \omega_0= \frac{后景像素数量}{图像宽 *图像高}\tag{1} ω0=图像宽图像高后景像素数量(1)

2.2 前景像素比w1

ω 1 = 前景像素数量 图像宽 ∗ 图像高 (2) \omega_1= \frac{前景像素数量}{图像宽 *图像高}\tag{2} ω1=图像宽图像高前景像素数量(2)

2.3 后景平均灰度u0

μ 0 = ∑ a l l 后景像素的值 后景像素数量 (3) \mu_0 =\frac{ \sum_{all}后景像素的值}{后景像素数量}\tag{3} μ0=后景像素数量all后景像素的值(3)

2.4 前景平均灰度u1

μ 1 = ∑ a l l 前景像素的值 前景像素数量 (4) \mu_1 =\frac{ \sum_{all}前景像素的值}{前景像素数量}\tag{4} μ1=前景像素数量all前景像素的值(4)

2.5 公式汇合

根据式1~4,可以得到(5)
μ = ω 0 ∗ μ 0 + ω 1 ∗ μ 1 、 (5) \mu = \omega_0*\mu_0 + \omega_1*\mu_1 、\tag{5} μ=ω0μ0+ω1μ1(5)
其中 μ \mu μ是图像的平均灰度

而大津法的公式为
g = ω 0 ∗ ( μ 0 − μ ) 2 + ω 1 ∗ ( μ 1 − μ ) 2 (6) g = \omega_0*(\mu_0-\mu)^2 + \omega_1*(\mu_1-\mu)^2 \tag{6} g=ω0(μ0μ)2+ω1(μ1μ)2(6)
将(5)带(6),可以得到(7)
g = ω 0 ω 1 ( μ 0 − μ 1 ) 2 (7) g = \omega_0\omega_1(\mu_0-\mu_1)^2 \tag{7} g=ω0ω1(μ0μ1)2(7)

3. 代码

代码部分中,上述的公式都会体现出来。已经被注释所标注。

import numpy as np
import math

'''
Summary:
	大津阈值分割
Paramaters:
	img - 输入的灰度图像 是二维矩阵
'''
def OTSU(img):
    # 类间方差g初始最小
    g_raw = -1
    # 要返回的阈值
    T_return = 0
    # 获得图像大小
    M_N = img.shape[0]*img.shape[1]
    # 大津阈值算法
    for T in range(256):
        # 获取阈值大于T和小于T的两个列表
        array0 = img[img<T] 
        array1 = img[img>T]
        # 算出w0和w1
        w0 = len(array0)/M_N  # 公式1
        w1 = len(array1)/M_N  # 公式2
        # 算出μ0和μ1 这里需要特判除数为0
        if len(array0) == 0:
            mu0 = 0
        else:
            mu0 = sum(array0)/len(array0) # 公式3
        if len(array1) == 0:
            mu1 = 0
        else:
            mu1 = sum(array1)/len(array1)  # 公式4
        # 算出g
        g=w0*w1*math.pow((mu0-mu1),2)  # 公式6
        if g > g_raw:
            g_raw = g
            T_return = T
    return T_return

使用该图进行测试,效果如下所示
请添加图片描述

import cv2

# 读取图片
img = Image.open('2.png')
# 转换成灰度图
img=img.convert('L')
# 转换成array
arr = np.array(img)
# # 获得最佳域值分割
T = OTSU(arr)
print(T)
# 根据阈值进行二值分割
arr[arr>T] = 255
arr[arr<T] = 0
# 展示分割结果
pil_image=Image.fromarray(arr)
pil_image

在这里插入图片描述

  • 5
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 13
    评论
大津法(Otsu's method)是一种自适应阈值分割方法,它通过找到一个阈值,使得两个类内的方差都最小,从而将图像分割为前景和背景。在大津法,通过计算图像的灰度直方图和累积分布函数,然后根据不同的阈值计算类内方差,最终选择使类内方差最小的阈值作为最佳阈值。 在Python,可以使用OpenCV库来实现大津法阈值分割。首先,读取图像并进行高斯模糊处理,然后计算图像的灰度直方图和累积分布函数。接下来,通过遍历不同的阈值,计算每个阈值下的类内方差,并选择使类内方差最小的阈值作为最佳阈值。最后,使用OpenCV的阈值分割函数将图像分割为前景和背景。 以下是一个使用大津法阈值分割的Python代码示例: ```python import cv2 import numpy as np # 读取图像并进行高斯模糊处理 img = cv2.imread('road.jpg', 0) blur = cv2.GaussianBlur(img, (5, 5), 0) # 计算灰度直方图和累积分布函数 hist = cv2.calcHist(\[blur\], \[0\], None, \[256\], \[0, 256\]) hist_norm = hist.ravel() / hist.max() Q = hist_norm.cumsum() bins = np.arange(256) # 初始化最小方差和阈值 fn_min = np.inf thresh = -1 # 遍历不同的阈值,计算类内方差 for i in range(1, 256): p1, p2 = np.hsplit(hist_norm, \[i\]) q1, q2 = Q\[i\], Q\[255\] - Q\[i\] b1, b2 = np.hsplit(bins, \[i\]) m1, m2 = np.sum(p1 * b1) / q1, np.sum(p2 * b2) / q2 v1, v2 = np.sum(((b1 - m1) ** 2) * p1) / q1, np.sum(((b2 - m2) ** 2) * p2) / q2 fn = v1 * q1 + v2 * q2 if fn < fn_min: fn_min = fn thresh = i # 使用OpenCV的阈值分割函数进行分割 ret, otsu = cv2.threshold(blur, thresh, 255, cv2.THRESH_BINARY) print("最佳阈值: ", thresh) print("OpenCV计算的阈值: ", ret) ``` 这段代码首先读取图像并进行高斯模糊处理,然后计算灰度直方图和累积分布函数。接下来,遍历不同的阈值,计算每个阈值下的类内方差,并选择使类内方差最小的阈值作为最佳阈值。最后,使用OpenCV的阈值分割函数将图像分割为前景和背景,并打印出最佳阈值和OpenCV计算的阈值。 希望对你有帮助! #### 引用[.reference_title] - *1* *2* [【opencv-python大津法(Otsu)阈值分割原理深入分析](https://blog.csdn.net/huangzhe0701/article/details/120485879)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [Python+OpenCV:阈值分割](https://blog.csdn.net/liubing8609/article/details/109659209)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值