python实现分水岭算法分割遥感图像
1. 定义
分水岭算法(watershed algorithm)可以将图像中的边缘转化为“山脉”,将均匀区域转化为“山谷”,在这方面有助于分割目标。
分水岭算法:是一种基于拓扑理论的数学形态学的分割方法。把图像看作是测地学上的拓扑地貌,图像中的每一个点像素值的灰度值表示该点的海拔高度,每一个局部极小值及其影响的区域称为“集水盆”,集水盆的边界可以看成分水岭。在每一个局部极小值表面刺穿一个小孔,然后把整个模型慢慢浸入水中,随着浸入的加深,每一个局部极小值的影响域慢慢的向外扩展,在两个集水盆汇合处构建大坝,形成分水岭。
迭代标注过程:
- 排序过程:对每个像素的灰度级进行从低到高的排序
- 淹没过程:对每一个局部最小值在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实现分水岭算法分割遥感图像的更多相关文章
- python实现分水岭算法
目录: 问题:分水岭算法对图像分割很有作用,怎么把对象分割开来的?分水岭算法是比较完美的分割,跟前面的讲的轮廓不一样! (一)原理 (二)实现 (一)原理 opencv中的分水岭算法是基于距离变换的, ...
- OpenCV 学习笔记 04 深度估计与分割——GrabCut算法与分水岭算法
1 使用普通摄像头进行深度估计 1.1 深度估计原理 这里会用到几何学中的极几何(Epipolar Geometry),它属于立体视觉(stereo vision)几何学,立体视觉是计算机视觉的一个分 ...
- python数字图像处理(19):骨架提取与分水岭算法
骨架提取与分水岭算法也属于形态学处理范畴,都放在morphology子模块内. 1.骨架提取 骨架提取,也叫二值图像细化.这种算法能将一个连通区域细化成一个像素的宽度,用于特征提取和目标拓扑表示. m ...
- 【Keras】基于SegNet和U-Net的遥感图像语义分割
上两个月参加了个比赛,做的是对遥感高清图像做语义分割,美其名曰"天空之眼".这两周数据挖掘课期末project我们组选的课题也是遥感图像的语义分割,所以刚好又把前段时间做的成果重新 ...
- 第八节、图片分割之GrabCut算法、分水岭算法
所谓图像分割指的是根据灰度.颜色.纹理和形状等特征把图像划分成若干互不交迭的区域,并使这些特征在同一区域内呈现出相似性,而在不同区域间呈现出明显的差异性.我们先对目前主要的图像分割方法做个概述,后面再 ...
- 图片分割之GrabCut算法、分水岭算法
https://www.cnblogs.com/zyly/p/9392881.html 所谓图像分割指的是根据灰度.颜色.纹理和形状等特征把图像划分成若干互不交迭的区域,并使这些特征在同一区域内呈现出 ...
- opencv分水岭算法对图像进行切割
先看效果 说明 使用分水岭算法对图像进行切割,设置一个标记图像能达到比較好的效果,还能防止过度切割. 1.这里首先对阈值化的二值图像进行腐蚀,去掉小的白色区域,得到图像的前景区域.并对前景区域用255 ...
- 图片像素对比OpenCV实现,实现人工分割跟算法分割图像结果的对比
图片对比,计算不同像素个数,已经比率.实现人工分割跟算法分割图像结果的对比,但是只能用灰度图像作为输入 // imageMaskComparison.cpp : 定义控制台应用程序的入口点. // / ...
- opencv学习之路(30)、分水岭算法及图像修补
一.简介 二.分水岭算法 #include "opencv2/opencv.hpp" using namespace cv; void main() { Mat srcImg = ...
随机推荐
- php cookie赋值使用
setcookie('username',$user,time()+3600*24); //cookie赋值 public function login(){ //cookie 使用 ...
- PHP-CGI远程代码执行漏洞(CVE-2012-1823)
影响版本 php < 5.3.12 or php < 5.4.2 访问http://p:8080/index.php?-s即爆出源码,说明漏洞存在 POST /index.php?-d+a ...
- 关于win7+cenos 7双系统安装
---恢复内容开始--- 1,cenos 0 7制作U盘启动 制作工具 http://pan.baidu.com/s/1nv9lpmp 镜像自备 2,安装centos 7 释放磁盘空间,如:20G.用 ...
- spring框架的学习->从零开始学JAVA系列
目录 Spring框架的学习 框架的概念 框架的使用 Spring框架的引入 概念 作用 内容 SpringIOC的学习 概念 作用 基本使用流程 SpringIOC创建对象的三种方式 通过构造器方式 ...
- 题解CF757B
题目 题意:在 \(s\) 数组中找出尽可能多的数使得他们的最大公约数 \(>1\) 既然最大公约数 \(>1\),\(s\) 数组的值域是 \(1 \le s_i \le 10^5\), ...
- 3、基于Python建立任意层数的深度神经网络
一.神经网络介绍: 神经网络算法参考人的神经元原理(轴突.树突.神经核),在很多神经元基础上构建神经网络模型,每个神经元可看作一个个学习单元.这些神经元采纳一定的特征作为输入,根据自身的模型得到输出. ...
- springboot整合javafx
原文(原码)参考地址: https://github.com/roskenet/springboot-javafx-support https://github.com/spartajet/javaf ...
- rancher清理主机脚本
#!/bin/bash #From:rancher #date:2019-10-18 #admin:jarno # 停止服务 systemctl disable kubelet.service sys ...
- STM32—位带操作
STM32中的位带操作: 名字为位带操作,实际上是对位的操作,位操作就是可以单独的对一个比特位读和写,这个在 51 单片机中非常常见. 51 单片机中通过关键字 sbit 来实现位定义, STM32 ...
- Java虚拟机漫漫学习路,我终于悟了
毕业8年,前5年的职业规划是做计算广告,后来感觉计算广告这一行更注重的是业务而非技术,而自己的性格更适合做技术,所以毅然决然的辞职, 全职1年半时间写了2本关于Java编译器与虚拟机的书,今年年初来到 ...