当前位置: 首页 > news >正文

【图像处理】:Otsu算法最大类间方差法(大津算法:附源码)

这里写自定义目录标题

  • 数学原理
  • 算法评价
  • 参考链接

数学原理

以灰度图像为例,对于图像M×N大小的矩阵,即图像中的像素,每一个值即为像素值,其中灰度图像像素值在(0~255)之间。
主要实现前景(即目标)和背景的分割:
主要公式:
前景的像素点数占整幅图像的比例记为ω0,前景平均灰度记为μ0
​背景像素点数占整幅图像的比例记为ω1,其平均灰度记为μ1
​图像的总平均灰度记为μ,类间方差记为maximum。
假设图像的背景较暗,并且图像的大小为M×N,图像中像素的灰度值小于阈值optimal threshold的像素个数记作N0
,像素灰度大于等于阈值optimalthreshold 的像素个数记作N1,
则有:
            ω0 = N0 / ( M × N )             (1)   
            ω1 = N1 / ( M × N )             (2)       
        N0 + N1 = M × N             (3)   
            1 = ω 0 + ω 1             (4)      
            μ = ω0 × μ0 + ω1 × μ1         (5)   
       maximum = ω0 × ( μ0 − μ ) 2 + ω1 × ( μ1 − μ ) 2 (6)  
将式(5)代入式(6),得到等价公式(7):
      maximum = ω0 × ω1 × (μ0 − μ1 ) 2 (7)    
采用遍历的方法得到使类间方差maximum最大的阈值optimal threshold
实现过程:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# author:longc
# datetime:2023/11/16 10:30
# software: PyCharm
# function: 图像处理逻辑import cv2
import numpy as np
import matplotlib.pyplot as plt
from PIL import Image# 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))  # 计算灰度的直方图,计数统计区间为0-257print("bins", bins)print("his", his)# 绘制直方图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  # 像素被分类为目标的概率# if t == 100:#     print("1>>>", intensity_arr[:t])#     print("2>>>", his[:t])#     print("3>>>", np.sum(intensity_arr[:t] * his[:t]))#     print("4>>>", float(pcb))#     print("5>>>", np.sum(intensity_arr[:t] * his[:t]) / float(pcb))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  # 计算目标和背景类间方差# 采用遍历的方法得到使类间方差value最大的阈值final_value和二值化对应最大的final_threshif value > final_value:final_thresh = t  # 进行二值化的操作值final_value = valueprint("final_thresh>>>", final_thresh)print("final_value>>>", final_value)# 二值化操作处理# final_img = gray.copy()# print(final_thresh)# final_img[gray > final_thresh] = 255# final_img[gray < final_thresh] = 0# cv2.imwrite("final_img.jpg", final_img)plt.imshow(gray)plt.show()# 二值化图像(多种方法对比)ret, binary_image = cv2.threshold(gray, final_thresh-15, 255, cv2.THRESH_BINARY)plt.imshow(binary_image, cmap='gray')plt.show()# ret, binary_image1 = cv2.threshold(gray, final_thresh, 255, cv2.THRESH_TRUNC)# plt.imshow(binary_image1)# plt.show()## ret, binary_image2 = cv2.threshold(gray, final_thresh, 255, cv2.THRESH_TOZERO)# plt.imshow(binary_image2)# plt.show()## ret, binary_image3 = cv2.threshold(gray, final_thresh, 255, cv2.THRESH_TOZERO_INV)# plt.imshow(binary_image3)# plt.show()imggray = cv2.imread("IMG_0004_3.jpg", 0)
plt.title("imggray")
plt.imshow(imggray, cmap='gray')
plt.show()# 进行OSTU运算
otsu(imggray)

算法评价

优点:算法简单,当目标与背景的面积相差不大时,能够有效地对图像进行分割。

缺点:类间方差法对噪声以及目标大小十分敏感,它仅对类间方差为单峰的图像产生较好的分割效果。当目标与背景的大小比例悬殊时(例如受光照不均、反光或背景复杂等因素影响),类间方差准则函数可能呈现双峰或多峰,或者目标与背景的灰度有较大的重叠时,效果不不是很理想。

原因:该方法忽略了图像的空间信息,同时将图像的灰度分布作为分割图像的依据,对噪声也相当敏感

原文链接:

参考链接

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

相关文章:

【图像处理】:Otsu算法最大类间方差法(大津算法:附源码)

这里写自定义目录标题 数学原理算法评价参考链接 数学原理 以灰度图像为例&#xff0c;对于图像MN大小的矩阵&#xff0c;即图像中的像素&#xff0c;每一个值即为像素值&#xff0c;其中灰度图像像素值在(0~255)之间。 主要实现前景(即目标)和背景的分割&#xff1a; 主要公式…...

【uni-app】设置背景颜色相关

1. 全局页面背景色设置&#xff1a; 在App.vue的style样式表中设置 <style> page {background-color: #F0AD4E; } </style> 2. 顶部导航栏背景色设置&#xff1a; 在pages.json页面路由中&#xff0c;globalStyle设置 "globalStyle": {"navi…...

