实现水体含量反演程序。
This commit is contained in:
118
find_severe_glint_area.py
Normal file
118
find_severe_glint_area.py
Normal file
@ -0,0 +1,118 @@
|
||||
from util import *
|
||||
from osgeo import gdal
|
||||
import argparse
|
||||
|
||||
|
||||
@timeit
|
||||
def otsu(img, max_value, data_water_mask, ignore_value=0, foreground=1, background=0):
|
||||
height = img.shape[0]
|
||||
width = img.shape[1]
|
||||
|
||||
hist = np.zeros([max_value], np.float32)
|
||||
|
||||
# 计算直方图
|
||||
invalid_counter = 0
|
||||
for i in range(height):
|
||||
for j in range(width):
|
||||
if img[i, j] == ignore_value or img[i, j] < 0 or data_water_mask[i, j] == 0:
|
||||
invalid_counter = invalid_counter + 1
|
||||
continue
|
||||
|
||||
hist[img[i, j]] += 1
|
||||
|
||||
hist /= (height * width - invalid_counter)
|
||||
|
||||
threshold = 0
|
||||
deltaMax = 0
|
||||
# 遍历像素值,计算最大类间方差
|
||||
for i in range(max_value):
|
||||
wA = 0
|
||||
wB = 0
|
||||
uAtmp = 0
|
||||
uBtmp = 0
|
||||
uA = 0
|
||||
uB = 0
|
||||
u = 0
|
||||
for j in range(max_value):
|
||||
if j <= i:
|
||||
wA += hist[j]
|
||||
uAtmp += j * hist[j]
|
||||
else:
|
||||
wB += hist[j]
|
||||
uBtmp += j * hist[j]
|
||||
if wA == 0:
|
||||
wA = 1e-10
|
||||
if wB == 0:
|
||||
wB = 1e-10
|
||||
uA = uAtmp / wA
|
||||
uB = uBtmp / wB
|
||||
u = uAtmp + uBtmp
|
||||
|
||||
# 计算类间方差
|
||||
deltaTmp = wA * ((uA - u)**2) + wB * ((uB - u)**2)
|
||||
# 找出最大类间方差以及阈值
|
||||
if deltaTmp > deltaMax:
|
||||
deltaMax = deltaTmp
|
||||
threshold = i
|
||||
|
||||
# 二值化
|
||||
det_img = img.copy()
|
||||
det_img[img > threshold] = foreground
|
||||
det_img[img <= threshold] = background
|
||||
det_img[np.where(data_water_mask == 0)] = background
|
||||
return det_img
|
||||
|
||||
|
||||
def find_overexposure_area(img_path, threhold=4095):
|
||||
# 第一步通过某个像素的光谱找到信号最强的波段
|
||||
|
||||
# 根据上步所得的波段号检测过曝区域
|
||||
pass
|
||||
|
||||
|
||||
@timeit
|
||||
def find_severe_glint_area(img_path, water_mask, glint_wave=750, output_path=None):
|
||||
if output_path is None:
|
||||
output_path = append2filename(img_path, "_severe_glint_area")
|
||||
|
||||
glint_band_number = find_band_number(glint_wave, img_path)
|
||||
|
||||
dataset = gdal.Open(img_path)
|
||||
num_bands = dataset.RasterCount
|
||||
im_geotrans = dataset.GetGeoTransform()
|
||||
im_proj = dataset.GetProjection()
|
||||
|
||||
tmp = dataset.GetRasterBand(glint_band_number + 1) # 波段计数从1开始
|
||||
band_flare = tmp.ReadAsArray().astype(np.int16)
|
||||
band_flare_stretch = (band_flare / band_flare.max() * 255).astype(np.int32)
|
||||
|
||||
dataset_water_mask = gdal.Open(water_mask)
|
||||
data_water_mask = dataset_water_mask.GetRasterBand(1).ReadAsArray()
|
||||
del dataset_water_mask
|
||||
|
||||
# 不加1报错:IndexError: index 73 is out of bounds for axis 0 with size 73
|
||||
flare_binary = otsu(band_flare_stretch, band_flare_stretch.max() + 1, data_water_mask)
|
||||
|
||||
write_bands(img_path, output_path, flare_binary)
|
||||
|
||||
del dataset
|
||||
|
||||
return output_path
|
||||
|
||||
|
||||
# Press the green button in the gutter to run the script.
|
||||
if __name__ == '__main__':
|
||||
img_path = r"D:\PycharmProjects\0water_rlx\test_data\ref_mosaic_1m_bsq"
|
||||
|
||||
parser = argparse.ArgumentParser(description="此程序通过大律法分割图像,提取耀斑最严重的区域,输出的栅格和输入的影像具有相同的行列数。")
|
||||
|
||||
parser.add_argument('-i1', '--input', type=str, required=True, help='输入影像文件的路径')
|
||||
parser.add_argument('-i2', '--input_water_mask', type=str, required=True, help='输入水域掩膜文件的路径')
|
||||
parser.add_argument('-gw', '--glint_wave', type=float, default=750.0, help='用于提取耀斑严重区域的波段.')
|
||||
parser.add_argument('-o', '--output', type=str, help='输出文件的路径')
|
||||
|
||||
parser.add_argument('-v', '--verbose', action='store_true', help='启用详细模式')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
find_severe_glint_area(args.input, args.input_water_mask, args.glint_wave, args.output)
|
Reference in New Issue
Block a user