大津算法OTSU

1、大津算法OTSU是一种常用的阈值化分割方法,既然是阈值化方法就是需要找到一个阈值,利用这个阈值对图像中所有的像素点进行区分,哪些像素点属于前景,哪些像素点属于背景。

2、如何找到这个阈值呢?OTSU算法中有一个假设,最优的阈值是能够使图像中的前景和背景之间的差最大的那个值,所以大津算法又名最大类间差算法。

3、我们来定义这个类间差(汉字公式,请见谅 ≥Ö‿Ö≤):
类间差 = 前景比重 x 背景比重 x (前景均值 - 背景均值)^2
这个比重其实就是该类所拥有的像素个数,均值就是该类所拥有的像素的灰度均值。

4、有了类间差公式后,阈值就直接遍历0~255,不断的计算类间差值,找到最大的类间差值就可以找到最优的阈值了。
python code:

import cv2 as cv
import math
import numpy as np
def otsu_threshold(img):
    h=img.shape[0]
    w=img.shape[1]
    m=h*w   # 图像像素点总和
    otsuimg=np.zeros((h,w),np.uint8)
    threshold_max=threshold=0   # 定义阈值
    histogram=np.zeros(256,np.int32)   # 初始化各灰度级个数统计参数
    probability=np.zeros(256,np.float32)   # 初始化各灰度级占图像中的分布的统计参数
    for i in range (h):
        for j in range (w):
            s=img[i,j]
            histogram[s]+=1   # 统计灰度级中每个像素在整幅图像中的个数
    for k in range (256):
        probability[k]=histogram[k]/m   # 统计每个灰度级占图像中的分布
    for i in range (255):
        w0 = w1 = 0  # 定义前景像素点和背景像素点灰度级占图像中的分布
        fgs = bgs = 0  # 定义前景像素点灰度级总和and背景像素点灰度级总和
        for j in range (256):
            if j<=i:   # 当前i为分割阈值
                w0+=probability[j]   # 前景像素点占整幅图像的比例累加
                fgs+=j*probability[j]
            else:
                w1+=probability[j]   # 背景像素点占整幅图像的比例累加
                bgs+=j*probability[j]
        u0=fgs/w0   # 前景像素点的平均灰度
        u1=bgs/w1   # 背景像素点的平均灰度
        g=w0*w1*(u0-u1)**2   # 类间方差
        if g>=threshold_max:
            threshold_max=g
            threshold=i
    print(threshold)
    return threshold

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 大津算法(OTSU)在图像处理领域,我们会遇到如下需求:把图像中的目标物体和背景分开。比如背景用白色表示,目标物体...
    invisprints阅读 5,868评论 0 3
  • 边缘检测是图像处理和计算机视觉的基本问题,边缘检测的目的是标识数字图像中亮度变化明显的点,图像属性中的显著变化通常...
    Daniel大人阅读 6,300评论 0 0
  • 此系列的其他文章:OpenCV算法学习笔记之初识OpenCVOpenCV算法学习笔记之几何变换OpenCV算法学习...
    Aengus_Sun阅读 5,242评论 0 5
  • 1.简单阀值cv2.threshold() 当像素值高于阀值时,我们给这个像素赋予一个新值(可能是白色),否则我们...
    Zoe_C阅读 953评论 0 0
  • 虚里人家缈缈烟 比翼飞鸟双双还 无限人生忧愁事 山河繁茂与我闲
    奥_0bf2阅读 226评论 0 0