修改粗糙度算法(地理编码模块)

dev
tian jiax 2023-10-24 16:22:24 +08:00
parent 477745e863
commit ded2843ceb
5 changed files with 286 additions and 18 deletions

View File

@ -0,0 +1,261 @@
# -*- coding: UTF-8 -*-
"""
@Project:microproduct
@File:SoilMoistureALg.py
@Function:实现土壤水分计算的算法
@Contact:
@Author:SHJ
@Date:2021/8/10 10:01
@Version:1.0.0
"""
import logging
from tool.algorithm.image.ImageHandle import ImageHandler
import numpy as np
import time
import scipy
import scipy.spatial.transform._rotation_groups # 解决打包的问题
from scipy.optimize import fmin
import math
from tool.algorithm.algtools.oh2004 import oh2004
logger = logging.getLogger("mylog")
class MoistureAlg:
def __init__(self,):
pass
@staticmethod
def cal_vwc(vwc_path, ndwi_path, e1, e2):
"""
:param vwc_path:
:param ndwi_path:
:param e1:
:param e2:
:return: True or False
"""
image_handler = ImageHandler()
proj = image_handler.get_projection(ndwi_path)
geotrans = image_handler.get_geotransform(ndwi_path)
array = image_handler.get_band_array(ndwi_path, 1)
# 原方案的计算方式
vwc = e1 * np.square(array) + e2 * array
# 论文《基于Radarsat-2全极化数据的高原牧草覆盖地表土壤水分反演》的计算方式
#vwc = e1 * array + e2
image_handler.write_img(vwc_path, proj, geotrans, vwc)
return True
@staticmethod
def cal_bare_soil_bsc(bsc_path, tif_path, vwc_path, arrival_angle_path, c, d):
"""
:param bsc_path:裸土后向散射系数
:param tif_path:输入影像
:param vwc_path:vwc影像路径
:param arrival_angle_path:入射角影像文件单位弧度
:param c:经验系数
:param d:经验系数
"""
image_handler = ImageHandler()
proj = image_handler.get_projection(tif_path)
geotrans = image_handler.get_geotransform(tif_path)
tif_array = image_handler.get_band_array(tif_path, 1)
vwc_array = image_handler.get_band_array(vwc_path, 1)
angle_array = image_handler.get_band_array(arrival_angle_path, 1)
try:
cos_angle = np.cos(angle_array)
tmp1 = tif_array - c * vwc_array * cos_angle
tmp2 = np.exp(-2 * d * vwc_array * (1/cos_angle))
bsc_array = 1 + tmp1/tmp2
except BaseException as msg:
logger.error(msg)
return False
bsc_array = np.where(bsc_array > 0, bsc_array, 0)
image_handler.write_img(bsc_path, proj, geotrans, bsc_array)
return True
@staticmethod
def cal_soil_moisture(soil_moisture_path, hh_bsc_path, vv_bsc_path, arrival_angle_path, mask_path, λ, f=5.3, T=24.5,bd=1, vsand=0.54, vclay=0.19,block_num=0):
"""
:param soil_moisture_path:土壤水分产品路径
:param hh_bsc_path:hh裸土后向散射系数
:param vv_bsc_path:vv裸土后向散射系数
:param arrival_angle_path:入射角影像文件
:param mask_path:掩膜影像文件
:param λ:经验系数
:param f:微波频率单位GHz
:param T:温度摄氏度
:param bd:土壤容重
:param vsand:沙土含量范围0-1
:param vclay:黏土含量范围0-1
:return: True or False
"""
image_handler = ImageHandler()
proj = image_handler.get_projection(hh_bsc_path)
geotrans = image_handler.get_geotransform(hh_bsc_path)
angle_array = image_handler.get_band_array(arrival_angle_path, 1)
try:
# 计算土壤介电常数
hh_bsc_array = image_handler.get_band_array(hh_bsc_path, 1)
if np.any(hh_bsc_array < 0):
logger.error("hh_bsc_array include negative value!")
return False
tmp = np.power(10, 0.19) * np.power(float(λ), 0.15) * hh_bsc_array
# 处理异常值
where_tmp1_0 = np.where(tmp == 0.0)
tmp[where_tmp1_0] = 1
except BaseException as msg:
logger.error(msg)
return False
try:
vv_bsc_array = image_handler.get_band_array(vv_bsc_path, 1)
if np.any(vv_bsc_array < 0):
logger.error("vv_bsc_array include negative value!")
return False
tmp2 = np.power(np.cos(angle_array), 1.82) * np.power(np.sin(angle_array), 0.93) *\
np.power(vv_bsc_array, 0.786)
# 处理异常值
where_tmp2_0 = np.where(tmp2 == 0.0)
tmp2[where_tmp2_0] = 1
tmp = tmp/tmp2
# 土壤介电常数
soil_dielectric = (1/(0.024 * np.tan(angle_array))) * np.log10(tmp)
soil_dielectric_path = soil_moisture_path.replace("soil_moisture","soil_dielectric")
image_handler.write_img(soil_dielectric_path, proj, geotrans, soil_dielectric)
except BaseException as msg:
logger.error(msg)
return False
mask_array = ImageHandler.get_band_array(mask_path, 1)
soil_dielectric[np.where(mask_array == 0)] = np.nan
try:
# Dobsen模型计算土壤水分
soil_moisture = dobsen_inverse(f, T, bd, vsand, vclay, soil_dielectric, block_num)
# topp模型计算土壤水分
# soil_moisture = -5.3 * np.power(10.0, -2) + 2.92 * np.power(10.0, -2) * soil_dielectric - \
# 5.5 * np.power(10.0, -4) * np.power(soil_dielectric, 2) + \
# 4.3 * np.power(10.0, -6) * np.power(soil_dielectric, 3)
# 处理异常值
soil_moisture[where_tmp1_0] = 0
soil_moisture[where_tmp2_0] = 0
except BaseException as msg:
logger.error(msg)
return False
image_handler.write_img(soil_moisture_path, proj, geotrans, soil_moisture)
return True
@staticmethod
def cal_soilM(soil_moisture_path, hh_bsc_path, vv_bsc_path, hv_bsc_path, vh_bsc_path, angle_path,mask_path, wl):
"""
:param soil_moisture_path: 土壤水分路径
:param hh_bsc_path: hh极化路径
:param vv_bsc_path: vv极化路径
:param hv_bsc_path: hv极化路径
:param vh_bsc_path: vh极化路径
:param angle_path: 入射角
:param wl: 波长
:return:
"""
image_handler = ImageHandler()
proj = image_handler.get_projection(hh_bsc_path)
geotrans = image_handler.get_geotransform(hh_bsc_path)
hh_arr = ImageHandler.get_band_array(hh_bsc_path, 1)
hv_arr = ImageHandler.get_band_array(hv_bsc_path, 1)
vh_arr = ImageHandler.get_band_array(vh_bsc_path, 1)
vv_arr = ImageHandler.get_band_array(vv_bsc_path, 1)
angle_arr = ImageHandler.get_band_array(angle_path, 1)
mask_arr = ImageHandler.get_band_array(mask_path, 1)
f = oh2004.lamda2freq(wl/100)/1e9 # wl 原来是cm 得转成m
n = np.array(hh_arr).shape[0] * np.array(hh_arr).shape[1]
hh = np.array(hh_arr).flatten().astype(np.double)
hh[np.where(hh == -9999)] = np.nan
hv = np.array(hv_arr).flatten().astype(np.double)
hv[np.where(hv == -9999)] = np.nan
vv = np.array(vv_arr).flatten().astype(np.double)
vv[np.where(vv == -9999)] = np.nan
angle = np.array(angle_arr).flatten().astype(np.double)
angle[np.where(angle == -9999)] = np.nan
mask = np.array(mask_arr).flatten().astype(np.int32)
# foo_retrieve = inverse_radar(hh_arr, hv_arr, vh_arr, vv_arr, angle_arr, wl)
# mv, h = foo_retrieve.retrieve_oh2004_Cython()
mv = np.zeros(np.array(hh_arr).shape, dtype=np.double).flatten()
h = np.zeros(np.array(hh_arr).shape, dtype=np.double).flatten()
angle=angle*180/3.1415926
oh2004.retrieve_oh2004_main(n, mv, h, mask, vv, hh, hv, hv, angle, f)
soil = np.array(mv).reshape(np.array(hh_arr).shape)
image_handler.write_img(soil_moisture_path, proj, geotrans, soil)
return True
def dobsen_inverse(f, T, bd, vsand, vclay, soil_dielectric_array,block_num, x0=0):
"""
Dobsen模型土壤水分反演
:param f:微波频率单位GHz
:param T:温度摄氏度
:param bd:土壤容重
:param vsand:沙土含量范围0-1
:param vclay:黏土含量范围0-1
:param soil_dielectric_array:土壤介电常数
:param x0 :土壤水分寻优初始值
:return: True or False
"""
alpha = 0.65
sd = 2.65
dcs = (1.01 + 0.44 * sd) ** 2 - 0.062
dc0 = 0.008854
dcw0 = 88.045 - 0.4147 * T + 6.295e-4 * (T ** 2) + 1.075e-5 * (T ** 3)
tpt = 0.11109 - 3.824e-3 * T + 6.938e-5 * (T ** 2) - 5.096e-7 * (T ** 3)
dcwinf = 4.9
if f >= 1.4:
sigma = -1.645 + 1.939 * bd - 2.013e-2 * vsand + 1.594e-2 * vclay
else:
sigma = 0.0467 + 0.2204 * bd - 4.111e-3 * vsand + 6.614e-3 * vclay
dcwr = dcwinf + ((dcw0 - dcwinf) / (1 + (tpt * f) ** 2))
betar = 1.2748 - 0.00519 * vsand - 0.00152 * vclay
betai = 1.33797 - 0.00603 * vsand - 0.00166 * vclay
# fun = lambda vwc: np.abs(np.sqrt(
# ((1.0 + (bd / sd) * ((dcs ** alpha) - 1.0) + (vwc ** betar) * (dcwr ** alpha) - vwc) ** (1 / alpha)) ** 2 +
# ((vwc ** (betai / alpha)) * ((tpt * f * (dcw0 - dcwinf)) / (1 + (tpt * f) ** 2) + sigma * (1.0 - (bd / sd)) / (2 * np.pi * dc0 * f * vwc))) ** 2
# ) - soil_dielectric)
fun = lambda vwc: np.abs(np.sqrt(
((1.0 + (bd / sd) * ((dcs ** alpha) - 1.0) + (vwc ** betar) * (dcwr ** alpha) - vwc) ** (1 / alpha)) ** 2 +
((vwc ** (betai / alpha)) * ((tpt * f * (dcw0 - dcwinf)) / (1 + (tpt * f) ** 2) + sigma * (1.0 - (bd / sd)) / (8 * math.atan(1.0) * dc0 * f * vwc))) ** 2
) - soil_dielectric)
soil_dielectric_array[np.isnan(soil_dielectric_array)] = 0
w = np.where((soil_dielectric_array == 0) == False)
num = len(w[0])
soil_mois = np.zeros(num)
bar_list = [0, int(0.1*num), int(0.2*num), int(0.3*num), int(0.4*num), int(0.5*num), int(0.6*num), int(0.7*num), int(0.8*num), int(0.9*num), num-1]
start = time.perf_counter()
for soil_dielectric, n in zip(soil_dielectric_array[w], range(num)):
soil_mois[n] = fmin(fun, x0, disp=0)
if n in bar_list:
logger.info('block:{},cal soil_moisture proggress bar:{}%,use time :{}s'.format(block_num, round(n/num * 100), int(time.perf_counter()-start)))
soil_dielectric_array[w] = soil_mois # 土壤水分
return soil_dielectric_array

