引言
我们讨论了OTSU算法的实现,该算法主要集中在确定特征值阈值上,该值可用于论文的讨论和说明。 然而,实际上需要对图像执行各种滤波和预处理,并且在这种情况下,可能需要具有坐标和投影的分割结果。 本文实现对图像进行阈值分割后的结果的输出。
本文的代码包括三角阈值分割法、Riddler-Calvard分割法、自适应局部平均分割法、自适应局部温软西牛分割法四种不同的分割算法,前两种是全局算法,在Python的封装函数中输出阈值另外,本质问题在使用Riddler-Calvard分割法时,引用了mahotas库,但由于内部网下载缓慢,因此在此作为附件上传使用。
注意在安装过程中安装到自己的开发环境中,并且必须在激活环境后再使用pip install命令
maho tas-1.4.9-cp37-cp37m-win _ amd64.whl
1.7M
百度网盘
主要方法原理
1 .三角阈值分割法
三角法求阈值的方法在kxdhl的论文《Automatic measurement of sister chromatid exchange frequency》中主要用于染色体的研究。 该方法利用直方图数据,基于纯几何方法寻找最佳阈值。 其成立条件是假设直方图的最大峰值位于最亮侧,通过三角形求出最大直线距离,在与最大直线距离对应的直方图的灰度等级为分割阈值的直方图上,从最高峰的bmx到最暗的对应直方图bmin(p=0) %构筑直线其中,在对应于最大距离的直方图位置是对应于图像的二值化的阈值t的情况下,存在最大峰值对应位置不是位于直方图的最亮侧,而是位于暗侧的情况。 需要这样反转直方图,在反转后求出值
2.Riddler-Calvard分割法
Riddler-Calvard与OTSU和Triangle一样,是基于直方图计算求出阈值的二值化分割算法,唯一的区别是Riddler-Calvard是基于反复搜索实现的,其算法步骤如下
首先,设定初始阈值t,例如T=127,然后得到分割后的2个像素cluster。 这些平均值的计算方法如下: 其中,g表示图像像素的灰度值,灰度值范围g={0、1、2、3、L-1}表示灰度值,L=256表示256灰度值。 p(g )表示图像直方图的统计概率(百分比)。 下标: f表示前景,b表示背景。
计算新阈值:
计算两个阈值之间的差:
如果差值大于指定错误,则使用新阈值计算(1)、(2)和(3),并继续更新阈值,直到错误小于指定错误或迭代次数超过指定次数。 基于最终得到的阈值t实现图像的二值分割。
3 .自适应局部均值和温软的西牛加权阈值分割
如果同一图像上的不同部分具有不同的亮度,则必须使用自适应本地阈值按块分割图像。 此时的阈值是针对图像上的每个小区域计算与其对应的阈值。 因此,在同一图像上的不同区域采用了不同的阈值。 因此,Python的自适应封装函数不能输出阈值,只能输出图像。 使用该自适应局部分割算法,即使亮度不同也能得到更好的结果。
所谓自适应局部平均,是指按照设定的Size尺寸,求出图像中的Size尺寸区域内的亮度平均,并将从平均值中减去常数c后的值作为分割阈值。 同样,关于温软西牛权重阈值分割,将图像亮度值的温软的西牛权重和减法常数c作为分割阈值
数据介绍
数据参数与本文相同。 基于Python的阈值分割算法的实现(一)环岛.智湖.com
Python代码的实现
import numpy as np
导入cv2
导入Gdal
import mahotas
#Step 1定义图像读取方式
efimage_open(image ) :
是DATA=gdal.open(image )
if data=='None':
print (“无法读取数据”
返回数据
#Step 2读取有关图像的信息,转移到np uint8矩阵
file path=r ' e :yynctryedataNDVI批处理实验结果阈值实验遥感图像_NDVI.tif '
image1=image _ open (文件路径)
width=image1.RasterXSize
height=image1.RasterYSize
项目=image1.get项目(
变换=
image1.GetGeoTransform()DataArray = image1.ReadAsArray(0, 0, width, height)
#Step 3 归一化处理
File_Path = r"E:yynctryedataNDVI批处理实验结果阈值实验遥感图像_NDVI.tif"
image = image_open(File_Path).ReadAsArray()
Normalize_data = np.zeros(image.shape)
for i in range(image.shape[0]):
for j in range(image.shape[1]):
Normalize_data[i][j] = (image[i][j] - np.min(image)) / (np.max(image) - np.min(image))
Normalize_data = Normalize_data*256
data = Normalize_data.astype(np.uint8)
#Step 4 阈值分割(1.三角阈值分割 2.Riddler-Calvard分割 3.自适应温婉的西牛加权分割 4.自适应均值分割)
ret1, th1 = cv2.threshold(data, 0, 256, cv2.THRESH_BINARY+cv2.THRESH_TRIANGLE)
ret2 = mahotas.thresholding.rc(data)
th3 = cv2.adaptiveThreshold(data, 256, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 11, 2)
th4 = cv2.adaptiveThreshold(data, 256, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2)
#全局算法分割阈值打印
print("triangle分割阈值为:%d" %(ret1))
print("RC分割阈值为:%d" %(ret2))
#Step 5 Riddler-Calvard分割结果转图像矩阵
th2 = np.zeros(image.shape)
for i in range(image.shape[0]):
for j in range(image.shape[1]):
if(data[i][j] > ret2):
th2[i][j] = 256
else:
th2[i][j] = 0
#Step 6 结果输出
out_type = gdal.GetDriverByName("GTiff")
output_Triangle = out_type.Create(r"E:yynctryedataNDVI批处理实验结果三角阈值分割结果.tif", width, height, 1, gdal.GDT_Byte )
output_Triangle.SetProjection(Projection)
output_Triangle.SetGeoTransform(Transform)
output_RC = out_type.Create(r"E:yynctryedataNDVI批处理实验结果RC分割结果.tif", width, height, 1, gdal.GDT_Byte)
output_RC.SetProjection(Projection)
output_RC.SetGeoTransform(Transform)
output_Mean = out_type.Create(r"E:yynctryedataNDVI批处理实验结果均值分割结果.tif", width, height, 1, gdal.GDT_Byte)
output_Mean.SetProjection(Projection)
output_Mean.SetGeoTransform(Transform)
output_Gaussian = out_type.Create(r"E:yynctryedataNDVI批处理实验结果温婉的西牛加权分割结果.tif", width, height, 1, gdal.GDT_Byte)
output_Gaussian.SetProjection(Projection)
output_Gaussian.SetGeoTransform(Transform)
output1 = output_Triangle.GetRasterBand(1).WriteArray(th1)
output2 = output_RC.GetRasterBand(1).WriteArray(th2)
output3 = output_Mean.GetRasterBand(1).WriteArray(th3)
output4 = output_Gaussian.GetRasterBand(1).WriteArray(th4)
代码关键点说明:
在全局算法分割阈值打印时输出的阈值如果需要转为实际的NDVI数值按照该文方法中的Python代码实现(二)进行处理即可:上官:基于Python的阈值分割算法实现(一)zhuanlan.zhihu.com
Python函数说明
下面讲下关于本文涉及的关键函数参数:
1.全局阈值分割:
cv2.threshold(data, 0, 256, cv2.THRESH_BINARY+cv2.THRESH_TRIANGLE)
其中,data为图像矩阵;0为设置的阈值(Otsu和triangle均为0);256为最大阈值; cv2.THRESH_BINARY+cv2.THRESH_TRIANGLE为阈值确定的方法。
2.自适应阈值分割:
cv2.adaptiveThreshold(data, 256, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2)
其中,data为图像矩阵;256为最大阈值;cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY,均为图像处理方法,后者也可以转换为INV方;11为每次分割的图像区域大小;2为需要减掉的常数c。
处理结果(a)为三角法分割结果; (b)为Riddler-Calvard分割法结果; (c)为自适应局部均值分割结果; (d)为自适应局部温婉的西牛加权分割结果
从结果中我们可以得到,全局分割方法效果更好,特别是三角分割结果。当然,本文未局部阈值分割法进行参数调试过程,因此,也不能说该方法对于建筑物提取不好,这需要读者根据自己的数据和特征进行参数的调试和各种预处理。
参考文献图像处理之三角法图像二值化_人工智能_关注微信公众号【OpenCV学堂】-CSDN博客blog.csdn.net干货 | 简单粗暴二分类分割方法Riddler-Calvard 详解!_阈值www.sohu.com