数字图像处理——最大类间方差法(OTSU)图像阈值分割实例

article/2025/8/7 21:43:38

数字图像处理——最大类间方差法(OTSU)图像阈值分割实例

数字图像处理——最大类间方差法(OTSU)图像阈值分割实例

图像阈值分割是指通过以某个确定的图像灰度值(灰度级)将图像分为不同的部分,其目的通常是将需要的目标从图像中分割出来,图像分割在数字图像处理领域具有重要作用。
最大类间方差法,也称为Otsu方法,是应用广泛的图像分割法之一,该方法是通过计算图像灰度级的类间方差最大值或者类内方差最小值来确定分割阈值的标准。具体操作方法是通过遍历数字图像的灰度图像灰度级直方图的全部灰度级作为图像灰度级分割阈值,在每个阈值下将图像灰度按阈值划分为两类,如果在某个阈值下,两类灰度值的类间方差达到最大,或者类内方差达到最小,则该阈值即为最佳分割阈值。

Python实现最大类间方差法分割图像实例

待分割的图像文件名:inkpad2.jpg,该图像是彩色图像,每个像素包含RGB三种颜色,本实例的任务是将印台(红色)部分图像与背景(绿色)部分图像通过最大类间方差法进行阈值分割。
图片在我电脑中的保存位置:D:\ZJPythonFiles\opencv45564\inkpad2.jpg,该位置应根据实际进行修改,如果不想用这张图片,可以换成其他图片,最大类间方差法是二分类

图1 待处理的原始图像在这里插入图片描述最大类间方差法分割图像的步骤:
1.将真彩色图像转换为灰度图像。
在这里插入图片描述
2.绘制灰度级直方图。
在这里插入图片描述
3.遍历灰度级,计算出各灰度级对应的目标和背景的类间方差。计算目标和背景的最大类间方差,此时对应的灰度值即为最佳阈值。用该阈值分割图像的灰度值即可实现图像的阈值分割。
在这里插入图片描述
以下代码是实例的完整代码,其中使用了名剑求瑕的python灰度图中的代码,用于将RGB真彩色图像转换为灰度图像,使用了mormal的OTSU算法(大津法—最大类间方差法)原理及实现中的代码用于实现将灰度图像进行最大类间方差法进行阈值分割。

#otsu
# 彩色图像转换成灰度图像
import numpy as np
from matplotlib import pyplot as plt
from PIL import Image
# 将一个RGB颜色转换成灰度值,结果保留整数
def RGBtoGray(r, g, b):########## Begin ##########gray = round(r*0.299 + g*0.587 + b*0.114)########## End ##########return gray
# 将真彩色图像转换成灰度图
# 真彩色和灰度图的文件路径分别为path1和path2
def toGrayImage(path1, path2):img1 = Image.open(path1)  # 真彩色图像,像素中是RGB颜色w, h = img1.sizeimg2 = Image.new('L', (w, h))  # 新建一个灰度图像,像素中是灰度值########## Begin ########### 此部分功能:依次取出img1中每个像素的RGB颜色,转换成灰度值,再放到img2的对应位置for x in range(w):for y in range(h):r, g, b = img1.getpixel((x, y))  # 取出颜色gray = RGBtoGray(r, g, b) # 转成灰度值img2.putpixel((x, y), gray)  # 放回像素########## End ##########img2.save(path2)
#  otsu算法
def otsu(gray):pixel_number = gray.shape[0] * gray.shape[1]mean_weigth = 1.0/pixel_number# #统计各灰度级的像素个数,灰度级分为256级# bins必须写到257,否则255这个值只能分到[254,255)区间his, bins = np.histogram(gray, np.arange(0,257))# 绘制直方图plt.figure(figsize=(12,8))plt.hist(gray,256,[0,256],label='灰度级直方图') #运行比较慢,如果电脑卡顿,可以将本行代码注释掉plt.show()final_thresh = -1final_value = -1intensity_arr = np.arange(256) #灰度分为256级,0级到255级for t in bins[1:-1]: # 遍历1到254级 (一定不能有超出范围的值)pcb = np.sum(his[:t])pcf = np.sum(his[t:])Wb = pcb * mean_weigth#像素被分类为背景的概率Wf = pcf * mean_weigth#像素被分类为目标的概率mub = np.sum(intensity_arr[:t]*his[:t]) / float(pcb)#分类为背景的像素均值muf = np.sum(intensity_arr[t:]*his[t:]) / float(pcf)#分类为目标的像素均值#print mub, mufvalue = Wb * Wf * (mub - muf) ** 2 #计算目标和背景类间方差if value > final_value:final_thresh = tfinal_value = valuefinal_img = gray.copy()print(final_thresh)final_img[gray > final_thresh] = 255final_img[gray < final_thresh] = 0return final_imgpath1 = r'D:\ZJPythonFiles\opencv45564\inkpad2.jpg'  # 真彩色图像
path2 = r'D:\ZJPythonFiles\opencv45564\inkpad2_grayA.jpg'  # 灰度图像
toGrayImage(path1, path2)
imgcolor=plt.imread(path1)
imggray=plt.imread(path2)
plt.imshow(imgcolor)
plt.show()
plt.imshow(imggray,cmap='gray')
plt.show()
plt.imshow(otsu(imggray),cmap='gray')
print(otsu(imggray))
plt.show()