工厂模式-C++实现

工厂模式是一个创建型设计模式&#xff0c;即“对象创建模式”&#xff0c;通过这种模式可以绕开new&#xff0c;来避免对象创建过程中&#xff0c;也就是new的方法造成的紧耦合&#xff0c;从而支持对象创建的稳定。 工厂模式中引入了一个工厂类&#xff0c;该工厂负责根据客…...

安装应用与免安装应用差异对比

差异 安装的程序和免安装的应用程序之间有以下几个方面的差别&#xff1a; 安装过程&#xff1a;安装的程序需要通过一个安装程序或安装脚本进行安装。这个过程通常会将应用程序的文件和依赖项复制到指定的目录&#xff0c;并进行一些配置和注册操作。免安装的应用程序则不需要…...

FiscoBcos使用Go调用合约

环境&#xff1a; fisco2.8.0 go 1.17 go-sdk 1.0.0 solidity 0.4.25 前言 请提前启动好四个fisco节点。 请准备好一个属于此fisco节点的账户私钥【待会调用合约和部署合约会用到】 此文章将讲解 官方文档使用gosdk部署helloworld合约并调用其方法 合约开发样例 官网提示 G…...

自然语言处理(NLP)-spacy简介以及安装指南(语言库zh_core_web_sm)

spacy 简介 spacy 是 Python 自然语言处理软件包&#xff0c;可以对自然语言文本做词性分析、命名实体识别、依赖关系刻画&#xff0c;以及词嵌入向量的计算和可视化等。 1.安装 spacy 使用 “pip install spacy" 报错&#xff0c; 或者安装完 spacy&#xff0c;无法正…...

CTF-PWN-tips

文章目录 overflowscanfgetreadstrcpystrcat Find string in gdbgdbgdb peda Binary ServiceFind specific function offset in libc手工自动 Find /bin/sh or sh in library手动自动 Leak stack addressFork problem in gdbSecret of a mysterious section - .tlsPredictable …...

《Effective C++》条款21

必须返回对象时&#xff0c;别妄想返回其reference 如果你的运算符重载函数写成了返回reference的形式&#xff1a; class A { public:A(int a,int b):x(a),y(b){}friend const A& operator*(const A& a, const A& b); private:int x;int y; }; const A& opera…...

决策树,sql考题,30个经典sql题目

大数据&#xff1a; 2022找工作是学历、能力和运气的超强结合体&#xff0c;遇到寒冬&#xff0c;大厂不招人&#xff0c;可能很多算法学生都得去找开发&#xff0c;测开 测开的话&#xff0c;你就得学数据库&#xff0c;sql&#xff0c;oracle&#xff0c;尤其sql要学&#x…...

【ES6.0】- 扩展运算符(...)

【ES6.0】- 扩展运算符... 文章目录 【ES6.0】- 扩展运算符...一、概述二、拷贝数组对象三、合并操作四、参数传递五、数组去重六、字符串转字符数组七、NodeList转数组八、解构变量九、打印日志十、总结 一、概述 **扩展运算符(...)**允许一个表达式在期望多个参数&#xff0…...

关于Java中的深拷贝与浅拷贝

Java中的深拷贝和浅拷贝是针对对象和数组等引用数据类型的复制操作。 浅拷贝&#xff08;Shallow Copy&#xff09;&#xff1a; 对于基本数据类型&#xff0c;浅拷贝直接复制其值。对于引用数据类型&#xff0c;浅拷贝只复制对原对象的引用&#xff0c;而不是复制对象本身。因…...

13.真刀实枪做项目---博客系统(页面设计)

文章目录 1.预期效果1.1博客列表页效果1.2博客详情页效果1.3博客登陆页效果1.4博客编辑页效果 2.实现博客列表页2.1实现导航栏2.2实现版心2.3实现个人信息2.4实现博客列表2.5博客列表页完整代码 3.实现博客正文页3.1引入导航栏3.2引入版心3.3引入个人信息3.4实现博客正文3.5博客…...

VScode 配置用户片段

