图像分割-阈值分割-python-opencv

图像分割是计算机视觉最基础的任务。在图像分割中,最基础的方法便是阈值分割。阈值分割,顾名思义就是使用一个阈值将图像背景和前景分开。OSTU,即大津法是阈值分割算法中常用的算法之一。总体而言,大津法的思路是寻找一个可以使得背景和前景两类像素之间类间距离最大化。详细的思路如下:

我们定义前景类为C_{1},总共有n_{1}个像素,背景类为C_{2} , 总共有n_{2}个像素。那么这种图像一个有N=n_{1}+n_{2}个像素。

对于C_{1},其像素的概率为P_{1}, 其灰度平均值为m_{1} , 对于C_{2},其像素的概率为P_{2}, 其灰度平均值为m_{2}, 那么所有它们的方差为:

\sigma ^2 =\sum_{i\in C_{1}} P_{i}(i-m_{1})^2 +\sum_{i\in C_{2}} P_{i}(i-m_{2})^2

其中,P_{i}表示灰度值为i的像素的比例,i 为灰度值。我们的目的即使找到一个阈值K,低于K的像素归为C_{1}, 大于K归为C_{2}类 ,从而使得\sigma ^2最大。我们可以表达为:

                                                        \arg\max_{K} \sigma ^2

 对于如何寻找最佳的K,对于一张灰度图像,其灰度值范围在0-255之间,我们可以遍历这256个值来寻找最佳的K。如果想要减少计算量,那么最简单的方法便是绘制灰度直方图,找到两个峰之间的谷,取一定范围遍历,寻找最佳的K。

import  cv2
import numpy  as np


def get_mean(histogram):
    total=np.sum(histogram)
    mean=0
    for i in range(len(histogram)):
        mean+=(histogram[i]/total)*i
    return mean
def get_variance(histogram,mean):
    total=np.sum(histogram)
    variance=0
    for i in range(len(histogram)):
        variance+=(histogram[i]/total)*((i-mean)**2)
    return variance
def OSTU(img):
    h,w=img.shape
    total=h*w
    best_k=0
    max_variance=-10000
    histogram=np.zeros(256)
    for i in range(h):
        for j in range(w):
            histogram[img[i,j]]+=1
    for k in range(256):
        bg=histogram[:k]
        object=histogram[k:]
        bg_mean=get_mean(bg)
        object_mean=get_mean(object)
        bg_variance=get_variance(bg,bg_mean)
        object_variance=get_variance(object,object_mean)
        variance=bg_variance+object_variance
        if(variance>max_variance):
            max_variance=variance
            best_k=k
    img[img>=best_k]=255
    img[img<best_k]=0
    return img

            

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值