主要内容

1、最大类间方差法原理概述

2、GEE频率分布统计,直方图绘制

3、算法具体实现,以GEE JavaScript版本为例

4、目标像元提取,以遥感影像提取水体为示例

算法原理

概念

最大类间方差法(又名otsu、大津法)是由日本学者OTSU于1979年提出的一种对图像进行二值化的高效算法。算法假定该图像根据频率分布直方图把包含两类像元(前景像元和背景像元),计算能将两类分开的最佳阈值,使得它们的类内方差最小;由于两两平方距离恒定,所以即它们的类间方差最大。

优点:计算简单快速,不受图像亮度和对比度的影响。

缺点:对图像噪声敏感;如果图像中的前景像元和背景像元的面积相差很大,直方图没有明显的双峰,或者两个峰的大小相差很大,分割效果不佳。实际应用中,常结合其他方法。

原理

大津法借助穷举法搜索能使类内方差最小的阈值,计算两个类的方差的加权和,权值为两类各自的概率,前人证明了最小化类内方差和最大化类间方差是相同的。

图像的总平均灰度为:M=P1(t) * M0 + P2(t) * M1

前景与背景像元类间方差:S=P1(t) * (M1 - M) * (M1 - M) + P2(t) * (M2 - M) * (M2 - M)

t为前景与背景的分割阈值,前景像元占图像比例为P1(t),平均灰度为M1;背景像元占图像比例为P2(t),平均灰度为M1。

算法实现

数据准备

1、原始影像:定义示例矢量区域geometry(山东省潍坊市峡山水库周边,便于提取水体),时间范围,云量低于20%,筛选出符合条件的Landsat8影像集dataset,中值合成得到示例影像l8_image

var geometry = ee.Geometry.Polygon([[[119.3140376290338, 36.559328749628065],[119.3140376290338, 36.263933411986294],[119.62234146204162, 36.263933411986294],[119.62234146204162, 36.559328749628065]]], null, false);var dataset = ee.ImageCollection('LANDSAT/LC08/C02/T1_L2').filterDate('2021-10-01', '2021-12-01').filterBounds(geometry).filter(ee.Filter.lt('CLOUD_COVER', 20));function applyScaleFactors(image) {var opticalBands = image.select('SR_B.').multiply(0.0000275).add(-0.2);var thermalBands = image.select('ST_B.*').multiply(0.00341802).add(149.0);return image.addBands(opticalBands, null, true).addBands(thermalBands, null, true);
}//获取图像 中值合成
var l8_image = dataset.map(applyScaleFactors).median().clip(geometry);//可视化
var visualization = {bands: ['SR_B4', 'SR_B3', 'SR_B2'],min: 0.0,max: 0.3,
};
Map.centerObject(geometry);
Map.addLayer(l8_image, visualization, 'True Color (432)');

原始影像真彩色显示:

2、提取NDWI:后续用于计算阈值,识别水体和非水体

NDWI(Normalized Difference Water Index,归一化水指数),用遥感影像的特定波段进行归一化差值处理,以凸显影像中的水体信息。其表达式为:

NDWI =(p(Green)-p(NIR))/(p(Green)+p(NIR))

是基于绿波段与近红外波段的归一化比值指数,一般用来提取影像中的水体信息,效果较好。

var ndwi = l8_image.normalizedDifference(['SR_B3', 'SR_B5']).float().rename('l8_NDWI');
print("ndwi", ndwi)
var visParams1 = {min: 0, max: 1, palette: ['FFFFFF', 'CE7E45', 'DF923D', 'F1B555', 'FCD163', '99B718','74A901', '66A000', '529400', '3E8601', '207401', '056201','004C00', '023B01', '012E01', '011D01', '011301']
};
Map.addLayer(ndwi, visParams1, "l8_NDWI");

NDWI灰度显示:

数据查看

NDWI频数分布直方图计算并显示,可见有明显双峰,且两类没有重叠,非常便于运用大津法计算分割阈值,其中参数: 最大组数maxBuckets 最小组距minBucketWidth设置较为关键,具体其他参数参阅官方文档

