356 lines
16 KiB
Python
356 lines
16 KiB
Python
|
# -*- coding: UTF-8 -*-
|
|||
|
"""
|
|||
|
@Project :microproduct
|
|||
|
@File :SoilMoistureMain.py
|
|||
|
@Author :SHJ
|
|||
|
@Contact:
|
|||
|
@Date :2021/7/26 17:11
|
|||
|
@Version :1.0.0
|
|||
|
修改历史:
|
|||
|
[修改序列] [修改日期] [修改者] [修改内容]
|
|||
|
1 2022-6-30 石海军 1.使用cover_roi_id来选取ROI区域; 2.内部处理使用地理坐标系(4326);
|
|||
|
"""
|
|||
|
import glob
|
|||
|
|
|||
|
from osgeo import osr
|
|||
|
|
|||
|
from tool.algorithm.algtools.PreProcess import PreProcess as pp
|
|||
|
from tool.algorithm.transforml1a.transHandle import TransImgL1A
|
|||
|
from tool.algorithm.xml.AlgXmlHandle import ManageAlgXML, CheckSource,InitPara # 导入xml文件读取与检查文件
|
|||
|
from tool.algorithm.image.ImageHandle import ImageHandler
|
|||
|
from tool.algorithm.algtools.logHandler import LogHandler
|
|||
|
from SoilMoistureALg import MoistureAlg as alg
|
|||
|
from tool.algorithm.block.blockprocess import BlockProcess
|
|||
|
from tool.algorithm.algtools.MetaDataHandler import MetaDataHandler
|
|||
|
from tool.config.ConfigeHandle import Config as cf
|
|||
|
from tool.algorithm.xml.CreatMetafile import CreateMetafile
|
|||
|
from tool.algorithm.algtools.ROIAlg import ROIAlg as roi
|
|||
|
from SoilMoistureXmlInfo import CreateDict, CreateStadardXmlFile
|
|||
|
from tool.algorithm.algtools.filter.lee_Filter import Filter
|
|||
|
from tool.file.fileHandle import fileHandle
|
|||
|
from SoilMoistureTool import SoilMoistureTool
|
|||
|
import logging
|
|||
|
import os
|
|||
|
import shutil
|
|||
|
import datetime
|
|||
|
import numpy as np
|
|||
|
import sys
|
|||
|
import multiprocessing
|
|||
|
cover_id_list = []
|
|||
|
threshold_of_ndvi_min = 0
|
|||
|
threshold_of_ndvi_max = 0
|
|||
|
multiprocessing_num = int(cf.get('multiprocessing_num'))
|
|||
|
if cf.get('debug') == 'True':
|
|||
|
DEBUG = True
|
|||
|
else:
|
|||
|
DEBUG = False
|
|||
|
file =fileHandle(DEBUG)
|
|||
|
EXE_NAME = cf.get('exe_name')
|
|||
|
FILTER_SIZE = int(cf.get('filter_size'))
|
|||
|
soil_moisture_value_min = float(cf.get('product_value_min'))
|
|||
|
soil_moisture_value_max = float(cf.get('product_value_max'))
|
|||
|
|
|||
|
LogHandler.init_log_handler('run_log\\' + EXE_NAME)
|
|||
|
logger = logging.getLogger("mylog")
|
|||
|
env_str = os.path.split(os.path.realpath(__file__))[0]
|
|||
|
os.environ['PROJ_LIB'] = env_str
|
|||
|
|
|||
|
class MoistureMain:
|
|||
|
"""
|
|||
|
土壤水分处理主函数
|
|||
|
"""
|
|||
|
def __init__(self, alg_xml_path):
|
|||
|
self.alg_xml_path = alg_xml_path
|
|||
|
self.imageHandler = ImageHandler()
|
|||
|
self.__alg_xml_handler = ManageAlgXML(alg_xml_path)
|
|||
|
self.__check_handler = CheckSource(self.__alg_xml_handler)
|
|||
|
self.__workspace_path, self.__out_para = None, None
|
|||
|
self.__input_paras, self.__output_paras, self.__processing_paras, self.__preprocessed_paras = {},{},{},{}
|
|||
|
# 参考影像路径
|
|||
|
self.__ref_img_path = ''
|
|||
|
# 宽/列数,高/行数
|
|||
|
self.__cols, self.__rows = 0, 0
|
|||
|
# 坐标系
|
|||
|
self.__proj = ''
|
|||
|
# 影像投影变换矩阵
|
|||
|
self.__geo = [0, 0, 0, 0, 0, 0]
|
|||
|
self.name = ''
|
|||
|
|
|||
|
def check_source(self):
|
|||
|
"""
|
|||
|
检查算法相关的配置文件,图像,辅助文件是否齐全
|
|||
|
"""
|
|||
|
env_str = os.getcwd()
|
|||
|
logger.info("sysdir: %s", env_str)
|
|||
|
|
|||
|
if self.__check_handler.check_alg_xml() is False:
|
|||
|
return False
|
|||
|
|
|||
|
if self.__check_handler.check_run_env() is False:
|
|||
|
return False
|
|||
|
input_para_names = ['box', 'DualPolarSAR']
|
|||
|
if self.__check_handler.check_input_paras(input_para_names) is False:
|
|||
|
return False
|
|||
|
self.__workspace_path = self.__alg_xml_handler.get_workspace_path()
|
|||
|
self.__create_work_space()
|
|||
|
self.__input_paras = self.__alg_xml_handler.get_input_paras()
|
|||
|
self.__processing_paras = InitPara.init_processing_paras(self.__input_paras)
|
|||
|
self.__processing_paras.update(self.get_tar_gz_inf(self.__processing_paras["sar_path0"]))
|
|||
|
|
|||
|
self.__out_para = os.path.join(self.__workspace_path, EXE_NAME, 'Output', r"SoilMoistureProduct.tar.gz")
|
|||
|
self.__alg_xml_handler.write_out_para("SoilMoistureProduct", self.__out_para) #写入输出参数
|
|||
|
|
|||
|
logger.info('check_source success!')
|
|||
|
logger.info('progress bar: 10%')
|
|||
|
return True
|
|||
|
|
|||
|
def get_tar_gz_inf(self, tar_gz_path):
|
|||
|
para_dic = {}
|
|||
|
self.name = os.path.split(tar_gz_path)[1].rstrip('.tar.gz')
|
|||
|
name = os.path.split(tar_gz_path)[1].rstrip('.tar.gz')
|
|||
|
file_dir = os.path.join(self.__workspace_preprocessing_path, name + '\\')
|
|||
|
file.de_targz(tar_gz_path, file_dir)
|
|||
|
# 元文件字典
|
|||
|
# 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))
|
|||
|
# tif路径字典
|
|||
|
pol_dic = InitPara.get_polarization_mode(InitPara.get_tif_paths(file_dir, name))
|
|||
|
|
|||
|
flag_list = [0, 0, 0, 0]
|
|||
|
|
|||
|
for key, in_tif_path in pol_dic.items():
|
|||
|
# 获取极化类型
|
|||
|
if 'HH' == key:
|
|||
|
para_dic.update({'HH': in_tif_path})
|
|||
|
flag_list[0] = 1
|
|||
|
elif 'HV' == key:
|
|||
|
para_dic.update({'HV': in_tif_path}) # 如果没有VV,用HV代替
|
|||
|
flag_list[1] = 1
|
|||
|
elif 'VV' == key:
|
|||
|
para_dic.update({'VV': in_tif_path})
|
|||
|
flag_list[2] = 1
|
|||
|
elif 'VH' == key:
|
|||
|
para_dic.update({'VH': in_tif_path})
|
|||
|
flag_list[3] = 1
|
|||
|
elif 'inc_angle' == key:
|
|||
|
para_dic.update({'inc_angle': in_tif_path})
|
|||
|
elif 'ori_sim' == key:
|
|||
|
para_dic.update({'ori_sim': in_tif_path})
|
|||
|
elif 'LocalIncidenceAngle' == key:
|
|||
|
para_dic.update({'LocalIncidenceAngle': in_tif_path})
|
|||
|
elif 'inci_Angle-ortho' == key:
|
|||
|
para_dic.update({'inci_Angle-ortho': in_tif_path})
|
|||
|
elif 'LocalIncidentAngle-ortho' == key:
|
|||
|
para_dic.update({'LocalIncidentAngle-ortho': in_tif_path})
|
|||
|
if flag_list != [1, 1, 1, 1]:
|
|||
|
raise Exception('There are not tar_gz path: HH、HV(VV)、IncidenceAngle in path:', tar_gz_path)
|
|||
|
self.processinfo = flag_list
|
|||
|
return para_dic
|
|||
|
|
|||
|
def __create_work_space(self):
|
|||
|
"""
|
|||
|
删除原有工作区文件夹,创建新工作区文件夹
|
|||
|
"""
|
|||
|
self.__workspace_preprocessing_path = self.__workspace_path + EXE_NAME + r'\Temporary\preprocessing''\\'
|
|||
|
self.__workspace_preprocessed_path = self.__workspace_path + EXE_NAME + r'\Temporary\preprocessed''\\'
|
|||
|
self.__workspace_processing_path = self.__workspace_path + EXE_NAME + r'\Temporary\processing''\\'
|
|||
|
self.__workspace_block_tif_path = self.__workspace_path + EXE_NAME + r'\Temporary\blockTif''\\'
|
|||
|
self.__workspace_block_tif_processed_path = self.__workspace_path + EXE_NAME + r'\Temporary\blockTifProcessed''\\'
|
|||
|
self.__product_dic = self.__workspace_processing_path + 'product\\'
|
|||
|
path_list = [self.__workspace_preprocessing_path, self.__workspace_preprocessed_path,
|
|||
|
self.__workspace_processing_path, self.__workspace_block_tif_path,
|
|||
|
self.__workspace_block_tif_processed_path, self.__product_dic]
|
|||
|
|
|||
|
file.creat_dirs(path_list)
|
|||
|
logger.info('create new workspace success!')
|
|||
|
|
|||
|
def preprocess_handle(self):
|
|||
|
"""
|
|||
|
预处理
|
|||
|
"""
|
|||
|
# para_names = []
|
|||
|
# p = pp()
|
|||
|
# self.__preprocessed_paras, scopes_roi = p.preprocessing_oh2004(para_names, self.__processing_paras,
|
|||
|
# self.__workspace_preprocessing_path, self.__workspace_preprocessed_path)
|
|||
|
|
|||
|
para_names_geo = ['Covering', 'NDVI']
|
|||
|
p = pp()
|
|||
|
cutted_img_paths, scopes_roi = p.cut_geoimg(self.__workspace_preprocessing_path, para_names_geo,
|
|||
|
self.__processing_paras)
|
|||
|
|
|||
|
self.__preprocessed_paras.update(cutted_img_paths)
|
|||
|
para_names_l1a = ["HH", "VV", "HV", "VH", 'inci_Angle-ortho', 'ori_sim']
|
|||
|
self._tr = TransImgL1A(self.__processing_paras['ori_sim'], scopes_roi)
|
|||
|
|
|||
|
for name in para_names_l1a:
|
|||
|
out_path = os.path.join(self.__workspace_preprocessed_path, name + "_preprocessed.tif")
|
|||
|
self._tr.cut_L1A(self.__processing_paras[name], out_path)
|
|||
|
self.__preprocessed_paras.update({name: out_path})
|
|||
|
logger.info('preprocess_handle success!')
|
|||
|
|
|||
|
self.__cols = self.imageHandler.get_img_width(self.__preprocessed_paras['HH'])
|
|||
|
self.__rows = self.imageHandler.get_img_height(self.__preprocessed_paras['HH'])
|
|||
|
logger.info('progress bar: 40%')
|
|||
|
|
|||
|
def create_roi(self):
|
|||
|
"""
|
|||
|
计算ROI掩膜
|
|||
|
:return: 掩膜路径
|
|||
|
"""
|
|||
|
processing_path = self.__workspace_processing_path
|
|||
|
# 利用角度为nan生成Mask
|
|||
|
pp.check_LocalIncidenceAngle(self.__preprocessed_paras['LocalIncidenceAngle'], self.__preprocessed_paras['LocalIncidenceAngle'])
|
|||
|
angle_nan_mask_path = processing_path + 'angle_nan_mask.tif'
|
|||
|
roi.trans_tif2mask(angle_nan_mask_path, self.__preprocessed_paras['LocalIncidenceAngle'], np.nan)
|
|||
|
|
|||
|
# 利用影像的有效范围生成MASK
|
|||
|
tif_mask_path = processing_path + 'tif_mask.tif'
|
|||
|
roi.trans_tif2mask(tif_mask_path, self.__preprocessed_paras['HH'], 0, 0) # 0,0修改为np.nan
|
|||
|
tif_zero_mask_path = processing_path + 'tif_mask_zero.tif'
|
|||
|
roi.trans_tif2mask(tif_zero_mask_path, self.__preprocessed_paras['HH'], np.nan)
|
|||
|
|
|||
|
# 利用cover计算植被覆盖范围
|
|||
|
cover_mask_path = processing_path + 'cover_mask.tif'
|
|||
|
#alg.trans_tif2mask(cover_mask_path, self.__preprocessed_paras['Covering'], threshold_of_cover_min, threshold_of_cover_max)
|
|||
|
|
|||
|
cover_id_list = list(self.__processing_paras['CoveringIDs'].split(';'))
|
|||
|
cover_id_list = [int(num) for num in cover_id_list]
|
|||
|
roi.trans_cover2mask(cover_mask_path, self.__preprocessed_paras["Covering"], cover_id_list)
|
|||
|
# 利用NDVI计算裸土范围该指数的输出值在 -1.0 和 1.0 之间,大部分表示植被量,
|
|||
|
# 负值主要根据云、水和雪而生成
|
|||
|
# 接近零的值则主要根据岩石和裸土而生成。
|
|||
|
# 较低的(小于等于 0.1)NDVI 值表示岩石、沙石或雪覆盖的贫瘠区域。
|
|||
|
# 中等值(0.2 至 0.3)表示灌木丛和草地
|
|||
|
# 较高的值(0.6 至 0.8)表示温带雨林和热带雨林。
|
|||
|
ndvi_mask_path = processing_path + 'ndvi_mask.tif'
|
|||
|
ndvi_scope = list(self.__processing_paras['NDVIScope'].split(';'))
|
|||
|
threshold_of_ndvi_min = float(ndvi_scope[0])
|
|||
|
threshold_of_ndvi_max = float(ndvi_scope[1])
|
|||
|
roi.trans_tif2mask(ndvi_mask_path, self.__preprocessed_paras['NDVI'], threshold_of_ndvi_min, threshold_of_ndvi_max)
|
|||
|
|
|||
|
|
|||
|
logger.info('create masks success!')
|
|||
|
# 利用覆盖范围和裸土范围 生成MASK
|
|||
|
bare_land_mask_path = processing_path + 'bare_land_mask.tif'
|
|||
|
roi.combine_mask(bare_land_mask_path, cover_mask_path, ndvi_mask_path)
|
|||
|
roi.combine_mask(bare_land_mask_path, bare_land_mask_path, tif_mask_path)
|
|||
|
roi.combine_mask(bare_land_mask_path, bare_land_mask_path, tif_zero_mask_path)
|
|||
|
roi.combine_mask(bare_land_mask_path, bare_land_mask_path, angle_nan_mask_path)
|
|||
|
logger.info('combine_mask success!')
|
|||
|
|
|||
|
# 计算roi区域
|
|||
|
roi.cal_roi(self.__preprocessed_paras['LocalIncidenceAngle'], self.__preprocessed_paras['LocalIncidenceAngle'],
|
|||
|
bare_land_mask_path, background_value=1)
|
|||
|
shutil.copyfile(bare_land_mask_path, self.__workspace_preprocessed_path + 'mask.tif')
|
|||
|
logger.info('create ROI image success!')
|
|||
|
return bare_land_mask_path
|
|||
|
|
|||
|
def resampleImgs(self, refer_img_path):
|
|||
|
ndvi_rampling_path = self.__workspace_processing_path + "ndvi.tif"
|
|||
|
pp.resampling_by_scale(self.__preprocessed_paras["NDVI"], ndvi_rampling_path, refer_img_path)
|
|||
|
self.__preprocessed_paras["NDVI"] = ndvi_rampling_path
|
|||
|
|
|||
|
cover_rampling_path = self.__workspace_processing_path + "cover.tif"
|
|||
|
pp.resampling_by_scale(self.__preprocessed_paras["Covering"], cover_rampling_path, refer_img_path)
|
|||
|
self.__preprocessed_paras["Covering"] = cover_rampling_path
|
|||
|
|
|||
|
def process_handle(self,start):
|
|||
|
"""
|
|||
|
算法主处理函数
|
|||
|
:return: True or False
|
|||
|
"""
|
|||
|
tem_folder = self.__workspace_path + EXE_NAME + r"\Temporary""\\"
|
|||
|
|
|||
|
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'])
|
|||
|
result = soilOh2004.soil_oh2004()
|
|||
|
|
|||
|
logger.info('progress bar: 80%')
|
|||
|
|
|||
|
product_temp_path = os.path.join(tem_folder, 'SoilMoistureProduct_temp.tif')
|
|||
|
tif_files = list(glob.glob(os.path.join(result, '*.tif')))
|
|||
|
for tif_file in tif_files:
|
|||
|
if 'oh2004_mv' in os.path.basename(tif_file):
|
|||
|
shutil.copy(tif_file, product_temp_path)
|
|||
|
product_geo_path = os.path.join(tem_folder, 'SoilMoistureProduct_geo.tif')
|
|||
|
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"
|
|||
|
self._tr.l1a_2_geo_int(self.__preprocessed_paras['ori_sim'], self.__preprocessed_paras['HH'], hh_geo_path, 'linear')
|
|||
|
self.resampleImgs(product_geo_path)
|
|||
|
|
|||
|
para_names = ['Covering', 'NDVI']
|
|||
|
bare_land_mask_path = roi().roi_process(para_names, self.__workspace_processing_path + "/roi/",
|
|||
|
self.__processing_paras, self.__preprocessed_paras)
|
|||
|
|
|||
|
product_path = os.path.join(self.__product_dic, 'SoilMoistureProduct.tif')
|
|||
|
# 获取影像roi区域
|
|||
|
|
|||
|
roi.cal_roi(product_path, product_geo_path, bare_land_mask_path, background_value=np.nan)
|
|||
|
|
|||
|
# 生成快视图
|
|||
|
self.imageHandler.write_quick_view(product_path)
|
|||
|
|
|||
|
# 生成元文件案例
|
|||
|
xml_path = "./model_meta.xml"
|
|||
|
|
|||
|
image_path = product_path
|
|||
|
out_path1 = os.path.join(tem_folder, "trans_geo_projcs.tif")
|
|||
|
out_path2 = os.path.join(tem_folder, "trans_projcs_geo.tif")
|
|||
|
par_dict = CreateDict(image_path, self.processinfo, out_path1, out_path2).calu_nature(start)
|
|||
|
model_xml_path = os.path.join(tem_folder, "creat_standard.meta.xml") # 输出xml路径
|
|||
|
|
|||
|
id_min = 0
|
|||
|
id_max = 1000
|
|||
|
threshold_of_ndvi_min = 0
|
|||
|
threshold_of_ndvi_max = 1
|
|||
|
set_threshold = [id_max, id_min, threshold_of_ndvi_min, threshold_of_ndvi_max]
|
|||
|
CreateStadardXmlFile(xml_path, self.alg_xml_path, par_dict, set_threshold, model_xml_path).create_standard_xml()
|
|||
|
|
|||
|
SrcImagePath = self.__input_paras["DualPolarSAR"]['ParaValue']
|
|||
|
paths = SrcImagePath.split(';')
|
|||
|
SrcImageName=os.path.split(paths[0])[1].split('.tar.gz')[0]
|
|||
|
if len(paths) >= 2:
|
|||
|
for i in range(1, len(paths)):
|
|||
|
SrcImageName=SrcImageName+";"+os.path.split(paths[i])[1].split('.tar.gz')[0]
|
|||
|
meta_xml_path = self.__product_dic + EXE_NAME + "Product.meta.xml"
|
|||
|
CreateMetafile(self.__processing_paras['META'], self.alg_xml_path, model_xml_path, meta_xml_path).process(SrcImageName)
|
|||
|
|
|||
|
# 文件夹打包
|
|||
|
file.make_targz(self.__out_para, self.__product_dic)
|
|||
|
logger.info('process_handle success!')
|
|||
|
logger.info('progress bar: 100%')
|
|||
|
|
|||
|
def del_temp_workspace(self):
|
|||
|
"""
|
|||
|
临时工作区
|
|||
|
"""
|
|||
|
if DEBUG is False:
|
|||
|
path = self.__workspace_path + EXE_NAME + r'\Temporary'
|
|||
|
if os.path.exists(path):
|
|||
|
file.del_folder(path)
|
|||
|
|
|||
|
if __name__ == '__main__':
|
|||
|
multiprocessing.freeze_support()
|
|||
|
start = datetime.datetime.now()
|
|||
|
try:
|
|||
|
if len(sys.argv) < 2:
|
|||
|
xml_path = 'SoilMoisture.xml'
|
|||
|
else:
|
|||
|
xml_path = sys.argv[1]
|
|||
|
main_handler = MoistureMain(xml_path)
|
|||
|
if main_handler.check_source() is False:
|
|||
|
raise Exception('check_source() failed!')
|
|||
|
if main_handler.preprocess_handle() is False:
|
|||
|
raise Exception('preprocess_handle() failed!')
|
|||
|
if main_handler.process_handle(start) is False:
|
|||
|
raise Exception('process_handle() failed!')
|
|||
|
logger.info('successful production of ' + EXE_NAME + ' products!')
|
|||
|
except Exception:
|
|||
|
logger.exception('run-time error!')
|
|||
|
finally:
|
|||
|
# main_handler.del_temp_workspace()
|
|||
|
pass
|
|||
|
end = datetime.datetime.now()
|
|||
|
msg = 'running use time: %s ' % (end - start)
|
|||
|
logger.info(msg)
|