C#,图像二值化(06)——全局阈值的大津OTSU算法及其源代码

news/2024/5/19 16:50:40/文章来源:https://blog.csdn.net/beijinghorn/article/details/128429571

1、大津OTSU算法

最大类间方差法是1979年由日本学者大津(Nobuyuki Otsu)提出的,是一种自适应阈值确定的方法,又叫大津法,简称OTSU,是一种基于全局的二值化算法,它是根据图像的灰度特性,将图像分为前景和背景两个部分。当取最佳阈值时,两部分之间的差别应该是最大的,在OTSU算法中所采用的衡量差别的标准就是较为常见的最大类间方差。前景和背景之间的类间方差如果越大,就说明构成图像的两个部分之间的差别越大,当部分目标被错分为背景或部分背景被错分为目标,都会导致两部分差别变小,当所取阈值的分割使类间方差最大时就意味着错分概率最小。

2、Image Threshold

If the intensity of a pixel in the input image is greater than a threshold, the corresponding output pixel is marked as white (foreground), and if the input pixel intensity intensity is less than or equal to the threshold, the output pixel location is marked black (background).

Image thresholding is used in many applications as a pre-processing step. For example, you may use it in medical image processing to reveal tumor in a mammogram or localize a natural disaster in satellite images.

A problem with simple thresholding is that you have to manually specify the threshold value. We can manually check how good a threshold is by trying different values but it is tedious and it may break down in the real world.

So, we need a way to automatically determine the threshold. The Otsu’s technique named after its creator Nobuyuki Otsu is a good example of auto thresholding.

Before we jump into the details of the technique let’s understand how image thresholding relates to image segmentation.
 

3、Otsu thresholding


To improve on the segmentation, we next investigated a smarter thresholding approach: Otsu’s method. Otsu thresholding assumes that there are two classes of pixels in the image which we wish to separate. Additionally, Otsu’s method assumes that the two classes are separated by a roughly bimodal intensity histogram. The algorithm will then find the optimal threshold that separates the two classes via an exhaustive search for the threshold that minimizes the variance between the two classes. Our golf course images seemed to fit the assumptions of the algorithm: the two classes of pixels are “trees” and “the rest” and the intuition for our bimodal intensity histogram is “trees are dark”, “the rest is light”.

Using Otsu’s method for thresholding worked much better than the simple thresholding: large parts of the playable rough are now included in the segmented mask. There are some small false-positives such as the masked pixels in the tree crowns on the right upper side of the image. However, those small areas of noise were easily fixed via morphological operations such as opening, erosion and dilation.

One area where we noted that Otsu’s method broke down is in an image that contains shadows such as the example below. Otsu’s method operates on grayscale images so it can’t distinguish the deep dark green color of the tree canopy from the dark shadows of a tree. This is very visible in the upper center of the picture where shadows on the right end of the horizontal tree line are being included. However, for our golf course image segmentation, these shadows should be excluded.
 

4、大津OTSU算法的源代码(两个版本)