GEE右上角“Download”可以将csv数据下载到本地进行分析

//频数分布直方图
var chart = ui.Chart.image.histogram({image: ndwi,region: geometry,scale: 30,maxBuckets: 1000,//最大组数minBucketWidth: 0.01, //最小组距// maxRaw, maxPixels: 1e13
})
print(chart)

计算阈值

首先计算频数分布数据,同前文注意参数设置,之后利用穷举法计算类内方差,得到类间方差结果表,按照方差排序,得到方差最大对应的值即为最佳阈值,

阈值=0.06508403641771252,可见符合频数分布直方图示意

详细过程见代码注释

//计算OTSU阈值
var yuzhi = otsu(ndwi)
print("阈值", yuzhi)//OTSU
function otsu1(histogram) {// 各组频数var counts = ee.Array(ee.Dictionary(histogram).get('histogram'))// 各组的值var means = ee.Array(ee.Dictionary(histogram).get('bucketMeans'))// 组数var size = means.length().get([0])// 总像元数量var total = counts.reduce(ee.Reducer.sum(), [0]).get([0])// 所有组的值之和var sum = means.multiply(counts).reduce(ee.Reducer.sum(), [0]).get([0])// 整幅影像的均值var mean = sum.divide(total)// 与组数相同长度的索引var indices = ee.List.sequence(1, size)// 穷举法计算类内方差var bss = indices.map(function (i) {// 当 i = 1, aCounts = [counts[0]], 当 i = 2, aCounts = [counts[0], counts[1]] //从i分割为两类A、B 计算A方差var aCounts = counts.slice(0, 0, i)var aCount = aCounts.reduce(ee.Reducer.sum(), [0]).get([0])var aMeans = means.slice(0, 0, i)// 类别A均值var aMean = aMeans.multiply(aCounts).reduce(ee.Reducer.sum(), [0]).get([0]).divide(aCount)var bCount = total.subtract(aCount)// 类别B均值var bMean = sum.subtract(aCount.multiply(aMean)).divide(bCount)//类间方差公式return aCount.multiply(aMean.subtract(mean).pow(2)).add(bCount.multiply(bMean.subtract(mean).pow(2)))})print('类间方差', ui.Chart.array.values(ee.Array(bss), 0, means))// 排序选出最适阈值return means.sort(bss).get([-1])
}
function otsu(image) {var histogram = image.reduceRegion({reducer: ee.Reducer.histogram(1000, 0.01),// 自行修改合适的最大组数,最小组距geometry: geometry,scale: 30,bestEffort: true,// tileScale:16});print("频数分布", histogram)return otsu1(histogram.get(histogram.keys().get(0)));
}

分割图像

借助前文得到的的阈值进行影像二值化分割,得到水体示意图

var result = ndwi.gt(yuzhi)
Map.addLayer(result.randomVisualizer(), "", "water");

结果图:

代码附录

链接:https://code.earthengine.google.com/4456dc4c799a8673d0f1aec1431250f4

var geometry = /* color: #d63000 *//* shown: false *//* displayProperties: [{"type": "rectangle"}] */ee.Geometry.Polygon([[[119.3140376290338, 36.559328749628065],[119.3140376290338, 36.263933411986294],[119.62234146204162, 36.263933411986294],[119.62234146204162, 36.559328749628065]]], null, false);var dataset = ee.ImageCollection('LANDSAT/LC08/C02/T1_L2').filterDate('2021-10-01', '2021-12-01').filterBounds(geometry).filter(ee.Filter.lt('CLOUD_COVER', 20));function applyScaleFactors(image) {var opticalBands = image.select('SR_B.').multiply(0.0000275).add(-0.2);var thermalBands = image.select('ST_B.*').multiply(0.00341802).add(149.0);return image.addBands(opticalBands, null, true).addBands(thermalBands, null, true);
}//获取图像 中值合成
var l8_image = dataset.map(applyScaleFactors).median().clip(geometry);//可视化
var visualization = {bands: ['SR_B4', 'SR_B3', 'SR_B2'],min: 0.0,max: 0.3,
};
Map.centerObject(geometry);
Map.addLayer(l8_image, visualization, 'True Color (432)');var ndwi = l8_image.normalizedDifference(['SR_B3', 'SR_B5']).float().rename('l8_NDWI');
print("ndwi", ndwi)
var visParams1 = {min: 0, max: 1
};
Map.addLayer(ndwi, visParams1, "l8_NDWI");//频数分布直方图
var chart = ui.Chart.image.histogram({image: ndwi,region: geometry,scale: 30,maxBuckets: 1000,//最大组数minBucketWidth: 0.01, //最小组距// maxRaw, maxPixels: 1e13
})
print(chart)//计算OTSU阈值 分割图像
var yuzhi = otsu(ndwi)
print("阈值", yuzhi)
var result = ndwi.gt(yuzhi)
Map.addLayer(result.randomVisualizer(), "", "water");
//
OTSU/function otsu1(histogram) {// 各组频数var counts = ee.Array(ee.Dictionary(histogram).get('histogram'))// 各组的值var means = ee.Array(ee.Dictionary(histogram).get('bucketMeans'))// 组数var size = means.length().get([0])// 总像元数量var total = counts.reduce(ee.Reducer.sum(), [0]).get([0])// 所有组的值之和var sum = means.multiply(counts).reduce(ee.Reducer.sum(), [0]).get([0])// 整幅影像的均值var mean = sum.divide(total)// 与组数相同长度的索引var indices = ee.List.sequence(1, size)// 穷举法计算类内方差var bss = indices.map(function (i) {// 当 i = 1, aCounts = [counts[0]], 当 i = 2, aCounts = [counts[0], counts[1]] //从i分割为两类A、B 计算A方差var aCounts = counts.slice(0, 0, i)var aCount = aCounts.reduce(ee.Reducer.sum(), [0]).get([0])var aMeans = means.slice(0, 0, i)// 类别A均值var aMean = aMeans.multiply(aCounts).reduce(ee.Reducer.sum(), [0]).get([0]).divide(aCount)var bCount = total.subtract(aCount)// 类别B均值var bMean = sum.subtract(aCount.multiply(aMean)).divide(bCount)//类间方差公式return aCount.multiply(aMean.subtract(mean).pow(2)).add(bCount.multiply(bMean.subtract(mean).pow(2)))})print('类间方差', ui.Chart.array.values(ee.Array(bss), 0, means))// 排序选出最适阈值return means.sort(bss).get([-1])
}
function otsu(image) {var histogram = image.reduceRegion({reducer: ee.Reducer.histogram(1000, 0.01),// .combine('mean', null, true)// .combine('variance', null, true),geometry: geometry,scale: 30,bestEffort: true,// tileScale:16});print("频数分布", histogram)return otsu1(histogram.get(histogram.keys().get(0)));
}

【GEE笔记】最大类间方差法(otsu、大津法)算法实现——计算阈值、图像二值化分割相关推荐

  1. otsu阈值分割算法原理_OTSU_图像二值化分割阈值的算法

    简介: 大津法(OTSU)是一种确定图像二值化分割阈值的算法,由日本学者大津于1979年提出.从大津法的原理上来讲,该方法又称作最大类间方差法,因为按照大津法求得的阈值进行图像二值化分割后,前景与背景 ...

  2. 图像二值化分割阈值的算法——OTSU

    该算法叫做大津算法,由日本学者大津于1979年提出. 该算法的核心在于 前景与背景图像的类间方差最大 MATLAB代码 clear all clcI = imread('1.jpg'); I = rg ...

  3. 图像二值化(Image Binarization):平均值法、双峰法、大津算法(OTSU)

    图像二值化(Image Binarization):平均值法.双峰法.大津算法(OTSU) 编程实现图像的二值化,分析不同的阈值对二值化图像的影响. 问题描述 传统的机器视觉通常包括两个步骤:预处理和 ...

  4. 【智能车】图像二值化算法--大津法OTSU

    图像二值化算法–大津法OTSU 大津算法是一种图像二值化算法,作用是确定将图像分成黑白两个部分的阈值. 大津法是针对灰度值进行阈值分割二值化,如果是彩色图像的话需要先转化成灰度图再进行计算. 方差越大 ...

  5. 图像二值化_三角阈值法

    前言 一.三角阈值法是什么? 二.算法原理 1.算法 总结 参考文献 前言 图像二值化有很多方法,比较经典的为OTSU,三角阈值法,本文主要想一探三角阈值法的算法原理. 一.三角阈值法是什么? 三角阈 ...

  6. 二值图像分析笔记(1)—— 图像二值化

    1 二值图像 像素矩阵只包含0和1: 0:黑色 1:白色 1.1 RGB彩色图像到二值图像的转换 彩色图像到灰度图像的转换 灰度图像到二值图像 1.2 常见的图像二值化方法 基于均值-统计学原理 迭代 ...

  7. 图像二值化之最大类间方差法(大津法,OTSU)

    参考文章1:图像二值化与otsu算法介绍 参考文章2:python opencv cv2.threshold() (将固定级别的阈值应用于每个数组元素)ThresholdTypes 最大类间方差法(大 ...

  8. CUDA精进之路(五):图像处理——OTSU二值算法(最大类间方差法、大津法)

    引言 最近在做医疗设备相关的项目,故在项目中大量用到了各类图像分割的算法,为了在图像中分割出特定目标,用到的算法可以有很多,比如阈值分割,多通道分割,边缘分割以及一些前沿的组合分割.而对大多数图像来说 ...

  9. 最大类间方差法(大津法OTSU)原理

    算法介绍 最大类间方差法是1979年由日本学者大津提出的,是一种自适应阈值确定的方法,又叫大津法,简称OTSU,是一种基于全局的二值化算法,它是根据图像的灰度特性,将图像分为前景和背景两个部分.当取最 ...

  10. 基于OTSU(大津法)的图像分块的阈值分割

    一.开发环境: Qt版本:Qt5.12.3VS版本:VS2017opencv版本:opencv-4.5.1-vc14_vc15 二.要求:实现基于图像分块+OTSU的图像分割 1.OTSU大津法实现 ...

最新文章

  1. 浅析网站内链优化如何营造良好的内链生态环境?
  2. mvc:annotation-driven/浅析
  3. IOS推送消息怎么实现icon图标的数字累加
  4. JavaScript 中的 this
  5. 易语言html到画板,易语言画板使用方法图解
  6. 第二次作业 项目质量管理重点知识梳理
  7. 在 Azure 虚拟机上快速搭建 MongoDB 集群
  8. N9程序开发-生成项目
  9. 计算机学业水平考试反思总结8百,考试反思与总结
  10. my97DatePicker选择年、季度、月、周、日(转)
  11. windows系统清除电脑地址栏文件(夹)路径
  12. 【基础理论】介绍一个概率分布:柯西分布
  13. SqlServer无备份下误删数据恢复
  14. iphone app 的图标上被自动添加一层半透明遮罩(玻璃效果),小米3这样的高分屏icon不生效,怎么破?
  15. Windows 10系统时间显示不正确
  16. Unity的IOS PlayerSettings的设置说明
  17. 跑跑卡丁车蛋白石盒喜当托儿纪念,2022/06/12,22:59:24
  18. 那些清华北大随便挑的高考状元们,后来都过上了怎样的生活?
  19. 关系数据库、关系代数和关系运算
  20. 为什么子进程要继承处理器亲缘性?

热门文章

  1. 雷电html查看程序编辑程序,NC程序编辑器(nEditor)
  2. 推荐6个实用的Vue模板
  3. QNX系统和凝思系统分别系统时间设置RTC时间方法
  4. 葵花卫星数据介绍与下载教程
  5. 5w1h,人机料法环
  6. qqxml图片代码_QQxml卡片代码合集超大图
  7. 【gp数据库】你可能不知道却超级实用的函数
  8. 【gp数据库】统计常用窗口函数详解
  9. 《高分辨率被动微波遥感——综合孔径微波辐射成像》附录仿真代码
  10. matlab环境下图像分形维数的计算,MATLAB环境下图像分形维数的计算_杨书申