参考:
1.normal的Otsu算法原理与python实现,https://blog.csdn.net/u011285477/article/details/52004513
2.名剑求瑕的python灰度图,https://blog.csdn.net/qq_42833469/article/details/121575782


http://chatgpt.dhexx.cn/article/LAdRnM1e.shtml

相关文章

【图像分割】最大类间方差法(otsu)图像分割

由Otsu(大津展之)于1978年提出的最大类间方差法&#xff0c;是引起较多关注的一种阈值选取方法。它是在判决分析或最小二乘原理的基础上推导出来的。 参考文献&#xff1a; [1] Otsu N. A threshold selection method from gray-level histogram. IEEE Trans,1979;SMC-9;62-66 …

最大类间方差法Ostu的C++实现

① 设灰度级为L&#xff0c;灰度值i的像素出现的频数为。分别为所纷呈的两个像素类的面积比&#xff0c;即 ② 分别为两个像素类的平均灰度值&#xff0c;即 ③计算类间方差&#xff0c;并找出最大类间方差以及对应的阈值。 ④ 求为最大值时的t&#xff0c;作为图像分割的最…

图像分割 - 阈值处理 - 最大类间方差法(OTSU)

目录 1. OTSU 介绍 2. 代码实现 1. OTSU 介绍 OTSU 大津法&#xff0c;也是最大类间方差算法 OTSU 算法的思想通过不同的阈值K&#xff0c;将图像的分为两个区域&#xff0c;一个是灰度值 0 < k < K 的子区域G1&#xff1b;另一个是灰度值 K1 < k < L-1 的子区…

【零散知识】最大类间方差法(大津法,Otsu)

前言&#xff1a; { 最近特别忙&#xff08;或者说时间规划出了问题&#xff09;&#xff0c;所以更新的都是短篇。 本次的内容是最大类间方差法&#xff08;大津法&#xff0c;Otsu&#xff09;。 } 正文&#xff1a; { 根据[1]中的介绍&#xff0c;大津法的主要作用是二值…

「 Redis 」 SkipList 跳表底层实现及应用

「 Redis 」 SkipList 跳表底层实现及应用 参考&鸣谢 Redis中ZSet的底层数据结构跳跃表skiplist&#xff0c;你真的了解吗&#xff1f; RiemannChow 深入理解跳表及其在Redis中的应用 京东云开发者 Redis跳表底层实现 来年花惜 文章目录 「 Redis 」 SkipList 跳表底层实现…

Redis 中的底层数据结构:SkipList

一、SkipList 简介 SkipList(5.0) 是zset的底层实现之一&#xff0c;它的数据结构定义如下&#xff1a; /* ZSETs use a specialized version of Skiplists */ typedef struct zskiplistNode {sds ele; //成员对象double score; //分值struct zskiplistNode *backward; //后退…

skiplist原理与实现

今天继续介绍分布式系统当中常用的数据结构&#xff0c;今天要介绍的数据结构非常了不起&#xff0c;和之前介绍的布隆过滤器一样&#xff0c;是一个功能强大原理简单的数据结构。并且它的缺点和短板更少&#xff0c;应用更加广泛&#xff0c;比如广泛使用的Redis就有用到它。 …

【数据结构】跳表Skiplist

文章目录 跳表--skiplistskiplist的概念skilplist的原理skilplist的实现随机值函数跳表节点 跳表框架查找函数寻找前置节点添加元素删除元素打印链表 测试结果Skiplist与其他Key-Value结构的比较 跳表–skiplist skiplist的概念 skiplist本质上也是一种查找结构&#xff0c;用…

Skiplist跳表详解及其模拟实现

