数字图像分割(二):相似性分割——灰度阈值处理

灰度阈值处理是属于相似性分割的一部分,因为它有着一个判断性的准则:T

基本的判断依据;

g(x,y)=\left\{\begin{matrix} 1,f(x,y)>T & & \\ 0,f(x,y)<T& & \end{matrix}\right.

设置一个中间判断的阈值,大于这个阈值,像素为1(255),小于这个阈值,像素为0。

过程展示如下方的灰度分布直方图,

当然,也可以分多段:

\left\{\begin{matrix} a,f(x,y)<T_{1} & \\ b,T_{1}\leqslant f(x,y)\leq T_{2}& \\ c,T_{2}<f(x,y)& \end{matrix}\right.

 

"""
run:python ThreholdSegmentation.py <img> <threhold>
"""

import numpy as np
import PIL.Image as Image
import sys
import os
import matplotlib.pyplot as plt
import seaborn as sns


# get save path
path_1, path_2 = os.path.split(sys.argv[1])
path_3, _ = os.path.splitext(path_2)
SAVE_PATH = path_1 + path_3 + "_" + sys.argv[2] + "_"


def read_img(img):
    """
    img: sys.argv[1]
    return: gray img as ndarray
    """
    img = Image.open(img, "r")
    img = img.convert("L")
    img = np.asarray(img, dtype=np.uint8)
    return img


def save_img(filename, img):
    """
    img: ndarray
    input_model: model["1","RGB","L"]
    """
    # must be uint8
    img = Image.fromarray(np.uint8(img))
    img.save(SAVE_PATH+filename)

    print("Save {} success!".format(filename))


def Threhold(img, threhold):
    """
    img: gray img as ndarray
    threhold: threhold of gray
    return: binary img as ndarray
    """
    img = np.where(img>np.uint8(threhold), 255, 0)

    return img

def save_count_kde(save_name, img):
    """
    img: gray ndarray
    """

    path1, path2 = os.path.splitext(save_name)

    img_list = img.reshape(-1)
    plt.figure(figsize=(10,5))
    plt.title("GrayScaleValue-Count")
    plt.xlabel("GrayScaleValue")
    plt.ylabel("Count")
    sns.countplot(img_list)
    
    plt.savefig(SAVE_PATH+path1+"_count"+path2)
    print(f"Save {path1}_count{path2} success!")

    plt.figure(figsize=(10,5))
    plt.title("GrayScaleValue-Kde")
    plt.xlabel("GrayScaleValue")
    plt.ylabel("Kde")
    sns.kdeplot(img_list)

    plt.savefig(SAVE_PATH+path1+"_kde"+path2)
    print(f"Save {path1}_kde{path2} success!")



if __name__ == "__main__":
    if len(sys.argv) != 3 :
        print(__doc__)
        exit(1)
    img_gray = read_img(sys.argv[1])
    save_img("gray.png", img_gray)
    save_count_kde("gray.png", img_gray)
    
    img_binary = Threhold(img_gray, sys.argv[2])
    save_img("binary.png", img_binary)
    save_count_kde("binary.png", img_binary)


设置阈值为170:

如果阈值设置为200:

图片的左上方灰度区域影响最大,直接成了一片,这里就说明分割效果没有170理想。

我们该如何选取一个合适的阈值呢?

人们就想出了一个全局的自适应的阈值处理:

基本的过程为:

# 这段代码 日后补全
# 没太多时间
# 整体上在作阈值判断的时候,作列表/迭代器的分类
# 做while 或for循环

# 写程序的时候:是否考虑栈与队列对代码效率的影响?

整个过程类似于K-means=>设置初始点、分为两类、计算像素距离作平均、更新中心点、循环、直至迭代次数达到限制或中心差值到达限制。

在这里,噪声同时也会对阈值处理产生影响,具体见上篇内容。

可以看出,对于噪声的处理,对于图像操作来讲,是十分重要的!

 

# 此外,阈值的处理还有 :
# 边缘+阈值  的组合形式
# 自动阈值处理
# 等

# 日后有时间继续补充信息与代码

# 2020-09-25

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值