python读取tif格式的遥感影像(灰度图)并用迭代法阈值选择算法进行二值化处理

在python中,一般的图像处理库或者绘图库无法处理或显示遥感影像,例如Matplotlib,opencv,scipy等等,用这些库读取遥感影像数值会发生一定的错误,从而导致后续工作无法展开。因此我们需要用到GDAL这个库。

GDAL的安装

GDAL轮子安装网址
在这里插入图片描述

找到与自己python相对应的版本即可
轮子安装完成后,在终端cd到轮子的安装位置,输入pip install “文件名”
这样就完成GDAL的安装了

批量读取遥感影像

import os

from osgeo import gdal

filedir = "D:/img"		# 图片所在路径
for image in os.listdir(filedir):
	print(image)
	driver = gdal.GetDriverByName("GTiff")
	driver.Register()
	img = gdal.Open(filedir + '/' + image)
	im_width = img.RasterXSize	# 栅格矩阵的列数
	print("im_width:", im_width)
	im_height = img.RasterYSize	# 栅格矩阵的行数
	print("im_height:", im_height)
	band = img.GetRasterBand(1)
	im_data = img.ReadAsArray(0, 0, im_width, im_height)	# 获取数据
	print(im_data)

迭代法阈值选择算法

迭代法阈值选择算法是对双峰法的改进,首先选择一个近似的阈值T,将图像分割成两份,R1和R2,分别计算出R1和R2的均值u1和u2,再选择新的阈值T=(u1+u2)/2,重复以上步骤,直到u1和u2不再变化。

迭代法是基于逼近的思想,其步骤如下:
(1)求出图像的最大灰度值和最小灰度值,分别记为ZMAX和ZMIN,令初始阈值为T=(ZMAX+ZMIN)/2
(2)根据阈值T将图像分割为前景和背景,分别求出两者的平均灰度值ZO和ZB
(3)求出新阈值T=(ZO+ZB)/2
(4)若两个平均灰度值ZO和ZB不再发生变化(或T不再变化),则T为阈值,否则转(2)迭代计算

完整代码

import cv2
import os

import numpy as np
import pandas as pd
from osgeo import gdal

filedir = "D:/img"		# 图片所在路径
savedir = "D:/image"	# 保存路径
for image in os.listdir(filedir):
	print(image)
	driver = gdal.GetDriverByName("GTiff")
	driver.Register()
	img = gdal.Open(filedir + '/' + image)
	im_width = img.RasterXSize	# 栅格矩阵的列数
	print("im_width:", im_width)
	im_height = img.RasterYSize	# 栅格矩阵的行数
	print("im_height:", im_height)
	band = img.GetRasterBand(1)
	im_data = img.ReadAsArray(0, 0, im_width, im_height)	# 获取数据
	print(im_data)
	img = np.array(im_data)
	ZMAX = 0; ZMIN = 255
	ZO = 0; ZB = 255
	for i in img:
		if max(i) > ZMAX:
			ZMAX = max(i)
		if min(i) < ZMIN:
			ZMIN = min(i)
	T = (ZMAX + ZMIN) / 2
	img = pd.DataFrame(img)
	while True:
		ZO_ = img[img>T].mean().mean()
		ZB_ = img[img<=T].mean().mean()
		if (ZO_ == ZO) and (ZB_ == ZB):
			break
		else:
			ZO = ZO_; ZB = ZB_
			T = (ZO + ZB) / 2
		print(T)
	img[img>T] = 255
	img[img<=T] = 0
	tiff.imsave(savedir + '/' + image, np.array(img))	# 保存二值化后的图像
print("finish")

猜你喜欢

转载自blog.csdn.net/YuqingF/article/details/120394458