文章目录 跳表1.跳表的概念2.Skiplist在插入时采用随机层数的方法是如何保证效率的呢?3.跳表的模拟实现4.跳表VS平衡搜索树和哈希表 跳表 1.跳表的概念 跳表是基于有序链表扩展实现的。对于一个普通的有序链表&#xff0c;我们查找数据的时间复杂度是O(N)。而跳表的出现&…

skiplist - 跳表

一 前言 跳表(skiplist、跳跃表) 是一个很优秀的数据结构&#xff0c;比如用于 Redis、levelDB等出名的开源项目上。跳表在原有的有序链表上面增加了多级索引&#xff0c;通过索引来实现快速查找。 它的结构特点在名称能很好的体现出来&#xff0c;就像兔子一样&#xff0c;蹦…

Leveldb skiplist 实现及解析

skiplist 原理介绍 skiplist 由William Pugh 在论文Skip Lists: A Probabilistic Alternative to Balanced Trees 中提出的一种数据结构,skiplist 是一种随机化存储的多层线性链表结构,插入,查找,删除的都是对数级别的时间复杂度。skiplist 和平衡树有相同的时间复杂度,但…

跳表SkipList介绍与实现

目录 一.跳表介绍 二.实现思路 &#xff08;一&#xff09;.结点结构 &#xff08;二&#xff09;.检索 &#xff08;三&#xff09;.插入 &#xff08;四&#xff09;.删除 三.实现代码 一.跳表介绍 跳表是一种随机化数据结构&#xff0c;主要用于快速检索数据。实质上…

SkipList(跳表)

SkipList(跳表) 文章目录 SkipList(跳表)参考前言跳表的原理跳表的插入和删除插入操作删除操作 跳表的时间空间复杂度分析时间复杂度空间复杂度 调表的基本操作插入数据删除数据 Go 实现小结 参考 https://juejin.cn/post/6844903955831619597#heading-2https://blog.csdn.net…

每日一博 - 如何理解跳表(SkipList)

文章目录 什么是跳跃表SkipList跳表关键字Why Skip ListCode跳表-查询跳表-删除跳表-插入 小结完整Code 什么是跳跃表SkipList 跳跃表(简称跳表)由美国计算机科学家William Pugh于1989年发明 论文&#xff1a; Skip lists: a probabilistic alternative to balanced trees 跳…

Skiplist(跳表)实现

前言&#xff1a;跳表本质是一种查找结构&#xff0c;相较于AVL树、红黑树、哈希表&#xff0c;实现起来要更加简单&#xff0c;而且效率也不差。 一.Skiplist概念 跳表本质也是一种查找结构&#xff0c;用于解决算法中的查找问题&#xff0c;跟平衡搜索树&#xff08;AVL树、红…

跳表(SkipList)设计与实现(java)

微信搜一搜「bigsai」关注这个有趣的程序员&#xff0c;一起做个朋友 新人原创公众号&#xff0c;求支持一下&#xff01;你的点赞三连肯定对我至关重要&#xff01; 文章已收录在 我的Github bigsai-algorithm 欢迎star 前言 跳表是面试常问的一种数据结构&#xff0c;它在很…

SkipList和java中ConcurrentSkipListMap的实现

文章目录 简介SkipListConcurrentSkipListMapSkipList的实现concurrent的实现 总结 SkipList和java中ConcurrentSkipListMap的实现 简介 一开始听说SkipList我是一脸懵逼的&#xff0c;啥&#xff1f;还有SkipList&#xff1f;这个是什么玩意。 后面经过我的不断搜索和学习&a…

跳表(SkipList)及ConcurrentSkipListMap源码解析

二分查找和AVL树查找 二分查找要求元素可以随机访问&#xff0c;所以决定了需要把元素存储在连续内存。这样查找确实很快&#xff0c;但是插入和删除元素的时候&#xff0c;为了保证元素的有序性&#xff0c;就需要大量的移动元素了。 如果需要的是一个能够进行二分查找&#…

Redis数据结构之——跳表skiplist

写在前面 以下内容是基于Redis 6.2.6 版本整理总结 一、跳表&#xff08;skiplist&#xff09; 如何理解跳表&#xff1f;在了解跳表之前&#xff0c;我们先从普通链表开始&#xff0c;一点点揭开跳表的神秘面纱~ 首先&#xff0c;普通单链表来说&#xff0c;即使链表是有序…

redis中ziplist,skiplist

ziplist压缩表 ziplist主要是为了节约内存&#xff0c;他将元素存储在一块连续的内存空间中&#xff0c;这样在查询数据的时候也可以利用CPU的缓存访问数据&#xff0c;加快查询的效率 相较于数组而言。我们知道,数组要求每个元素的大小都相同,如果我们要存储不同长度的字符串…