Merge remote-tracking branch 'origin/dev-pyramid'

This commit is contained in:
copper 2022-08-02 15:34:36 +08:00
commit e8e7dba935
5 changed files with 171 additions and 31 deletions

View File

@ -241,6 +241,7 @@ class InOnePlugin(BasicPlugin):
pth2=Meanfilter(w.x_size_input.text(),w.y_size_input.text(),w.layer_combox.layer2)
self.send_message.emit('均值滤波图像{}'.format(w.layer_combox.layer2.name))
name=name+'_mean_filter'
dict['预处理']=['均值滤波','|'.format(pth1,pth2)]
else:
pass
@ -248,18 +249,18 @@ class InOnePlugin(BasicPlugin):
if w.cd_select.choose==self.cd[0]:
cdpth=basic_cd(pth1,pth2,w.layer_combox.layer1.layer_parent,self.send_message)
name += '_basic_cd'
#dict[name]=cdpth
dict['变化检测算法']=['差分法',cdpth]
else:
pass
thpth=None
if w.threshold_select.choose==self.threshold[0]:
thpth=otsu(cdpth,w.layer_combox.layer1.layer_parent.name,self.send_message)
thpth,gap=otsu(cdpth,w.layer_combox.layer1.layer_parent.name,self.send_message)
name+='_otsu'
dict[name]=thpth
dict['后处理']=['OTSU阈值',gap,cdpth]
elif w.threshold_select.choose=='手动阈值':
thpth=thresh(cdpth,float(w.threshold_input.text()),w.layer_combox.layer1.layer_parent.name,self.send_message)
dict[name+'_thresh_{:.1f}'.format(float(w.threshold_input.text()))]
dict['后处理']=['手动阈值',[float(w.threshold_input.text())],thpth]
else:
pass
@ -417,7 +418,7 @@ def otsu(pth,name,send_message):
out_ds = None
ds = None
send_message.emit('OTSU阈值完成')
return out_th
return out_th,gap
#otsu_layer = SingleBandRasterLayer(path = out_th, style_info={})
#layer.layer_parent.add_result_layer(otsu_layer)
@ -496,8 +497,7 @@ def table_layer(pth,layer,name,send_message,dict):
center_y = center_y * geo[5] + geo [3]
f.write(f'{center_x},{center_y},{block_data_xy.mean() * 100},{int(block_data_xy.mean() > 0.5)}\n')
result_layer = ResultPointLayer(out_csv, enable=True, proj=layer.proj, geo=layer.geo)
result_layer.result_path=dict
result_layer = ResultPointLayer(out_csv, enable=True, proj=layer.proj, geo=layer.geo,result_path=dict)
# print(result_layer.result_path)
layer.layer_parent.add_result_layer(result_layer)
send_message.emit('计算完成')

View File

@ -57,7 +57,8 @@ class eagleEye(QgsMapCanvas):
self.setLayers(layer_list_1)
if len(layer_list_1) > 0:
self.zoomToFeatureExtent(layer_list_1[0].extent())
def zoom(self,layer):
self.zoomToFeatureExtent(layer.extent())
def draw_extent(self,extent):
self.Extent=extent
self.rubber.draw_extent(self.Extent)

29
rscder/gui/info.py Normal file
View File

@ -0,0 +1,29 @@
from distutils.log import info
from PyQt5.QtWidgets import QHBoxLayout,QDialog,QLabel,QVBoxLayout
from PyQt5.QtGui import QColor, QDragEnterEvent, QDropEvent,QPixmap
from PyQt5.QtCore import QSize,Qt
import yaml
class InfoBox(QDialog):
def __init__(self,infodic:dict,parent=None):
super(InfoBox,self).__init__(parent=parent)
v=QVBoxLayout()
if 'prewmap' in infodic.keys():
pmap=infodic.pop('prewmap')
label=QLabel(yaml.dump(infodic,allow_unicode=True,sort_keys=False))
label.setWordWrap(True)#过长自动换行主要是wkt过长
v.addWidget(label)
maplabel=QLabel()
maplabel.setPixmap(QPixmap.fromImage(pmap))
v.addWidget(maplabel,0,Qt.AlignHCenter)
else:
label=QLabel(yaml.dump(infodic,allow_unicode=True,sort_keys=False))
label.setWordWrap(True)#过长自动换行主要是wkt过长
v.addWidget(label)
self.setLayout(v)
self.show()