View File

@ -19,16 +19,16 @@ from tool.algorithm.transforml1a.transHandle import TransImgL1A
from tool.algorithm.xml.AlgXmlHandle import ManageAlgXML, CheckSource,InitPara # 导入xml文件读取与检查文件 from tool.algorithm.xml.AlgXmlHandle import ManageAlgXML, CheckSource,InitPara # 导入xml文件读取与检查文件
from tool.algorithm.image.ImageHandle import ImageHandler from tool.algorithm.image.ImageHandle import ImageHandler
from tool.algorithm.algtools.logHandler import LogHandler from tool.algorithm.algtools.logHandler import LogHandler
from SoilMoistureALg import MoistureAlg as alg from SurfaceRoughnessAlg import MoistureAlg as alg
from tool.algorithm.block.blockprocess import BlockProcess from tool.algorithm.block.blockprocess import BlockProcess
from tool.algorithm.algtools.MetaDataHandler import MetaDataHandler from tool.algorithm.algtools.MetaDataHandler import MetaDataHandler
from tool.config.ConfigeHandle import Config as cf from tool.config.ConfigeHandle import Config as cf
from tool.algorithm.xml.CreatMetafile import CreateMetafile from tool.algorithm.xml.CreatMetafile import CreateMetafile
from tool.algorithm.algtools.ROIAlg import ROIAlg as roi from tool.algorithm.algtools.ROIAlg import ROIAlg as roi
from SoilMoistureXmlInfo import CreateDict, CreateStadardXmlFile from SurfaceRoughnessXmlInfo import CreateDict, CreateStadardXmlFile
from tool.algorithm.algtools.filter.lee_Filter import Filter from tool.algorithm.algtools.filter.lee_Filter import Filter
from tool.file.fileHandle import fileHandle from tool.file.fileHandle import fileHandle
from SoilMoistureTool import SoilMoistureTool from SurfaceRoughnessTool import SoilMoistureTool
import logging import logging
import os import os
import shutil import shutil
@ -114,6 +114,8 @@ class MoistureMain:
# para_dic.update(InitPara.get_meta_dic(InitPara.get_meta_paths(file_dir, name), name)) # para_dic.update(InitPara.get_meta_dic(InitPara.get_meta_paths(file_dir, name), name))
para_dic.update(InitPara.get_meta_dic_new(InitPara.get_meta_paths(file_dir, name), name)) para_dic.update(InitPara.get_meta_dic_new(InitPara.get_meta_paths(file_dir, name), name))
# tif路径字典 # tif路径字典
parameter_path = os.path.join(file_dir, "orth_para.txt")
para_dic.update({"paraMeter": parameter_path})
pol_dic = InitPara.get_polarization_mode(InitPara.get_tif_paths(file_dir, name)) pol_dic = InitPara.get_polarization_mode(InitPara.get_tif_paths(file_dir, name))
flag_list = [0, 0, 0, 0] flag_list = [0, 0, 0, 0]
@ -136,6 +138,8 @@ class MoistureMain:
para_dic.update({'inc_angle': in_tif_path}) para_dic.update({'inc_angle': in_tif_path})
elif 'ori_sim' == key: elif 'ori_sim' == key:
para_dic.update({'ori_sim': in_tif_path}) para_dic.update({'ori_sim': in_tif_path})
elif 'sim_ori' == key:
para_dic.update({'sim_ori': in_tif_path})
elif 'LocalIncidenceAngle' == key: elif 'LocalIncidenceAngle' == key:
para_dic.update({'LocalIncidenceAngle': in_tif_path}) para_dic.update({'LocalIncidenceAngle': in_tif_path})
elif 'inci_Angle-ortho' == key: elif 'inci_Angle-ortho' == key:
@ -173,13 +177,13 @@ class MoistureMain:
# self.__preprocessed_paras, scopes_roi = p.preprocessing_oh2004(para_names, self.__processing_paras, # self.__preprocessed_paras, scopes_roi = p.preprocessing_oh2004(para_names, self.__processing_paras,
# self.__workspace_preprocessing_path, self.__workspace_preprocessed_path) # self.__workspace_preprocessing_path, self.__workspace_preprocessed_path)
para_names_geo = ['Covering', 'NDVI'] para_names_geo = ['Covering', 'NDVI', 'inc_angle', 'sim_ori']
p = pp() p = pp()
cutted_img_paths, scopes_roi = p.cut_geoimg(self.__workspace_preprocessing_path, para_names_geo, cutted_img_paths, scopes_roi = p.cut_geoimg(self.__workspace_preprocessing_path, para_names_geo,
self.__processing_paras) self.__processing_paras)
self.__preprocessed_paras.update(cutted_img_paths) self.__preprocessed_paras.update(cutted_img_paths)
para_names_l1a = ["HH", "VV", "HV", "VH", 'inci_Angle-ortho', 'ori_sim'] para_names_l1a = ["HH", "VV", "HV", "VH", 'ori_sim']
self._tr = TransImgL1A(self.__processing_paras['ori_sim'], scopes_roi) self._tr = TransImgL1A(self.__processing_paras['ori_sim'], scopes_roi)
for name in para_names_l1a: for name in para_names_l1a:
@ -254,15 +258,14 @@ class MoistureMain:
pp.resampling_by_scale(self.__preprocessed_paras["Covering"], cover_rampling_path, refer_img_path) pp.resampling_by_scale(self.__preprocessed_paras["Covering"], cover_rampling_path, refer_img_path)
self.__preprocessed_paras["Covering"] = cover_rampling_path self.__preprocessed_paras["Covering"] = cover_rampling_path
def inter_Range2Geo(self, lon_lat_path, data_tiff, grid_path, space): def calInterpolation_bil_Wgs84_rc_sar_sigma(self, parameter_path, dem_rc, in_sar, out_sar):
''' '''
# std::cout << "mode 10"; # std::cout << "mode 11";
# std::cout << "SIMOrthoProgram.exe 10 lon_lat_path data_tiff grid_path space"; # std::cout << "SIMOrthoProgram.exe 11 in_parameter_path in_rc_wgs84_path in_ori_sar_path out_orth_sar_path";
''' '''
exe_path = r".\baseTool\x64\Release\SIMOrthoProgram.exe" exe_path = r".\baseTool\x64\Release\SIMOrthoProgram.exe"
exe_cmd = r"set PROJ_LIB=.\baseTool\x64\Release; & {0} {1} {2} {3} {4} {5}".format(exe_path, 10, exe_cmd = r"set PROJ_LIB=.\baseTool\x64\Release; & {0} {1} {2} {3} {4} {5}".format(exe_path, 11, parameter_path,
lon_lat_path, data_tiff, dem_rc, in_sar, out_sar)
grid_path, space)
print(exe_cmd) print(exe_cmd)
print(os.system(exe_cmd)) print(os.system(exe_cmd))
print("==========================================================================") print("==========================================================================")
@ -275,7 +278,7 @@ class MoistureMain:
tem_folder = self.__workspace_path + EXE_NAME + r"\Temporary""\\" tem_folder = self.__workspace_path + EXE_NAME + r"\Temporary""\\"
soilOh2004 = SoilMoistureTool(self.__workspace_preprocessed_path, self.__workspace_processing_path, self.__cols, soilOh2004 = SoilMoistureTool(self.__workspace_preprocessed_path, self.__workspace_processing_path, self.__cols,
self.__rows, self.__preprocessed_paras['inci_Angle-ortho'], self.__processing_paras['Origin_META']) self.__rows, self.__preprocessed_paras['inc_angle'], self.__processing_paras['Origin_META'])
result = soilOh2004.soil_oh2004() result = soilOh2004.soil_oh2004()
logger.info('progress bar: 80%') logger.info('progress bar: 80%')
@ -287,7 +290,10 @@ class MoistureMain:
shutil.copy(tif_file, product_temp_path) shutil.copy(tif_file, product_temp_path)
product_geo_path = os.path.join(tem_folder, 'SurfaceRoughnessProduct_geo.tif') product_geo_path = os.path.join(tem_folder, 'SurfaceRoughnessProduct_geo.tif')
self.inter_Range2Geo(self.__preprocessed_paras['ori_sim'], product_temp_path, product_geo_path, pixelspace) self.calInterpolation_bil_Wgs84_rc_sar_sigma(self.__processing_paras['paraMeter'],
self.__preprocessed_paras['sim_ori'], product_temp_path,
product_geo_path)
# self.inter_Range2Geo(self.__preprocessed_paras['ori_sim'], product_temp_path, product_geo_path, pixelspace)
# self._tr.l1a_2_geo_int(self.__preprocessed_paras['ori_sim'], product_temp_path, product_geo_path, 'linear') # self._tr.l1a_2_geo_int(self.__preprocessed_paras['ori_sim'], product_temp_path, product_geo_path, 'linear')
# #
# hh_geo_path = self.__workspace_processing_path + "hh_geo.tif" # hh_geo_path = self.__workspace_processing_path + "hh_geo.tif"
@ -298,10 +304,11 @@ class MoistureMain:
bare_land_mask_path = roi().roi_process(para_names, self.__workspace_processing_path + "/roi/", bare_land_mask_path = roi().roi_process(para_names, self.__workspace_processing_path + "/roi/",
self.__processing_paras, self.__preprocessed_paras) self.__processing_paras, self.__preprocessed_paras)
product_path = os.path.join(self.__product_dic, 'SurfaceRoughnessProduct.tif') SrcImageName = os.path.split(self.__input_paras["DualPolarSAR"]['ParaValue'])[1].split('.tar.gz')[0] + '-Roughness.tif'
product_path = os.path.join(self.__product_dic, SrcImageName)
# 获取影像roi区域 # 获取影像roi区域
roi.cal_roi(product_path, product_geo_path, bare_land_mask_path, background_value=np.nan) roi.cal_roi(product_path, product_geo_path, bare_land_mask_path, background_value=0)
# 生成快视图 # 生成快视图
self.imageHandler.write_quick_view(product_path) self.imageHandler.write_quick_view(product_path)

