灰度阈值处理是属于相似性分割的一部分,因为它有着一个判断性的准则:T
基本的判断依据;
设置一个中间判断的阈值,大于这个阈值,像素为1(255),小于这个阈值,像素为0。
过程展示如下方的灰度分布直方图,
当然,也可以分多段:
"""
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