View File

@ -148,8 +148,8 @@ class loader(QDialog):
button_layout = QHBoxLayout()
button_layout.setDirection(QHBoxLayout.RightToLeft)
button_layout.addWidget(ok_button, 0, Qt.AlignRight)
button_layout.addWidget(cancel_button, 0, Qt.AlignRight)
button_layout.addWidget(ok_button, 0, Qt.AlignRight)
main_layout = QVBoxLayout()
main_layout.addLayout(path1_layout)
@ -169,14 +169,14 @@ class loader(QDialog):
self.path1_input.setText(self.path1)
result=QMessageBox.question(self, '提示', '是否创建图像金字塔', QMessageBox.Yes | QMessageBox.No, QMessageBox.No) #默认关闭界面选择No
if result==QMessageBox.Yes:
progress1=progressDialog(self,'加载时相一')
progress1:QDialog=progressDialog(self,'加载时相一')
progress1.setModal(False)
self.temp1=os.path.join(Project().other_path,'temp1.tif')
t1=GdalPreviewImage(self.path1,self.temp1,1024,self)
t1=GdalPreviewImage(self.path1,self.temp1,1024,self.parent())
# t1.started.connect(progress1.show)
t1.finished.connect(self.loadfile1)
t1.finished.connect(lambda :progress1.setlabel('创建影像金字塔..'))
t2=build_pyramids_overviews(self.path1,self)
t1.finished.connect(lambda :self.setlabel(progress1) )
t2=build_pyramids_overviews(self.path1,self.parent())
t2.finished.connect(progress1.hide)
t1.start()
t1.finished.connect(t2.start)
@ -186,7 +186,7 @@ class loader(QDialog):
progress1=progressDialog(self,'加载时相一')
progress1.setModal(False)
self.temp1=os.path.join(Project().other_path,'temp1.tif')
t1=GdalPreviewImage(self.path1,self.temp1,1024)
t1=GdalPreviewImage(self.path1,self.temp1,1024,self.parent())
# t1.started.connect(progress1.show)
t1.finished.connect(self.loadfile1)
t1.finished.connect(progress1.hide)
@ -217,11 +217,12 @@ class loader(QDialog):
progress2.setModal(False)
# progress1.show
self.temp2=os.path.join(Project().other_path,'temp2.tif')
t1=GdalPreviewImage(self.path2,self.temp2,1024,self)
t1=GdalPreviewImage(self.path2,self.temp2,1024,self.parent())
# t1.started.connect(progress1.show)
t1.finished.connect(self.loadfile2)
t1.finished.connect(lambda :progress2.setlabel('创建影像金字塔..'))
t2=build_pyramids_overviews(self.path2,self)
t1.finished.connect(lambda :self.setlabel(progress2))
t2=build_pyramids_overviews(self.path2,self.parent())
t2.finished.connect(progress2.hide)
t1.start()
t1.finished.connect(t2.start)
@ -230,7 +231,7 @@ class loader(QDialog):
progress2=progressDialog(self,'加载时相二')
progress2.setModal(False)
self.temp2=os.path.join(Project().other_path,'temp2.tif')
t1=GdalPreviewImage(self.path2,self.temp2,1024)
t1=GdalPreviewImage(self.path2,self.temp2,1024,self.parent())
# t1.started.connect(progress1.show)
t1.finished.connect(self.loadfile2)
t1.finished.connect(progress2.hide)
@ -266,7 +267,11 @@ class loader(QDialog):
def open_alg(self,path):
pass
def setlabel(self,s):
try:
s.setlabel('创建影像金字塔..')
except:
pass
def set_style1(self):
self.bandsorder1=[int(q.text()) for q in self.style1_inputs ]
self.style1={'r':self.bandsorder1[0],'g':self.bandsorder1[1],'b':self.bandsorder1[2],'NIR':self.bandsorder1[3]}
@ -335,6 +340,7 @@ class GdalPreviewImage(QThread):
del outDataset
except:
pass
# return outFilePath
@ -346,11 +352,9 @@ class build_pyramids_overviews(QThread):
try:
filename=self.filename
image:gdal.Dataset = gdal.Open(filename, 0)
# 如果第二个参数设置为0则金字塔文件建立在外面
# 如果第二个参数缺省或者为1则金字塔文件建立在文件内
gdal.SetConfigOption('COMPRESS_OVERVIEW', 'DEFLATE')
ov_list = [2, 4,6, 8, 12,16,24, 32, 48,64,96,128]
image.BuildOverviews("NEAREST", len(ov_list),overviewlist=ov_list)
image.BuildOverviews("NEAREST",overviewlist=ov_list)
del image
except:
pass