using System;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Drawing.Imaging;namespace Legalsoft.Truffer.ImageTools
{public static partial class BinarizationHelper{#region 灰度图像二值化 全局算法 大津OTSU 算法(两种代码)/// <summary>/// 图像二值化的大津算法/// Otsu's Thresholding/// https://blog.csdn.net/weixin_35811044/article/details/85255924/// </summary>/// <param name="data">灰度化的图片数据</param>/// <returns></returns>public static int Otsu_Threshold(byte[,] data){int height = data.GetLength(0);int width = data.GetLength(1);int[] histv = Gray_Histogram(data);double[] histogram = Histogram_Normalize(histv);int pixelNumb = height * width;double[] variances = new double[256];for (int T = 0; T < histogram.Length; T++){double n1 = 0, n2 = 0;double total1 = 0, total2 = 0;double aver1 = 0, aver2 = 0;double w1 = 0, w2 = 0;double ft1 = 0, ft2 = 0;for (int i = 0; i < T; i++){n1 += histogram[i];total1 += histogram[i] * i;}for (int j = T; j < variances.Length; j++){n2 += histogram[j];total2 += histogram[j] * j;}w1 = n1 / pixelNumb;w2 = n2 / pixelNumb;aver1 = (n1 == 0) ? 0 : (total1 / n1);aver2 = (n2 == 0) ? 0 : (total2 / n2);for (int i = 0; i < T; i++){ft1 += (Math.Pow((i - aver1), 2) * histogram[i]);}for (int j = T; j < 256; j++){ft2 += (Math.Pow((j - aver2), 2) * histogram[j]);}ft1 = (n1 == 0) ? 0 : (ft1 / n1);ft2 = (n2 == 0) ? 0 : (ft2 / n2);variances[T] = w1 * ft1 + w2 * ft2;}double min = variances[0];int threshold = 0;for (int i = 1; i < variances.Length; i++){if (variances[i] < min){min = variances[i];threshold = i;}}return threshold;}/// <summary>/// 大津算法之二/// </summary>/// <param name="histogram"></param>/// <returns></returns>public static int Ostu_Threshold_Second(int[] histogram){int left = Histogram_Left(histogram);int right = Histogram_Right(histogram);int amount = Histogram_Sum(histogram);double PixelIntegral = Histogram_Sum(histogram, 1);int Threshold = 0;double PixelBack = 0.0;double PixelIntegralBack = 0.0;double SigmaB = -1.0;for (int i = left; i <= right; i++){PixelBack = PixelBack + histogram[i];double PixelFore = amount - PixelBack;double OmegaBack = (double)PixelBack / (double)amount;double OmegaFore = (double)PixelFore / (double)amount;PixelIntegralBack += histogram[i] * (double)i;double PixelIntegralFore = PixelIntegral - PixelIntegralBack;double MicroBack = (double)PixelIntegralBack / PixelBack;double MicroFore = (double)PixelIntegralFore / PixelFore;double Sigma = OmegaBack * OmegaFore * (MicroBack - MicroFore) * (MicroBack - MicroFore);if (Sigma > SigmaB){SigmaB = Sigma;Threshold = i;}}return Threshold;}/// <summary>/// 图像二值化的大津算法/// </summary>/// <param name="data">灰度化的图片数据</param>public static void Otsu_Algorithm(byte[,] data){int threshold = Otsu_Threshold(data);Threshold_Algorithm(data, threshold);}#endregion}
}

5、大津OTSU算法的计算效果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_240785.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

rocketmq 实战问题汇总

rocketmq 实战过程会遇到这样或者那样的问题&#xff0c;今天我们专门抽出一篇文章来分析一下汇总一下&#xff0c;避免以后踩同样的坑&#xff1a; 1、找不到JDK的问题&#xff1a; 综合分析&#xff0c;是因为JDK安装的目录有空格导致的&#xff1a;Program Files 两个单词之…

YOLO-V5 系列算法和代码解析(三)—— 训练数据加载

文章目录调试准备Debug 设置代码修改调试数据代码运行逻辑类初始化启动迭代器数据增强调试准备 为了便于阅读代码和打印中间变量&#xff0c;需进行调试模式下运行代码。配置平台&#xff1a;Ubuntu&#xff0c;VSCode。在上一篇博文中&#xff0c;我们简单探讨过调试的设置。在…

JavaScript手写响应式原理(详解)

响应式原理 首先我们有一个对象 const obj {name: zlk,age: 18}这个对象可能在别处被用到 比如是这样的 function foo() {const newValue obj.nameconsole.log(hello world);console.log(obj.name);}我们来改变obj对象中的name的值 obj.name zlk这时候foo()应该被重新执…

一文读懂bert结构。

最近承接了项目要复现tiny_Bert。所以在这里用文章记录自己学到的。这篇文章是前置&#xff0c;主要介绍bert原理。 下一篇文章介绍tinybert的原理和训练 模型介绍&#xff1a; BERT概述&#xff1a; 如果要介绍tinyBERT&#xff0c;首先我们需要了解BERT模型。&#xff08;了…

原神私服搭建教程 (最新版)

搭建教程 1.准备阶段 1.请先确保电脑内有这些安装环境&#xff0c;否则私服无法运行&#xff01;&#xff01;&#xff01; MongoDB Python3.8 java17 mitmproxy 没有请在群文件下载安装环境&#xff0c;安装即可。特别强调&#xff1a;java17直接放在C:\Program Files目录下即…

【Java编程进阶】方法初识

推荐学习专栏&#xff1a;Java 编程进阶之路【从入门到精通】 文章目录1. Java 方法初识2. 方法的创建与使用3. 方法的分类3.1 无参无返回值3.2 无参带返回值3.3 有参无返回值3.4 有参带返回值4. 递归方法5. 总结1. Java 方法初识 方法是组合在一起来执行操作语句的集合&#…

一体式无线阀控超声水表在西北某市大用户用水计量收费管理项目应用案例

多年来&#xff0c;西北某市的工业园区供水公司对工业企业用户的用水收费一直采取业务员手动抄表、上门收费的方式。不仅效率低、浪费人力资源&#xff0c;而且供水公司很难掌握地区用水情况&#xff0c;不便于统一调度和管理。 为此&#xff0c;该工业园区安装了平升电子一体…

2023年无线运动耳机排行榜最新公布、公认最好的运动耳机推荐

随着人们日益对健康的重视&#xff0c;”全民健身“正在全国&#xff0c;乃至全世界蔓延开来&#xff0c;其中跑步锻炼凭借着门槛低&#xff0c;益处多成为了大部分人的健身的首选。而随着跑步大军的壮大&#xff0c;国内蓝牙耳机市场也是一片火热。其中蓝牙无线运动耳机凭借着…

拆串后结构化,其中按行对齐

【问题】 I have a bit weired scenario where i need to fetch data i have following three products product1 product2 product3and each product has different ids(e.g. p1345,p3453,p2345) and then each froduct have different options which are having different…

go 库 Cobra 现代化的命令行框架

go 库 Cobra 现代化的命令行框架 文章目录go 库 Cobra 现代化的命令行框架1. 简介2. 主要功能3. 应用举例4. Cobra 安装5. 使用 Cobra 库创建命令5.1 创建 rootCmd5.2 创建 main.go5.3 添加命令5.4 编译并运行6. 特性6.1 使用标志6.2 非选项参数验证6.3 PreRun and PostRun Hoo…

申请大学用的是IB预估分?

IB课程体系以其独特的优越性成为越来越多国际高中生的选择。如今全球共有3300多所高校接受IB成绩申请&#xff0c;其中包括美国常春藤盟校、英国G5在内的多所名校。 但是&#xff0c;大家知道吗&#xff0c;国内学习IB课程的学生是需要用预估分来申请大学的。今天&#xff0c;小…

4.7W防削顶单声道D类音频功率放大器HT6872介绍

HT6872简介 HT6872是一款低EMI&#xff0c;防削顶失真&#xff0c;单声道免滤波D类音频功率放大器。在6.5V电源&#xff0c;10%THDN&#xff0c;4Ω负载条件下&#xff0c;输出4.71W功率&#xff0c;在各类音频终端应用中维持高效率并提供AB类放大器的性能。 HT6872的最大特点是…

【PAT甲级 - C++题解】1032 Sharing

✍个人博客&#xff1a;https://blog.csdn.net/Newin2020?spm1011.2415.3001.5343 &#x1f4da;专栏地址&#xff1a;PAT题解集合 &#x1f4dd;原题地址&#xff1a;题目详情 - 1032 Sharing (pintia.cn) &#x1f511;中文翻译&#xff1a;共享 &#x1f4e3;专栏定位&…

梯度下降算法、随机梯度下降算法、动量随机梯度下降算法、AdaGrad算法、RMSProp算法、Adam算法详细介绍及其原理详解

文章目录前言一、回归拟合问题二、损失函数三、梯度下降算法四、随机梯度下降算法五、动量随机梯度下降算法六、AdaGrad算法七、RMSProp算法八、Adam算法总结前言 本篇博文详细介绍了关于梯度下降算法的所有相关知识&#xff0c;具体包括&#xff1a;回归拟合问题、损失函数、梯…

【OpenCV-Python】教程:9-1 级联分类器训练

OpenCV Python 级联分类器训练 【介绍】 使用增强的弱分类器级联包括两个主要阶段: 训练和检测阶段。使用基于HAAR或LBP模型的检测,在object detection tutorial中进行了描述。本文档概述了训练您自己的增强弱分类器级联所需的功能。当前的手册将走过所有不同的阶段: 收集训练…

MySQL5.7 多主一从(多源复制)同步配置

主从复制有如下一些优势&#xff1a; 分担负载&#xff1a;对业务进行读写分离&#xff0c;减轻主库I/O负载&#xff0c;将部分压力分担到从库上&#xff0c;缩短客户查询响应时间。 增加健壮性&#xff1a;在主库出现问题时&#xff0c;可通过多种方案将从库设置为主库&#…

4.防止数据权限越权

涉及的修改 这次提交内容很简单&#xff0c;就是在这些类的操作上&#xff0c;添加了 checkXxxDataScope()方法校验&#xff0c;下面来看下这个方法的实现 /*** 校验用户是否有数据权限* * param userId 用户id*/ Override public void checkUserDataScope(Long userId) {if (…

【JavaScript】——javascript牛客专项练习错题合集

答&#xff1a; var b function(){alert(this.a); }, obj {a:1,b:b // 把函数独立出来 }; var fun obj.b;// 存储的是内存中的地址 fun(); 虽然fun是obj.b的一个引用&#xff0c;但是实际上&#xff0c;它引用的是b函数本身&#xff0c;因此此时的fun()其实 是一个不带任何…

借助“云上”SPSS降低未来数据分析的不确定性

生活工作中我们常常会遇到这样或那样的困难&#xff0c;比如不得不临时居家办工&#xff0c;却发现家中电脑没有安装工作中的必备软件&#xff0c;比如毕业论文写到一半&#xff0c;同学告诉你&#xff0c;新版的软件升级加强了某个模型&#xff0c;能让你更好的完成论文。软件…

【Spring【IOC】】——17、@Resource注解和@Inject注解?

&#x1f4eb;作者简介&#xff1a;zhz小白 公众号&#xff1a;小白的Java进阶之路 专业技能&#xff1a; 1、Java基础&#xff0c;并精通多线程的开发&#xff0c;熟悉JVM原理 2、熟悉Java基础&#xff0c;并精通多线程的开发&#xff0c;熟悉JVM原理&#xff0c;具备⼀定的线…