文件->首选项->配置用户片段->新建全局用户片段 后续就可以通过vv3来直接生成下面的代码 {// Place your 全局 snippets here. Each snippet is defined under a snippet name and has a scope, prefix, body and // description. Add comma separated ids of the l…...

Fedora 项目近日发布了 Fedora Linux 39

导读几经推迟之后&#xff0c;Fedora 项目近日发布了 Fedora Linux 39&#xff0c;这是红帽公司赞助的面向大众的 GNU/Linux 发行版的最新稳定版本&#xff0c;采用了最新的技术和开源应用程序。 Fedora Linux 39 由 Linux 内核 6.5 支持&#xff0c;并提供了一些最新的桌面环境…...

Uniapp连接iBeacon设备——实现无线定位与互动体验(理论篇)

目录 前言&#xff1a; 一、什么是iBeacon技术 二、Uniapp连接iBeacon设备的准备工作 硬件设备&#xff1a; 三、Uniapp连接iBeacon设备的实现步骤 创建Uniapp项目&#xff1a; 四、Uniapp连接iBeacon设备的应用场景 室内导航&#xff1a; 五、Uniapp连接iBeacon设备的未来…...

GCD:异步同步?串行并发?一文轻松拿捏!

GCD 文章目录 GCD进程线程进程与线程的关系进程与线程的区别 任务&#xff08;执行的代码&#xff09;队列线程与队列的关系 队列任务**同步执行任务&#xff08;sync&#xff09;**辅助方法**异步执行任务&#xff08;async)**总结栅栏任务迭代任务 队列详细属性QoSAttributes…...

学习c#的第十七天

目录 C# 异常处理 异常的原因 System.Exception 类 如何处理异常 常见的异常类 throw 语句 throw 表达式 try 语句 try-catch 语句 try-finally 语句 try-catch-finally 语句 when 异常筛选器 异步和迭代器方法中的异常 C# 异常处理 C # 中的异常提供了结构化、统…...

龙芯 操作系统选择和安装

龙芯3a5000及之后的cpu底层架构已经从mips64el改为了loongarch64 所以这里分了2种来说明&#xff0c;分别对应3a4000之前的和3a5000之后的 龙芯的系统安装难点在于操作系统的选取和引导 一、烧录工具 制作安装盘使用常规的烧录工具是不行滴&#xff0c;会提示没有\boot\initrd…...

【开源】基于JAVA的智能停车场管理系统

项目编号&#xff1a; S 005 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S005&#xff0c;文末获取源码。} 项目编号&#xff1a;S005&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、研究内容A. 车主端功能B. 停车工作人员功能C. 系…...

使用IDEA 将Eclipse java工程转为maven格式

使用IDEA 将Eclipse java工程转为maven格式 ①使用idea打开项目&#xff0c;在项目根目录下右键选择 Add Framework Support 选择 maven &#xff0c;引入maven ②找到项目中的.classpath文件或者lib目录 根据.classpath文件或者lib目录中列举的jar包名&#xff0c;将其依次手…...

突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合

强化学习&#xff08;Reinforcement Learning, RL&#xff09;是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程&#xff0c;然后使用强化学习的Actor-Critic机制&#xff08;中文译作“知行互动”机制&#xff09;&#xff0c;逐步迭代求解…...

Java多线程实现之Callable接口深度解析

Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...

新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案

随着新能源汽车的快速普及&#xff0c;充电桩作为核心配套设施&#xff0c;其安全性与可靠性备受关注。然而&#xff0c;在高温、高负荷运行环境下&#xff0c;充电桩的散热问题与消防安全隐患日益凸显&#xff0c;成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...

leetcodeSQL解题:3564. 季节性销售分析

leetcodeSQL解题&#xff1a;3564. 季节性销售分析 题目&#xff1a; 表&#xff1a;sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...

零基础设计模式——行为型模式 - 责任链模式

第四部分&#xff1a;行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习&#xff01;行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想&#xff1a;使多个对象都有机会处…...

使用 SymPy 进行向量和矩阵的高级操作

在科学计算和工程领域&#xff0c;向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能&#xff0c;能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作&#xff0c;并通过具体…...

C# 求圆面积的程序(Program to find area of a circle)

给定半径r&#xff0c;求圆的面积。圆的面积应精确到小数点后5位。 例子&#xff1a; 输入&#xff1a;r 5 输出&#xff1a;78.53982 解释&#xff1a;由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982&#xff0c;因为我们只保留小数点后 5 位数字。 输…...

【C++特殊工具与技术】优化内存分配(一):C++中的内存分配

目录 一、C 内存的基本概念​ 1.1 内存的物理与逻辑结构​ 1.2 C 程序的内存区域划分​ 二、栈内存分配​ 2.1 栈内存的特点​ 2.2 栈内存分配示例​ 三、堆内存分配​ 3.1 new和delete操作符​ 4.2 内存泄漏与悬空指针问题​ 4.3 new和delete的重载​ 四、智能指针…...

【Nginx】使用 Nginx+Lua 实现基于 IP 的访问频率限制

使用 NginxLua 实现基于 IP 的访问频率限制 在高并发场景下&#xff0c;限制某个 IP 的访问频率是非常重要的&#xff0c;可以有效防止恶意攻击或错误配置导致的服务宕机。以下是一个详细的实现方案&#xff0c;使用 Nginx 和 Lua 脚本结合 Redis 来实现基于 IP 的访问频率限制…...

Scrapy-Redis分布式爬虫架构的可扩展性与容错性增强:基于微服务与容器化的解决方案

在大数据时代&#xff0c;海量数据的采集与处理成为企业和研究机构获取信息的关键环节。Scrapy-Redis作为一种经典的分布式爬虫架构&#xff0c;在处理大规模数据抓取任务时展现出强大的能力。然而&#xff0c;随着业务规模的不断扩大和数据抓取需求的日益复杂&#xff0c;传统…...