View File

@ -1,16 +1,21 @@
from cgitb import enable
from collections import OrderedDict
from email.message import Message
import imp
import inspect
import os
from pathlib import Path
from pydoc import render_doc
import shutil
from statistics import stdev
from threading import Thread
from time import sleep, time
from typing import Dict, List
import uuid
import numpy as np
from osgeo import gdal, gdal_array
from osgeo import gdal, gdal_array,osr
from rscder.utils.icons import IconInstance
from rscder.gui.info import InfoBox
from rscder.utils.setting import Settings
from qgis.core import (\
QgsRasterLayer, QgsMarkerSymbol, QgsUnitTypes,
@ -19,12 +24,12 @@ from qgis.core import (\
QgsLineSymbol, QgsSingleSymbolRenderer, QgsSimpleLineSymbolLayer,
QgsVectorLayer, QgsCoordinateReferenceSystem, QgsFeature,
QgsGeometry, QgsPointXY, QgsMultiBandColorRenderer)
from PyQt5.QtCore import QObject, pyqtSignal, Qt, QThread
from PyQt5.QtWidgets import QTreeWidgetItem, QAction
from PyQt5.QtCore import QObject, pyqtSignal, Qt, QThread,QSize
from PyQt5.QtWidgets import QTreeWidgetItem, QAction,QMessageBox
from PyQt5.QtGui import QColor, QIcon, QFont
import yaml
from .misc import singleton
from .misc import singleton
def relative_path(path: str, root:str) -> str:
return os.path.relpath(path, root)
@ -89,6 +94,7 @@ class Project(QObject):
self.layer_tree = layer_tree
self.message_box = message_box
self.result_table = result_table
self.eye=eye
IconInstance(self)
self.layer_tree_update.connect(layer_tree.update_layer)
self.layer_show_update.connect(pair_canvas.update_layer)
@ -176,6 +182,7 @@ class Project(QObject):
def zoom_to_layer(self, data):
self.pair_canvas.zoom_to_layer(data['layer'])
self.eye.zoom(data['layer'])
@property
def cmi_path(self):
@ -316,8 +323,22 @@ class BasicLayer(QObject):
del_action.triggered.connect(del_layer)
actions.append(del_action)
if self.info:
show_info=QAction(IconInstance().HELP,'属性信息')
actions.append(show_info)
def showIofn(info):
#print(info)
a=InfoBox(info)
a.exec_()
show_info.triggered.connect(lambda :showIofn(self.info))
return actions
return actions
@property
def info(self):
return None
class GridLayer(BasicLayer):
def set_render(self):
@ -391,7 +412,7 @@ class GridLayer(BasicLayer):
class RasterLayer(BasicLayer):
def __init__(self, name=None, enable=False, path=None, view_mode=BasicLayer.BOATH_VIEW,style_info={'r':3,'g':2,'b':1,'NIR':3}):
def __init__(self, name=None, enable=False, path=None, view_mode=BasicLayer.BOATH_VIEW,style_info={'r':3,'g':2,'b':1,'NIR':0}):
if name is None:
name = os.path.splitext(os.path.basename(path))[0]
super().__init__(name, enable, IconInstance().RASTER, path, BasicLayer.IN_FILE, view_mode)
@ -439,11 +460,44 @@ class RasterLayer(BasicLayer):
return s
def apply_style(self):
pass
@property
def bandinfo(self):
ds :gdal.Dataset= gdal.Open(self.path)
bands=ds.RasterCount
bandinfo_={}
for i in range(1,bands+1) :
min,max,mean,stdev=ds.GetRasterBand(i).ComputeStatistics(True)
bandinfo_['波段{}'.format(i)]=['最小值:{}'.format(min),'最大值:{}'.format(max),'均值:{}'.format(mean),'方差:{}'.format(stdev)]
ds=None
return bandinfo_
def set_stlye(self,style_info):
self.style_info=style_info
self.apply_style()
@property
def info(self):
#基础属性
basic={}
basic['文件名']=self.path
basic['文件大小']="{} Mb".format(os.path.getsize(self.path)//(1024*1024))
basic['波段信息']=self.bandinfo
#渲染属性
render=self.style_info
mapinfo={
'基础属性':basic,
'渲染属性':render,
'prewmap':self.preview
}
return mapinfo
@property
def preview(self,width=400):
w=self.layer.width()
h=self.layer.height()
return self.layer.previewAsImage(QSize(width,int(width*h/w)))
class MultiBandRasterLayer(RasterLayer):
@ -451,7 +505,10 @@ class MultiBandRasterLayer(RasterLayer):
renderer=QgsMultiBandColorRenderer(self.layer.dataProvider(),self.style_info['r'],self.style_info['g'],self.style_info['b'])
self.layer.setRenderer(renderer)
self.layer.triggerRepaint()
# @property
# def info(self):
# mapinfo=super().info
# mapinfo['渲染属性']['波段']='单波段'
class SingleBandRasterLayer(RasterLayer):
def apply_style(self):
@ -464,7 +521,7 @@ class VectorLayer(BasicLayer):
class ResultPointLayer(BasicLayer):
def __init__(self, path, name=None, enable = False, proj = None, geo = None,result_path={},dsort=False ):
def __init__(self, path, name=None, enable = False, proj = None, geo = None,result_path={},dsort=False):
if name is None:
name = os.path.splitext(os.path.basename(path))[0]
super().__init__(name, enable, icon=IconInstance().VECTOR, path=path, path_mode = BasicLayer.IN_FILE, view_mode=BasicLayer.BOATH_VIEW )
@ -472,8 +529,8 @@ class ResultPointLayer(BasicLayer):
self.wkt = proj
self.geo = geo
self.dsort=dsort
self.result_path=result_path
self.result_path:dict=result_path
# self.methods=
self.load_point_file()
def save(self):
@ -620,8 +677,23 @@ class ResultPointLayer(BasicLayer):
return actions
# def load_file(self, path):
@property
def info(self):
#基础属性
basic={}
basic['文件路径']=self.path
#中间算法信息:
methods={ k:v[0] for k ,v in self.result_path.items()}
basic['变化检测算法']=methods
#渲染信息
render={}
render['标注字体大小']=2
render['标注颜色']='#ffff00'
render['阈值']=self.result_path['后处理'][1]
return {'基础属性':basic,'渲染属性':render}
class PairLayer(BasicLayer):
def __init__(self, pth1, pth2,style_info1,style_info2) -> None:
@ -695,7 +767,41 @@ class PairLayer(BasicLayer):
)
return data
@property
def info(self):
ds= gdal.Open(self.main_l1.path)
srs= osr.SpatialReference(ds.GetProjectionRef())
metadata={}
# 空间参考系统
metadata['proj4'] = srs.ExportToProj4()
metadata['wkt'] = srs.ExportToWkt()
# 地理坐标系
metadata['geocs'] = srs.GetAttrValue('GEOGCS')
metadata['uom'] = srs.GetAttrValue('UNIT')
# 投影坐标系
metadata['projcs'] = srs.GetAttrValue('PROJCS') # if projected
metadata['epsg'] = srs.GetAuthorityCode(None)
ds=None
#格网信息
gridData={}
gridData['格网大小']='{}像素'.format(self.grid.cell_size)
gridData['格网线']=['宽度1像素', '颜色:白色']
#公共掩模
maskData={}
mapinfo={
'坐标系':metadata,
'格网':gridData,
'公共掩膜':maskData
}
return mapinfo
@staticmethod
def from_dict(data):
player = PairLayer(data['pth1'], data['pth2'], data['style_info1'], data['style_info2'])