1. 定义

  分水岭算法(watershed algorithm)可以将图像中的边缘转化为“山脉”,将均匀区域转化为“山谷”,在这方面有助于分割目标。
  分水岭算法:是一种基于拓扑理论的数学形态学的分割方法。把图像看作是测地学上的拓扑地貌,图像中的每一个点像素值的灰度值表示该点的海拔高度,每一个局部极小值及其影响的区域称为“集水盆”,集水盆的边界可以看成分水岭。在每一个局部极小值表面刺穿一个小孔,然后把整个模型慢慢浸入水中,随着浸入的加深,每一个局部极小值的影响域慢慢的向外扩展,在两个集水盆汇合处构建大坝,形成分水岭。

迭代标注过程:

  1. 排序过程:对每个像素的灰度级进行从低到高的排序
  2. 淹没过程:对每一个局部最小值在h阶高度的影响域采用先进先出结构判断及标注。

2.实现算法:watershed()函数

  这些标记的值可以使用findContours()函数和drawContours()函数由二进制的掩模检索出来

3.程序代码:

import numpy as np
import cv2
from osgeo import gdal, gdal_array
import shapefile
try:
import Image
import ImageDraw
except:
from PIL import Image, ImageDraw def tif_jpg(rasterfile):
in_ds = gdal.Open(rasterfile) # 打开样本文件
xsize = in_ds.RasterXSize # 获取行列数
ysize = in_ds.RasterYSize
bands = in_ds.RasterCount
block_data = in_ds.ReadAsArray(0, 0, xsize, ysize).astype(np.float32)
B = block_data[0, :, :] G = block_data[ 1,:, :]
R = block_data[2,:, :]
R1 = (R/np.max(R)*255).astype(np.int16)
G1 = (G / np.max(G) * 255).astype(np.int16)
B1 = (B / np.max(B) * 255).astype(np.int16)
data2 = cv2.merge([R1,G1,B1])
return data2 def watershed(path,out):
print("分水岭分割")
in_ds = gdal.Open(path) # 打开样本文件
xsize = in_ds.RasterXSize # 获取行列数
ysize = in_ds.RasterYSize
bands = in_ds.RasterCount
geotransform = in_ds.GetGeoTransform()
projection = in_ds.GetProjectionRef()
#tif转jpg 非255通道转换为255通道
img=tif_jpg(path).astype(np.uint8)
# 转换为灰度图片
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# canny边缘检测 函数返回一副二值图,其中包含检测出的边缘。
canny = cv2.Canny(gray_img, 80,120)
# 寻找图像轮廓 返回修改后的图像 图像的轮廓 以及它们的层次
# canny, contours, hierarchy = cv2.findContours(canny, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
contours, hierarchy = cv2.findContours(canny, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# 32位有符号整数类型,
marks = np.zeros(img.shape[:2], np.int32)
# findContours检测到的轮廓
imageContours = np.zeros(img.shape[:2], np.uint8)
# 轮廓颜色
compCount = 0
index = 0
# 绘制每一个轮廓
for index in range(len(contours)):
# 对marks进行标记,对不同区域的轮廓使用不同的亮度绘制,相当于设置注水点,有多少个轮廓,就有多少个轮廓
# 图像上不同线条的灰度值是不同的,底部略暗,越往上灰度越高
marks = cv2.drawContours(marks, contours, index, (index, index, index), 1, 8, hierarchy)
# 绘制轮廓,亮度一样
imageContours = cv2.drawContours(imageContours, contours, index, (255, 255, 255), 1, 8, hierarchy)
# 查看 使用线性变换转换输入数组元素成8位无符号整型。
markerShows = cv2.convertScaleAbs(marks)
# cv2.imshow('imageContours',imageContours)
# 使用分水岭算法
marks = cv2.watershed(img, marks)
driver = gdal.GetDriverByName('GTiff')
outfile_lake = out + "\\" + "watershed_cut.tif"
out_dataset = driver.Create(outfile_lake, xsize, ysize, 1, gdal.GDT_Float32)
out_band1 = out_dataset.GetRasterBand(1)
out_band1.WriteArray(marks)
out_dataset.SetGeoTransform(geotransform) # 写入仿射变换
out_dataset.SetProjection(projection)
return outfile_lake if __name__ == "__main__":
path = r"D:\data\实验数据\fenlei2.tif"
out = r"D:\data\实验结果\分割结果"
watershed(path, out)

python实现分水岭算法分割遥感图像的更多相关文章

  1. python实现分水岭算法

    目录: 问题:分水岭算法对图像分割很有作用,怎么把对象分割开来的?分水岭算法是比较完美的分割,跟前面的讲的轮廓不一样! (一)原理 (二)实现 (一)原理 opencv中的分水岭算法是基于距离变换的, ...

  2. OpenCV 学习笔记 04 深度估计与分割——GrabCut算法与分水岭算法

    1 使用普通摄像头进行深度估计 1.1 深度估计原理 这里会用到几何学中的极几何(Epipolar Geometry),它属于立体视觉(stereo vision)几何学,立体视觉是计算机视觉的一个分 ...

  3. python数字图像处理(19):骨架提取与分水岭算法

    骨架提取与分水岭算法也属于形态学处理范畴,都放在morphology子模块内. 1.骨架提取 骨架提取,也叫二值图像细化.这种算法能将一个连通区域细化成一个像素的宽度,用于特征提取和目标拓扑表示. m ...

  4. 【Keras】基于SegNet和U-Net的遥感图像语义分割

    上两个月参加了个比赛,做的是对遥感高清图像做语义分割,美其名曰"天空之眼".这两周数据挖掘课期末project我们组选的课题也是遥感图像的语义分割,所以刚好又把前段时间做的成果重新 ...

  5. 第八节、图片分割之GrabCut算法、分水岭算法

    所谓图像分割指的是根据灰度.颜色.纹理和形状等特征把图像划分成若干互不交迭的区域,并使这些特征在同一区域内呈现出相似性,而在不同区域间呈现出明显的差异性.我们先对目前主要的图像分割方法做个概述,后面再 ...

  6. 图片分割之GrabCut算法、分水岭算法

    https://www.cnblogs.com/zyly/p/9392881.html 所谓图像分割指的是根据灰度.颜色.纹理和形状等特征把图像划分成若干互不交迭的区域,并使这些特征在同一区域内呈现出 ...

  7. opencv分水岭算法对图像进行切割

    先看效果 说明 使用分水岭算法对图像进行切割,设置一个标记图像能达到比較好的效果,还能防止过度切割. 1.这里首先对阈值化的二值图像进行腐蚀,去掉小的白色区域,得到图像的前景区域.并对前景区域用255 ...

  8. 图片像素对比OpenCV实现,实现人工分割跟算法分割图像结果的对比

    图片对比,计算不同像素个数,已经比率.实现人工分割跟算法分割图像结果的对比,但是只能用灰度图像作为输入 // imageMaskComparison.cpp : 定义控制台应用程序的入口点. // / ...

  9. opencv学习之路(30)、分水岭算法及图像修补

    一.简介 二.分水岭算法 #include "opencv2/opencv.hpp" using namespace cv; void main() { Mat srcImg = ...

随机推荐

  1. solr(CVE-2020-13957)文件上传

    影响版本 Apache Solr 6.6.0 - 6.6.5 Apache Solr 7.0.0 - 7.7.3 Apache Solr 8.0.0 - 8.6.2 环境搭建 下载环境 http:// ...

  2. yum 卸载

    # yum list installed | grep [软件名] #yum -y remove [软件名]

  3. 面试官:展开说说,Spring中Bean对象是如何通过注解注入的?

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 章节目录(手写Spring,让你了解更多) [x] 第 01 章:开篇介绍,我要带你撸 Spr ...

  4. etcd raft 处理流程图系列2-transport

    本章给出了raftexample中使用的传输层代码,补全了上一节中传输层与raft节点(raft server和channel server)的交互细节.下图中流程的核心在于传输层中的streamRt ...

  5. Python设计模式: 最佳的"策略"模式实践代码

    Python设计模式: 最佳的"策略"模式实践代码 今天抽空看了下流畅的python,发现里面介绍了不少python自带的库的使用实例,用起来非常的优雅. 平时用Python来写爬 ...

  6. [源码解析] PyTorch 分布式(1) --- 数据加载之DistributedSampler

    [源码解析] PyTorch 分布式(1) --- 数据加载之DistributedSampler 目录 [源码解析] PyTorch 分布式(1) --- 数据加载之DistributedSampl ...

  7. Linux中的DNS的正解析

    目录 一.DNS概述 1.1.DNS定义 1.2.域名结构 1.3.DNS域名解析的方式 1.4.DNS服务器类型 1.5.BIND服务 BIND服务器端程序 二.构建DNS域名正向解析步骤 一.DN ...

  8. Linux统计文本中某个字符串出现的次数

    常用的有如下两种方式: 1.VIM 用vim打开文件,然后输入: :%s/hello//gn 如下图: 图中的例子就是统计文本中"hello"字符串出现的次数 说明: %s/pat ...

  9. 【监控】Zabbix安装

    目录 一.监控目的 二.监控方式 三.主流监控系统 四.Zabbix介绍 五.Zabbix服务端安装 5.1 环境介绍 5.2 准备系统环境 5.3 安装Nginx(源码编译安装) 5.3.1 配置N ...

  10. ACL的配置

    一.实验拓扑 实验要求: 二.实验编址 三.实验步骤: 1.启动设备(全选) 2.配置端口IP R1: R2: R3: R4: 2.搭建OSPF网络: R1: R2: R3: R4: 4.配置ACL控 ...