View File

@ -3,7 +3,7 @@
block_cipher = None block_cipher = None
a = Analysis(['SoilMoistureMain.py'], a = Analysis(['SurfaceRoughnessMain.py'],
pathex=['D:\\estar-proj\\microproduct\\surfaceRoughness_oh2004'], pathex=['D:\\estar-proj\\microproduct\\surfaceRoughness_oh2004'],
binaries=[], binaries=[],
datas=[('D:/Anaconda/envs/micro/Lib/site-packages/dask/dask.yaml', './dask'), ('D:/Anaconda/envs/micro/Lib/site-packages/distributed/distributed.yaml', './distributed')], datas=[('D:/Anaconda/envs/micro/Lib/site-packages/dask/dask.yaml', './dask'), ('D:/Anaconda/envs/micro/Lib/site-packages/distributed/distributed.yaml', './distributed')],
@ -23,7 +23,7 @@ exe = EXE(pyz,
a.zipfiles, a.zipfiles,
a.datas, a.datas,
[], [],
name='SoilMoistureMain', name='SurfaceRoughnessMain',
debug=False, debug=False,
bootloader_ignore_signals=False, bootloader_ignore_signals=False,
strip=False, strip=False,

View File

@ -53,7 +53,7 @@ class SoilMoistureTool:
leeFilter.api_lee_refined_filter_T3('', t3_path, lee_filter_path, 0, 0, atp.rows(), atp.cols()) leeFilter.api_lee_refined_filter_T3('', t3_path, lee_filter_path, 0, 0, atp.rows(), atp.cols())
logger.info("refine_lee filter success!") logger.info("refine_lee filter success!")
# logging.info("refine_lee filter success!") # logging.info("refine_lee filter success!")
return t3_path return lee_filter_path
# def create_incidence(self, incidence_xml): # def create_incidence(self, incidence_xml):