fixbug;remove bug

This commit is contained in:
copper 2023-04-17 13:05:10 +08:00
parent 1e32f960db
commit 08550bd746
24 changed files with 1174 additions and 183 deletions

6
.gitignore vendored
View File

@ -222,7 +222,11 @@ share
nuitka.help
log.txt
logs/
*.7z
*.zip*
*.tar.gz
install/
!plugins/unsupervised_method/scripts/*.pyd
!plugins/*/scripts/*.pyd

View File

@ -1,52 +0,0 @@
# 变化检测
王铜
CVEO团队
# 环境
Python3.7 + PyQt + QGIS
## 配置方式
```
conda create -f conda.yaml
```
```
conda env create -n cevo_qt -f conda.yaml
```
# 打包方式
1. 打包keygen:
```
nuitka keygen.py --standalone --plugin-enable=qt-plugins --plugin-enable=numpy --show-progress --include-package=qgis --plugin-enable=pylint-warnings --output-dir=package --windows-disable-console --windows-icon-from-ico=logo.ico --no-pyi-file
```
2. 打包主体:
```
nuitka RSCDer.py --standalone --plugin-enable=qt-plugins --plugin-enable=numpy --show-progress --include-package=qgis --plugin-enable=pylint-warnings --output-dir=package --windows-disable-console --windows-icon-from-ico=logo.ico --no-pyi-file
```
3. 打包插件:
```
python setup.py
```
# 功能
1. 证书检查与生成
1. 基于MAC地址与过期时间进行证书生成启动时检查证书过期则退出
2. 工程管理
1. 以工程为单位进行数据管理与生产
2. 提供工程保存与导入功能
3. 提供多种格式的栅格数据导入TIF、PNG、BMP、JPG
4. 提供矢量数据导入
3. 基本工具
1. 双视图同步浏览
2. 格网展示

View File

@ -1,11 +0,0 @@
nuitka ECD.py --standalone --plugin-enable=pyqt5 --include-qt-plugins=sensible,styles --plugin-enable=numpy --nofollow-import-to=cv2 --nofollow-import-to=scipy --nofollow-import-to=yaml --nofollow-import-to=matplotlib --nofollow-import-to=PIL --nofollow-import-to=skimage --nofollow-import-to=numpy --nofollow-import-to=osgeo --nofollow-import-to=cryptography --nofollow-import-to=brotli --nofollow-import-to=cffi --show-progress --include-package=qgis --include-package=distutils --output-dir=package --windows-icon-from-ico=logo.ico --windows-disable-console
@REM nuitka ECD.py --standalone --plugin-enable=pyqt5 --include-qt-plugins=sensible,styles --plugin-enable=numpy --plugin-enable=anti-bloat --show-progress --include-package=qgis --output-dir=package --windows-icon-from-ico=logo.ico
@REM nuitka keygen.py --standalone --plugin-enable=qt-plugins --plugin-enable=numpy --show-progress --plugin-enable=pylint-warnings --output-dir=package --windows-disable-console --windows-icon-from-ico=logo.ico --no-pyi-file
REM Win7 with console
REM nuitka gui.py --mingw64 --standalone --plugin-enable=qt-plugins --plugin-enable=numpy --recurse-all --show-progress --include-package=qgis --output-dir=package --windows-icon=icons/logo.ico
REM Win7
@REM nuitka gui.py --mingw64 --standalone --plugin-enable=qt-plugins --plugin-enable=numpy --recurse-all --show-progress --include-package=qgis --output-dir=package --windows-disable-console --windows-icon=icons/logo.ico

View File

@ -1,23 +0,0 @@
name: cveo_ss
channels:
- conda-forge
- defaults
dependencies:
- cryptography=3.4.7
- gdal=3.3
- pyqt=5.12.3
- pyqtads=3.8.2
- python=3.7.10
- python=3.7
- qgis=3.18.3
- scikit-image
- scipy
- pip:
- attrs==21.4.0
- cython==0.29.24
- nuitka==0.8.3
- opencv-python==4.5.3.56
- pillow==6.2.2
- pycryptodome==3.14.1
- scikit-learn==1.0.2
- sklearn==0.0

View File

@ -1 +0,0 @@
IieXktda+1nRK9zLwe87uPPn2VpCwmUrEOPfyenaW/Sek70/CqqbCr7nangL1+pVXSkzDELia7Qq8e+pDMuHCXzxyJOALRj4j3bhFVExwqSTLuXwdev1e26nr7vnECl7H0SCVynr8To7ciwcnmK6HJXre6i+mBdTjACmKseTMlWp480XOt7uHysltORbTA3J

View File

@ -1 +0,0 @@
vd4FiYncytyziGH9GNCAA8hGGr1/79Xmphtc5+PHPJDpxvqj1hP7+985QMojYO4M5Qn/aqEAvFgeDN3CA8x1YAK8SdCgSXSBJpRBK8wqPQjBY1ak96QfdPCrTLunr+xuPxK3Gxe772adTTsee2+ot7WePYUsC4y4NcS5+rlP1if87xtYqVeSwx3c64cOmAGP

View File

@ -6,6 +6,8 @@ from rscder.plugins.basic import BasicPlugin
from PyQt5.QtWidgets import QDialog, QHBoxLayout, QFileDialog, QComboBox, QVBoxLayout, QPushButton, QLabel, QLineEdit, QAction
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import Qt
from osgeo import gdal, gdal_array
import numpy as np
class ExportDialog(QDialog):
TXT='*.txt'
@ -90,8 +92,12 @@ class ExportPlugin(BasicPlugin):
self.export_bin = QAction(IconInstance().DOCUMENT, '导出栅格二值变化检测结果')
self.export_bin.triggered.connect(self.export_bin_action)
self.export_rgb = QAction(IconInstance().DOCUMENT, '导出变化幅度渲染结果')
self.export_rgb.triggered.connect(self.export_rgb_action)
ActionManager().export_menu.addAction(self.export_txt)
ActionManager().export_menu.addAction(self.export_bin)
ActionManager().export_menu.addAction(self.export_rgb)
# self.ctx['toolbar'].addAction(self.export_txt)
@ -111,4 +117,82 @@ class ExportPlugin(BasicPlugin):
out = dialog.out_path
if result:
shutil.copy(result.path, out)
self.message_box.info('导出成功')
self.message_box.info('导出成功')
def export_rgb_action(self):
dialog = ExportDialog(self.mainwindow, ExportDialog.TIF)
btn = QPushButton('选择样式文件')
style_path = ''
def select_style():
select_file = QFileDialog.getOpenFileName(self, '选择样式文件', '*.*')
if select_file[0]:
# style_path.setText(select_file[0])
style_path = select_file[0]
btn.setText(select_file[0])
btn.clicked.connect(select_style)
dialog.layout().addWidget(btn)
default_style = [
[0, 0, 255, 0],
[1, 255, 0, 0]
]
if style_path is '':
style = default_style
else:
style = np.loadtxt(style_path, comments='#', delimiter=',')
style = style.tolist()
if dialog.exec_():
result = dialog.result_layer.path
out = dialog.out_path
self.render(style, result, out)
def render(self, style:list, path, out):
data = gdal_array.LoadFile(path)
if len(data.shape) == 3:
data = data[..., 0]
def get_color(v):
first_color = []
second_color = []
first_value = 0
second_value = 1
for s in style:
if s[0] <= v:
first_value = s[0]
first_color = s[1:]
else:
second_value = s[0]
second_color = s[1:]
break
if second_value == -1:
return np.array(style[-1][1:])
first_dis = (v - first_value) / (second_value - first_value)
second_dis = (second_value - v) / (second_value - first_value)
first_color = np.array(first_color)
second_color = np.array(second_color)
color = first_color* first_dis + second_color * second_dis
return color
get_color = np.frompyfunc(get_color, nin=1, nout=1)
Y, X = data.shape
rgbs = get_color(data.reshape(-1,))
rgbs = np.stack(rgbs).reshape((Y, X, 3)).astype(np.uint8)
driver = gdal.GetDriverByName('GTiff')
# out_tif = os.path.join(Project().other_path, 'temp.tif')
out_ds = driver.Create(out, X, Y, 3, gdal.GDT_Byte)
ds = gdal.Open(path)
geo = ds.GetGeoTransform()
proj = ds.GetProjectionRef()
out_ds.SetGeoTransform(geo)
out_ds.SetProjection(proj)
for i in range(3):
out_ds.GetRasterBand(i+1).WriteArray(rgbs[..., i])
del out_ds

View File

@ -5,4 +5,7 @@ FILTER = Register('滤波处理算法')
from .mean_filter import MeanFilter
from filter_collection.main import *
from .morphology_filter import MorphologyFilter
from .bilater_filter import BilaterFilter
from .bilater_filter import BilaterFilter
from .lee_filter import LeeFilter
from .lms_filter import AdaptiveFilter
from .lmsnp_filter import AdaptiveNPFilter

View File

@ -0,0 +1,112 @@
from misc import AlgFrontend
from misc.utils import format_now
from osgeo import gdal, gdal_array
from skimage.filters import rank
from skimage.morphology import rectangle
from filter_collection import FILTER
from PyQt5.QtWidgets import QDialog, QAction
from PyQt5 import QtCore, QtGui, QtWidgets
from rscder.utils.project import PairLayer, Project, RasterLayer, ResultPointLayer
from rscder.utils.icons import IconInstance
import os
from datetime import datetime
from scipy.ndimage.filters import uniform_filter
from scipy.ndimage.measurements import variance
def lee_filter(img, size):
img_mean = uniform_filter(img, size)
img_sqr_mean = uniform_filter(img**2, size)
img_variance = img_sqr_mean - img_mean**2
overall_variance = variance(img)
img_weights = img_variance / (img_variance + overall_variance)
img_output = img_mean + img_weights * (img - img_mean)
return img_output
@FILTER.register
class LeeFilter(AlgFrontend):
@staticmethod
def get_name():
return 'Lee滤波'
@staticmethod
def get_icon():
return IconInstance().ARITHMETIC2
@staticmethod
def get_widget(parent=None):
widget = QtWidgets.QWidget(parent)
x_size_input = QtWidgets.QLineEdit(widget)
x_size_input.setText('3')
x_size_input.setValidator(QtGui.QIntValidator())
x_size_input.setObjectName('xinput')
y_size_input = QtWidgets.QLineEdit(widget)
y_size_input.setValidator(QtGui.QIntValidator())
y_size_input.setObjectName('yinput')
y_size_input.setText('3')
size_label = QtWidgets.QLabel(widget)
size_label.setText('窗口大小:')
time_label = QtWidgets.QLabel(widget)
time_label.setText('X')
hlayout1 = QtWidgets.QHBoxLayout()
hlayout1.addWidget(size_label)
hlayout1.addWidget(x_size_input)
hlayout1.addWidget(time_label)
hlayout1.addWidget(y_size_input)
widget.setLayout(hlayout1)
return widget
@staticmethod
def get_params(widget:QtWidgets.QWidget=None):
if widget is None:
return dict(x_size=3, y_size=3)
x_input = widget.findChild(QtWidgets.QLineEdit, 'xinput')
y_input = widget.findChild(QtWidgets.QLineEdit, 'yinput')
if x_input is None or y_input is None:
return dict(x_size=3, y_size=3)
x_size = int(x_input.text())
y_size = int(y_input.text())
return dict(x_size=x_size, y_size=y_size)
@staticmethod
def run_alg(pth, x_size, y_size, *args, **kargs):
x_size = int(x_size)
y_size = int(y_size)
# pth = layer.path
if pth is None:
return
ds = gdal.Open(pth)
band_count = ds.RasterCount
name = os.path.splitext(os.path.basename(pth))[0]
out_path = os.path.join(Project().other_path, '{}_{}_{}.tif'.format(name, LeeFilter.get_name(), format_now()))
out_ds = gdal.GetDriverByName('GTiff').Create(out_path, ds.RasterXSize, ds.RasterYSize, band_count, ds.GetRasterBand(1).DataType)
out_ds.SetProjection(ds.GetProjection())
out_ds.SetGeoTransform(ds.GetGeoTransform())
for i in range(band_count):
band = ds.GetRasterBand(i+1)
data = band.ReadAsArray()
data = lee_filter(data, (y_size, x_size))
out_band = out_ds.GetRasterBand(i+1)
out_band.WriteArray(data)
out_ds.FlushCache()
del out_ds
del ds
return out_path

View File

@ -0,0 +1,140 @@
from misc import AlgFrontend
from misc.utils import format_now
from osgeo import gdal, gdal_array
from skimage.filters import rank
from skimage.morphology import rectangle
from filter_collection import FILTER
from PyQt5.QtWidgets import QDialog, QAction
from PyQt5 import QtCore, QtGui, QtWidgets
from rscder.utils.project import PairLayer, Project, RasterLayer, ResultPointLayer
from rscder.utils.icons import IconInstance
import os
from datetime import datetime
import numpy as np
import torch
import torch.nn.functional as F
def adaptiveMedianDeNoise(count, original):
# 初始窗口大小
startWindow = 3
# 卷积范围
c = count // 2
rows, cols = original.shape
newI = np.zeros(original.shape)
# median =
for i in range(c, rows - c):
for j in range(c, cols - c):
k = int(startWindow / 2)
median = np.median(original[i - k:i + k + 1, j - k:j + k + 1])
mi = np.min(original[i - k:i + k + 1, j - k:j + k + 1])
ma = np.max(original[i - k:i + k + 1, j - k:j + k + 1])
if mi < median < ma:
if mi < original[i, j] < ma:
newI[i, j] = original[i, j]
else:
newI[i, j] = median
else:
while True:
startWindow = startWindow + 2
k = int(startWindow / 2)
median = np.median(original[i - k:i + k + 1, j - k:j + k + 1])
mi = np.min(original[i - k:i + k + 1, j - k:j + k + 1])
ma = np.max(original[i - k:i + k + 1, j - k:j + k + 1])
if mi < median < ma or startWindow > count:
break
if mi < median < ma or startWindow > count:
if mi < original[i, j] < ma:
newI[i, j] = original[i, j]
else:
newI[i, j] = median
return newI
@FILTER.register
class AdaptiveFilter(AlgFrontend):
@staticmethod
def get_name():
return '自适应滤波'
@staticmethod
def get_icon():
return IconInstance().ARITHMETIC2
@staticmethod
def get_widget(parent=None):
widget = QtWidgets.QWidget(parent)
x_size_input = QtWidgets.QLineEdit(widget)
x_size_input.setText('3')
x_size_input.setValidator(QtGui.QIntValidator())
x_size_input.setObjectName('xinput')
# y_size_input = QtWidgets.QLineEdit(widget)
# y_size_input.setValidator(QtGui.QIntValidator())
# y_size_input.setObjectName('yinput')
# y_size_input.setText('3')
size_label = QtWidgets.QLabel(widget)
size_label.setText('窗口大小:')
# time_label = QtWidgets.QLabel(widget)
# time_label.setText('X')
hlayout1 = QtWidgets.QHBoxLayout()
hlayout1.addWidget(size_label)
hlayout1.addWidget(x_size_input)
# hlayout1.addWidget(time_label)
# hlayout1.addWidget(y_size_input)
widget.setLayout(hlayout1)
return widget
@staticmethod
def get_params(widget:QtWidgets.QWidget=None):
if widget is None:
return dict(x_size=3)
x_input = widget.findChild(QtWidgets.QLineEdit, 'xinput')
# y_input = widget.findChild(QtWidgets.QLineEdit, 'yinput')
if x_input is None:
return dict(x_size=3)
x_size = int(x_input.text())
# y_size = int(y_input.text())
return dict(x_size=x_size)
@staticmethod
def run_alg(pth, x_size, *args, **kargs):
x_size = int(x_size)
# y_size = int(y_size)
# pth = layer.path
if pth is None:
return
ds = gdal.Open(pth)
band_count = ds.RasterCount
name = os.path.splitext(os.path.basename(pth))[0]
out_path = os.path.join(Project().other_path, '{}_{}_{}.tif'.format(name, AdaptiveFilter.get_name(), format_now()))
out_ds = gdal.GetDriverByName('GTiff').Create(out_path, ds.RasterXSize, ds.RasterYSize, band_count, ds.GetRasterBand(1).DataType)
out_ds.SetProjection(ds.GetProjection())
out_ds.SetGeoTransform(ds.GetGeoTransform())
for i in range(band_count):
band = ds.GetRasterBand(i+1)
data = band.ReadAsArray()
data = adaptiveMedianDeNoise(x_size, data)
out_band = out_ds.GetRasterBand(i+1)
out_band.WriteArray(data)
out_ds.FlushCache()
del out_ds
del ds
return out_path

View File

@ -0,0 +1,128 @@
from misc import AlgFrontend
from misc.utils import format_now
from osgeo import gdal, gdal_array
from skimage.filters import rank
from skimage.morphology import rectangle
from filter_collection import FILTER
from PyQt5.QtWidgets import QDialog, QAction
from PyQt5 import QtCore, QtGui, QtWidgets
from rscder.utils.project import PairLayer, Project, RasterLayer, ResultPointLayer
from rscder.utils.icons import IconInstance
import os
from datetime import datetime
import numpy as np
import torch
import torch.nn.functional as F
def adaptiveMedianDeNoise(count, original):
# 初始窗口大小
startWindow = 3
# 卷积范围
c = count // 2
rows, cols = original.shape
newI = np.zeros(original.shape)
# median =
for i in range(c, rows - c):
for j in range(c, cols - c):
k = int(startWindow / 2)
median = np.median(original[i - k:i + k + 1, j - k:j + k + 1])
mi = np.min(original[i - k:i + k + 1, j - k:j + k + 1])
ma = np.max(original[i - k:i + k + 1, j - k:j + k + 1])
if mi < median < ma:
if mi < original[i, j] < ma:
newI[i, j] = original[i, j]
else:
newI[i, j] = median
else:
while True:
startWindow = startWindow + 2
k = int(startWindow / 2)
median = np.median(original[i - k:i + k + 1, j - k:j + k + 1])
mi = np.min(original[i - k:i + k + 1, j - k:j + k + 1])
ma = np.max(original[i - k:i + k + 1, j - k:j + k + 1])
if mi < median < ma or startWindow > count:
break
if mi < median < ma or startWindow > count:
if mi < original[i, j] < ma:
newI[i, j] = original[i, j]
else:
newI[i, j] = median
return newI
@FILTER.register
class AdaptiveNPFilter(AlgFrontend):
@staticmethod
def get_name():
return '自动滤波(无参自适应滤波)'
@staticmethod
def get_icon():
return IconInstance().ARITHMETIC2
@staticmethod
def get_widget(parent=None):
# widget = QtWidgets.QWidget(parent)
# x_size_input = QtWidgets.QLineEdit(widget)
# x_size_input.setText('3')
# x_size_input.setValidator(QtGui.QIntValidator())
# x_size_input.setObjectName('xinput')
# # y_size_input = QtWidgets.QLineEdit(widget)
# # y_size_input.setValidator(QtGui.QIntValidator())
# # y_size_input.setObjectName('yinput')
# # y_size_input.setText('3')
# size_label = QtWidgets.QLabel(widget)
# size_label.setText('窗口大小:')
# # time_label = QtWidgets.QLabel(widget)
# # time_label.setText('X')
# hlayout1 = QtWidgets.QHBoxLayout()
# hlayout1.addWidget(size_label)
# hlayout1.addWidget(x_size_input)
# # hlayout1.addWidget(time_label)
# # hlayout1.addWidget(y_size_input)
# widget.setLayout(hlayout1)
return None
@staticmethod
def get_params(widget:QtWidgets.QWidget=None):
return dict()
@staticmethod
def run_alg(pth, x_size, *args, **kargs):
# x_size = int(x_size)
# y_size = int(y_size)
# pth = layer.path
if pth is None:
return
ds = gdal.Open(pth)
band_count = ds.RasterCount
name = os.path.splitext(os.path.basename(pth))[0]
out_path = os.path.join(Project().other_path, '{}_{}_{}.tif'.format(name, AdaptiveNPFilter.get_name(), format_now()))
out_ds = gdal.GetDriverByName('GTiff').Create(out_path, ds.RasterXSize, ds.RasterYSize, band_count, ds.GetRasterBand(1).DataType)
out_ds.SetProjection(ds.GetProjection())
out_ds.SetGeoTransform(ds.GetGeoTransform())
for i in range(band_count):
band = ds.GetRasterBand(i+1)
data = band.ReadAsArray()
data = adaptiveMedianDeNoise(5, data)
out_band = out_ds.GetRasterBand(i+1)
out_band.WriteArray(data)
out_ds.FlushCache()
del out_ds
del ds
return out_path

View File

@ -164,6 +164,132 @@ class BasicCD(AlgFrontend):
return out_normal_tif
@UNSUPER_CD.register
class LogCD(AlgFrontend):
@staticmethod
def get_name():
return '对数比值法'
@staticmethod
def get_icon():
return IconInstance().ARITHMETIC3
@staticmethod
def run_alg(pth1: str, pth2: str, layer_parent: PairLayer, send_message=None, *args, **kargs):
ds1: gdal.Dataset = gdal.Open(pth1)
ds2: gdal.Dataset = gdal.Open(pth2)
cell_size = layer_parent.cell_size
xsize = layer_parent.size[0]
ysize = layer_parent.size[1]
band = ds1.RasterCount
yblocks = ysize // cell_size[1]
driver = gdal.GetDriverByName('GTiff')
out_tif = os.path.join(Project().other_path, 'temp.tif')
out_ds = driver.Create(out_tif, xsize, ysize, 1, gdal.GDT_Float32)
geo = layer_parent.grid.geo
proj = layer_parent.grid.proj
out_ds.SetGeoTransform(geo)
out_ds.SetProjection(proj)
max_diff = 0
min_diff = math.inf
start1x, start1y = geo2imageRC(ds1.GetGeoTransform(
), layer_parent.mask.xy[0], layer_parent.mask.xy[1])
end1x, end1y = geo2imageRC(ds1.GetGeoTransform(
), layer_parent.mask.xy[2], layer_parent.mask.xy[3])
start2x, start2y = geo2imageRC(ds2.GetGeoTransform(
), layer_parent.mask.xy[0], layer_parent.mask.xy[1])
end2x, end2y = geo2imageRC(ds2.GetGeoTransform(
), layer_parent.mask.xy[2], layer_parent.mask.xy[3])
for j in range(yblocks + 1): # 该改这里了
if send_message is not None:
send_message.emit(f'计算{j}/{yblocks}')
block_xy1 = (start1x, start1y+j * cell_size[1])
block_xy2 = (start2x, start2y+j*cell_size[1])
block_xy = (0, j * cell_size[1])
if block_xy1[1] > end1y or block_xy2[1] > end2y:
break
block_size = (xsize, cell_size[1])
block_size1 = (xsize, cell_size[1])
block_size2 = (xsize, cell_size[1])
if block_xy[1] + block_size[1] > ysize:
block_size = (xsize, ysize - block_xy[1])
if block_xy1[1] + block_size1[1] > end1y:
block_size1 = (xsize, end1y - block_xy1[1])
if block_xy2[1] + block_size2[1] > end2y:
block_size2 = (xsize, end2y - block_xy2[1])
if block_size1[0] * block_size1[1] == 0 or block_size2[0] * block_size2[1] == 0:
continue
block_data1 = ds1.ReadAsArray(*block_xy1, *block_size1)
block_data2 = ds2.ReadAsArray(*block_xy2, *block_size2)
# if block_data1.shape[0] == 0:
# continue
if band == 1:
block_data1 = block_data1[None, ...]
block_data2 = block_data2[None, ...]
# pdb.set_trace()
block_diff = np.log( block_data1.sum(0) / (block_data2.sum(0) + 1e-6 ) )
block_diff = block_diff.astype(np.float32)
block_diff = np.abs(block_diff)
min_diff = min(min_diff, block_diff[block_diff >= 0].min())
max_diff = max(max_diff, block_diff.max())
out_ds.GetRasterBand(1).WriteArray(block_diff, *block_xy)
if send_message is not None:
send_message.emit(f'完成{j}/{yblocks}')
del ds2
del ds1
out_ds.FlushCache()
del out_ds
if send_message is not None:
send_message.emit('归一化概率中...')
temp_in_ds = gdal.Open(out_tif)
out_normal_tif = os.path.join(Project().cmi_path, '{}_{}_cmi.tif'.format(
layer_parent.name, int(np.random.rand() * 100000)))
out_normal_ds = driver.Create(
out_normal_tif, xsize, ysize, 1, gdal.GDT_Byte)
out_normal_ds.SetGeoTransform(geo)
out_normal_ds.SetProjection(proj)
# hist = np.zeros(256, dtype=np.int32)
for j in range(yblocks+1):
block_xy = (0, j * cell_size[1])
if block_xy[1] > ysize:
break
block_size = (xsize, cell_size[1])
if block_xy[1] + block_size[1] > ysize:
block_size = (xsize, ysize - block_xy[1])
block_data = temp_in_ds.ReadAsArray(*block_xy, *block_size)
block_data = (block_data - min_diff) / (max_diff - min_diff) * 255
block_data = block_data.astype(np.uint8)
out_normal_ds.GetRasterBand(1).WriteArray(block_data, *block_xy)
# hist_t, _ = np.histogram(block_data, bins=256, range=(0, 256))
# hist += hist_t
# print(hist)
del temp_in_ds
del out_normal_ds
try:
os.remove(out_tif)
except:
pass
if send_message is not None:
send_message.emit('计算完成')
return out_normal_tif
@UNSUPER_CD.register
class LSTS(AlgFrontend):
@ -444,7 +570,7 @@ class CVAAlg(AlgFrontend):
return out_normal_tif
@UNSUPER_CD.register
# @UNSUPER_CD.register
class ACDAlg(AlgFrontend):
@staticmethod
@ -524,6 +650,7 @@ class AHTAlg(AlgFrontend):
@staticmethod
def run_alg(pth1: str, pth2: str, layer_parent: PairLayer, send_message=None, *args, **kargs):
if send_message is None:
class Empty:
@ -559,11 +686,11 @@ class AHTAlg(AlgFrontend):
send_message.emit('图像一提取完成')
# 运算
send_message.emit('开始AHT计算.....')
send_message.emit('开始LHBA计算.....')
time.sleep(0.1)
out_normal_tif = os.path.join(Project().cmi_path, '{}_{}_cmi.tif'.format(
layer_parent.name, int(np.random.rand() * 100000)))
AHT(temp_tif1, temp_tif2, out_normal_tif)
LHBA(temp_tif1, temp_tif2, out_normal_tif)
# 添加投影
send_message.emit('录入投影信息.....')
time.sleep(0.1)
@ -571,11 +698,10 @@ class AHTAlg(AlgFrontend):
ds.SetGeoTransform(geo)
ds.SetProjection(proj)
del ds
return out_normal_tif
@UNSUPER_CD.register
# @UNSUPER_CD.register
class OCDAlg(AlgFrontend):
@staticmethod
@ -766,3 +892,234 @@ class SHAlg(AlgFrontend):
ds.SetProjection(proj)
del ds
return out_normal_tif
@UNSUPER_CD.register
class KPVDAlg(AlgFrontend):
@staticmethod
def get_name():
return 'KPVD'
@staticmethod
def get_icon():
return IconInstance().ARITHMETIC3
@staticmethod
def run_alg(pth1: str, pth2: str, layer_parent: PairLayer, send_message=None, *args, **kargs):
ds1: gdal.Dataset = gdal.Open(pth1)
ds2: gdal.Dataset = gdal.Open(pth2)
cell_size = layer_parent.cell_size
xsize = layer_parent.size[0]
ysize = layer_parent.size[1]
band = ds1.RasterCount
yblocks = ysize // cell_size[1]
driver = gdal.GetDriverByName('GTiff')
out_tif = os.path.join(Project().other_path, 'temp.tif')
out_ds = driver.Create(out_tif, xsize, ysize, 1, gdal.GDT_Float32)
geo = layer_parent.grid.geo
proj = layer_parent.grid.proj
out_ds.SetGeoTransform(geo)
out_ds.SetProjection(proj)
max_diff = 0
min_diff = math.inf
start1x, start1y = geo2imageRC(ds1.GetGeoTransform(
), layer_parent.mask.xy[0], layer_parent.mask.xy[1])
end1x, end1y = geo2imageRC(ds1.GetGeoTransform(
), layer_parent.mask.xy[2], layer_parent.mask.xy[3])
start2x, start2y = geo2imageRC(ds2.GetGeoTransform(
), layer_parent.mask.xy[0], layer_parent.mask.xy[1])
end2x, end2y = geo2imageRC(ds2.GetGeoTransform(
), layer_parent.mask.xy[2], layer_parent.mask.xy[3])
for j in range(yblocks + 1):
if send_message is not None:
send_message.emit(f'计算{j}/{yblocks}')
block_xy1 = (start1x, start1y+j * cell_size[1])
block_xy2 = (start2x, start2y+j*cell_size[1])
block_xy = (0, j * cell_size[1])
if block_xy1[1] > end1y or block_xy2[1] > end2y:
break
block_size = (xsize, cell_size[1])
block_size1 = (xsize, cell_size[1])
block_size2 = (xsize, cell_size[1])
if block_xy[1] + block_size[1] > ysize:
block_size = (xsize, ysize - block_xy[1])
if block_xy1[1] + block_size1[1] > end1y:
block_size1 = (xsize, end1y - block_xy1[1])
if block_xy2[1] + block_size2[1] > end2y:
block_size2 = (xsize, end2y - block_xy2[1])
block_data1 = ds1.ReadAsArray(*block_xy1, *block_size1)
block_data2 = ds2.ReadAsArray(*block_xy2, *block_size2)
if band == 1:
block_data1 = block_data1[None, ...]
block_data2 = block_data2[None, ...]
# pdb.set_trace()
block_diff = np.sum((block_data1-block_data2)**2, 0)**0.5
min_diff = min(min_diff, block_diff[block_diff > 0].min())
max_diff = max(max_diff, block_diff.max())
out_ds.GetRasterBand(1).WriteArray(block_diff, *block_xy)
if send_message is not None:
send_message.emit(f'完成{j}/{yblocks}')
del ds2
del ds1
out_ds.FlushCache()
del out_ds
if send_message is not None:
send_message.emit('归一化概率中...')
temp_in_ds = gdal.Open(out_tif)
out_normal_tif = os.path.join(Project().cmi_path, '{}_{}_cmi.tif'.format(
layer_parent.name, int(np.random.rand() * 100000)))
out_normal_ds = driver.Create(
out_normal_tif, xsize, ysize, 1, gdal.GDT_Byte)
out_normal_ds.SetGeoTransform(geo)
out_normal_ds.SetProjection(proj)
# hist = np.zeros(256, dtype=np.int32)
for j in range(yblocks+1):
block_xy = (0, j * cell_size[1])
if block_xy[1] > ysize:
break
block_size = (xsize, cell_size[1])
if block_xy[1] + block_size[1] > ysize:
block_size = (xsize, ysize - block_xy[1])
block_data = temp_in_ds.ReadAsArray(*block_xy, *block_size)
block_data = (block_data - min_diff) / (max_diff - min_diff) * 255
block_data = block_data.astype(np.uint8)
out_normal_ds.GetRasterBand(1).WriteArray(block_data, *block_xy)
# hist_t, _ = np.histogram(block_data, bins=256, range=(0, 256))
# hist += hist_t
# print(hist)
del temp_in_ds
del out_normal_ds
try:
os.remove(out_tif)
except:
pass
if send_message is not None:
send_message.emit('欧式距离计算完成')
return out_normal_tif
@UNSUPER_CD.register
class MOHDAlg(AlgFrontend):
@staticmethod
def get_name():
return 'MOHD'
@staticmethod
def get_icon():
return IconInstance().ARITHMETIC3
@staticmethod
def run_alg(pth1: str, pth2: str, layer_parent: PairLayer, send_message=None, *args, **kargs):
ds1: gdal.Dataset = gdal.Open(pth1)
ds2: gdal.Dataset = gdal.Open(pth2)
cell_size = layer_parent.cell_size
xsize = layer_parent.size[0]
ysize = layer_parent.size[1]
band = ds1.RasterCount
yblocks = ysize // cell_size[1]
driver = gdal.GetDriverByName('GTiff')
out_tif = os.path.join(Project().other_path, 'temp.tif')
out_ds = driver.Create(out_tif, xsize, ysize, 1, gdal.GDT_Float32)
geo = layer_parent.grid.geo
proj = layer_parent.grid.proj
out_ds.SetGeoTransform(geo)
out_ds.SetProjection(proj)
max_diff = 0
min_diff = math.inf
start1x, start1y = geo2imageRC(ds1.GetGeoTransform(
), layer_parent.mask.xy[0], layer_parent.mask.xy[1])
end1x, end1y = geo2imageRC(ds1.GetGeoTransform(
), layer_parent.mask.xy[2], layer_parent.mask.xy[3])
start2x, start2y = geo2imageRC(ds2.GetGeoTransform(
), layer_parent.mask.xy[0], layer_parent.mask.xy[1])
end2x, end2y = geo2imageRC(ds2.GetGeoTransform(
), layer_parent.mask.xy[2], layer_parent.mask.xy[3])
for j in range(yblocks + 1):
if send_message is not None:
send_message.emit(f'计算{j}/{yblocks}')
block_xy1 = (start1x, start1y+j * cell_size[1])
block_xy2 = (start2x, start2y+j*cell_size[1])
block_xy = (0, j * cell_size[1])
if block_xy1[1] > end1y or block_xy2[1] > end2y:
break
block_size = (xsize, cell_size[1])
block_size1 = (xsize, cell_size[1])
block_size2 = (xsize, cell_size[1])
if block_xy[1] + block_size[1] > ysize:
block_size = (xsize, ysize - block_xy[1])
if block_xy1[1] + block_size1[1] > end1y:
block_size1 = (xsize, end1y - block_xy1[1])
if block_xy2[1] + block_size2[1] > end2y:
block_size2 = (xsize, end2y - block_xy2[1])
block_data1 = ds1.ReadAsArray(*block_xy1, *block_size1)
block_data2 = ds2.ReadAsArray(*block_xy2, *block_size2)
if band == 1:
block_data1 = block_data1[None, ...]
block_data2 = block_data2[None, ...]
# pdb.set_trace()
block_diff = np.sum((block_data1-block_data2)**2, 0)**0.5
min_diff = min(min_diff, block_diff[block_diff > 0].min())
max_diff = max(max_diff, block_diff.max())
out_ds.GetRasterBand(1).WriteArray(block_diff, *block_xy)
if send_message is not None:
send_message.emit(f'完成{j}/{yblocks}')
del ds2
del ds1
out_ds.FlushCache()
del out_ds
if send_message is not None:
send_message.emit('归一化概率中...')
temp_in_ds = gdal.Open(out_tif)
out_normal_tif = os.path.join(Project().cmi_path, '{}_{}_cmi.tif'.format(
layer_parent.name, int(np.random.rand() * 100000)))
out_normal_ds = driver.Create(
out_normal_tif, xsize, ysize, 1, gdal.GDT_Byte)
out_normal_ds.SetGeoTransform(geo)
out_normal_ds.SetProjection(proj)
# hist = np.zeros(256, dtype=np.int32)
for j in range(yblocks+1):
block_xy = (0, j * cell_size[1])
if block_xy[1] > ysize:
break
block_size = (xsize, cell_size[1])
if block_xy[1] + block_size[1] > ysize:
block_size = (xsize, ysize - block_xy[1])
block_data = temp_in_ds.ReadAsArray(*block_xy, *block_size)
block_data = (block_data - min_diff) / (max_diff - min_diff) * 255
block_data = block_data.astype(np.uint8)
out_normal_ds.GetRasterBand(1).WriteArray(block_data, *block_xy)
# hist_t, _ = np.histogram(block_data, bins=256, range=(0, 256))
# hist += hist_t
# print(hist)
del temp_in_ds
del out_normal_ds
try:
os.remove(out_tif)
except:
pass
if send_message is not None:
send_message.emit('欧式距离计算完成')
return out_normal_tif

53
res.qrc
View File

@ -1,53 +0,0 @@
<RCC>
<qresource prefix="/">
<file>icons/AI变化检测.png</file>
<file>icons/使用帮助.png</file>
<file>icons/公路变化.png</file>
<file>icons/其他</file>
<file>icons/创建工程.png</file>
<file>icons/删除.png</file>
<file>icons/办学评估.png</file>
<file>icons/单窗口.png</file>
<file>icons/去云.png</file>
<file>icons/双窗口.png</file>
<file>icons/噪声处理.png</file>
<file>icons/图像质量.png</file>
<file>icons/图像配准.png</file>
<file>icons/图层.png</file>
<file>icons/定位.png</file>
<file>icons/工具.png</file>
<file>icons/工具箱.png</file>
<file>icons/工程保存.png</file>
<file>icons/帮助 (1).png</file>
<file>icons/帮助.png</file>
<file>icons/平移.png</file>
<file>icons/弱监督.png</file>
<file>icons/影像.png</file>
<file>icons/打开工程.png</file>
<file>icons/插件配置 (1).png</file>
<file>icons/插件配置-展开.png</file>
<file>icons/插件配置-收起.png</file>
<file>icons/插件配置.png</file>
<file>icons/数据加载.png</file>
<file>icons/文件.png</file>
<file>icons/文档.png</file>
<file>icons/植被变化.bmp</file>
<file>icons/水体变化.png</file>
<file>icons/海岸变化.png</file>
<file>icons/滑坡变化.png</file>
<file>icons/滤波.png</file>
<file>icons/田地变化.png</file>
<file>icons/界面定制.png</file>
<file>icons/监督.png</file>
<file>icons/矢量.png</file>
<file>icons/网格关闭.png</file>
<file>icons/网格开.png</file>
<file>icons/视图.png</file>
<file>icons/退出.png</file>
<file>icons/选择要素.png</file>
<file>icons/道路变化.png</file>
<file>icons/遥感.png</file>
<file>icons/铁路变化.png</file>
<file>icons/非监督.png</file>
</qresource>
</RCC>

118
result.txt Normal file
View File

@ -0,0 +1,118 @@
x,y,diff,status
234053.9937022142,3530980.0747939292,80.47999999999999,1
234153.9937022142,3530980.0747939292,76.88000000000001,1
234253.9937022142,3530980.0747939292,77.83,1
234353.9937022142,3530980.0747939292,81.65,1
234453.9937022142,3530980.0747939292,84.71,1
234553.9937022142,3530980.0747939292,79.03999999999999,1
234653.9937022142,3530980.0747939292,74.18,1
234753.9937022142,3530980.0747939292,76.0,1
234853.9937022142,3530980.0747939292,85.37,1
234953.9937022142,3530980.0747939292,73.00999999999999,1
235053.9937022142,3530980.0747939292,52.32,1
235153.9937022142,3530980.0747939292,86.32,1
235253.9937022142,3530980.0747939292,84.875,1
234053.9937022142,3530880.0747939292,79.83,1
234153.9937022142,3530880.0747939292,84.71,1
234253.9937022142,3530880.0747939292,78.86999999999999,1
234353.9937022142,3530880.0747939292,79.36999999999999,1
234453.9937022142,3530880.0747939292,80.62,1
234553.9937022142,3530880.0747939292,81.55,1
234653.9937022142,3530880.0747939292,73.83,1
234753.9937022142,3530880.0747939292,78.67,1
234853.9937022142,3530880.0747939292,71.81,1
234953.9937022142,3530880.0747939292,75.89,1
235053.9937022142,3530880.0747939292,59.660000000000004,1
235153.9937022142,3530880.0747939292,80.33,1
235253.9937022142,3530880.0747939292,82.5,1
234053.9937022142,3530780.0747939292,80.27,1
234153.9937022142,3530780.0747939292,81.04,1
234253.9937022142,3530780.0747939292,78.48,1
234353.9937022142,3530780.0747939292,84.17999999999999,1
234453.9937022142,3530780.0747939292,91.45,1
234553.9937022142,3530780.0747939292,81.96,1
234653.9937022142,3530780.0747939292,74.38,1
234753.9937022142,3530780.0747939292,74.42999999999999,1
234853.9937022142,3530780.0747939292,68.12,1
234953.9937022142,3530780.0747939292,73.22999999999999,1
235053.9937022142,3530780.0747939292,56.28999999999999,1
235153.9937022142,3530780.0747939292,75.52,1
235253.9937022142,3530780.0747939292,74.55000000000001,1
234053.9937022142,3530680.0747939292,78.72,1
234153.9937022142,3530680.0747939292,77.56,1
234253.9937022142,3530680.0747939292,73.77,1
234353.9937022142,3530680.0747939292,77.64999999999999,1
234453.9937022142,3530680.0747939292,86.4,1
234553.9937022142,3530680.0747939292,80.36,1
234653.9937022142,3530680.0747939292,70.63000000000001,1
234753.9937022142,3530680.0747939292,77.24,1
234853.9937022142,3530680.0747939292,61.29,1
234953.9937022142,3530680.0747939292,54.230000000000004,1
235053.9937022142,3530680.0747939292,50.22,1
235153.9937022142,3530680.0747939292,71.95,1
235253.9937022142,3530680.0747939292,76.75,1
234053.9937022142,3530580.0747939292,78.06,1
234153.9937022142,3530580.0747939292,83.17,1
234253.9937022142,3530580.0747939292,83.14,1
234353.9937022142,3530580.0747939292,84.32,1
234453.9937022142,3530580.0747939292,62.23,1
234553.9937022142,3530580.0747939292,84.72,1
234653.9937022142,3530580.0747939292,86.11999999999999,1
234753.9937022142,3530580.0747939292,81.85,1
234853.9937022142,3530580.0747939292,70.58,1
234953.9937022142,3530580.0747939292,50.63999999999999,1
235053.9937022142,3530580.0747939292,63.17,1
235153.9937022142,3530580.0747939292,76.55,1
235253.9937022142,3530580.0747939292,74.225,1
234053.9937022142,3530480.0747939292,78.14,1
234153.9937022142,3530480.0747939292,77.41,1
234253.9937022142,3530480.0747939292,78.31,1
234353.9937022142,3530480.0747939292,78.0,1
234453.9937022142,3530480.0747939292,82.67,1
234553.9937022142,3530480.0747939292,89.29,1
234653.9937022142,3530480.0747939292,73.53,1
234753.9937022142,3530480.0747939292,82.24000000000001,1
234853.9937022142,3530480.0747939292,81.16,1
234953.9937022142,3530480.0747939292,73.44000000000001,1
235053.9937022142,3530480.0747939292,74.52,1
235153.9937022142,3530480.0747939292,71.52,1
235253.9937022142,3530480.0747939292,89.85,1
234053.9937022142,3530380.0747939292,79.36,1
234153.9937022142,3530380.0747939292,78.77,1
234253.9937022142,3530380.0747939292,72.13000000000001,1
234353.9937022142,3530380.0747939292,77.56,1
234453.9937022142,3530380.0747939292,74.67,1
234553.9937022142,3530380.0747939292,84.54,1
234653.9937022142,3530380.0747939292,89.53,1
234753.9937022142,3530380.0747939292,85.99,1
234853.9937022142,3530380.0747939292,87.22999999999999,1
234953.9937022142,3530380.0747939292,85.53,1
235053.9937022142,3530380.0747939292,75.82,1
235153.9937022142,3530380.0747939292,66.47999999999999,1
235253.9937022142,3530380.0747939292,67.55,1
234053.9937022142,3530280.0747939292,80.64,1
234153.9937022142,3530280.0747939292,81.23,1
234253.9937022142,3530280.0747939292,76.6,1
234353.9937022142,3530280.0747939292,93.39,1
234453.9937022142,3530280.0747939292,85.55,1
234553.9937022142,3530280.0747939292,90.69,1
234653.9937022142,3530280.0747939292,87.16000000000001,1
234753.9937022142,3530280.0747939292,87.01,1
234853.9937022142,3530280.0747939292,90.9,1
234953.9937022142,3530280.0747939292,86.92999999999999,1
235053.9937022142,3530280.0747939292,67.22,1
235153.9937022142,3530280.0747939292,63.77,1
235253.9937022142,3530280.0747939292,78.475,1
234053.9937022142,3530180.0747939292,76.86111111111111,1
234153.9937022142,3530180.0747939292,79.76388888888889,1
234253.9937022142,3530180.0747939292,80.15277777777777,1
234353.9937022142,3530180.0747939292,91.45833333333333,1
234453.9937022142,3530180.0747939292,82.05555555555556,1
234553.9937022142,3530180.0747939292,94.15277777777777,1
234653.9937022142,3530180.0747939292,82.72222222222221,1
234753.9937022142,3530180.0747939292,89.11111111111111,1
234853.9937022142,3530180.0747939292,91.41666666666667,1
234953.9937022142,3530180.0747939292,87.58333333333333,1
235053.9937022142,3530180.0747939292,64.54166666666666,1
235153.9937022142,3530180.0747939292,56.40277777777778,1
235253.9937022142,3530180.0747939292,64.86111111111111,1

View File

@ -1,19 +1,26 @@
import os
import sys
# sys.path.insert(0, os.path.dirname(__file__))
# sys.path.insert(0, os.path.join('..', os.path.dirname(__file__), 'libs'))
# os.environ['PROJ_LIB'] = os.path.join(os.path.dirname(__file__), 'share/proj')
# os.environ['GDAL_DATA'] = os.path.join(os.path.dirname(__file__), 'share')
os.environ['ECD_BASEDIR'] = os.path.join( os.path.dirname(__file__), '..')
BASE_DIR = os.path.join( os.path.dirname(__file__), '..')
# import ctypes
from .mul.mulstart import MulStart
# ctypes.windll.LoadLibrary()
from rscder.mul.mulstart import MulStart
import logging
from plugins.misc import format_now
os.makedirs(os.path.join(BASE_DIR, 'logs'), exist_ok=True)
logging.basicConfig(level=logging.INFO, filename=os.path.join(BASE_DIR, 'logs', format_now() + '_log.txt'), filemode='a', format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
def main():
# print(sys.path)
t = MulStart()
t.run()

View File

@ -13,6 +13,8 @@ from rscder.gui.plugins import PluginDialog
from rscder.utils.setting import Settings
from rscder.gui.load import loader
from functools import partial
from rscder.gui.guicfg import GUICfg
from rscder.gui.location import Location
def get_action_manager() -> 'ActionManager':
return ActionManager()
@ -66,7 +68,7 @@ class ActionManager(QtCore.QObject):
self.road_menu = self.special_chagne_detec_menu.addMenu(IconInstance().ROAD_CHANGE,'&道路变化检测')
self.landslide_menu = self.special_chagne_detec_menu.addMenu(IconInstance().LANDSIDE,'&滑坡变化检测')
self.seg_chagne_detec_menu = menubar.addMenu('&分类后变化检测')
# self.seg_chagne_detec_menu = menubar.addMenu('&分类后变化检测')
self.postop_menu = menubar.addMenu( '&检测后处理')
# self.noise_menu = self.postop_menu.addMenu(IconInstance().NOISE,'&噪声处理')
@ -165,6 +167,7 @@ class ActionManager(QtCore.QObject):
pan = self.add_action(QAction(IconInstance().PAN,'&漫游', self.w_parent), 'Basic')
locate = self.add_action(QAction(IconInstance().ZOOM_TO,'&定位', self.w_parent), 'Basic')
locate.triggered.connect(self.locate)
pan.setCheckable(True)
pan.setChecked(True)
zomm_out.setCheckable(True)
@ -253,6 +256,12 @@ class ActionManager(QtCore.QObject):
self.message_box.info('工程初始化完成')
def locate(self):
loc = Location(self.w_parent)
loc.show()
loc.extent.connect(self.double_map.zoom_to_extent)
def project_open(self):
if Project().is_init:
Project().save()
@ -278,7 +287,9 @@ class ActionManager(QtCore.QObject):
self.message_box.info('Data loaded')
def view_setting(self):
pass
g = GUICfg(self.w_parent)
g.show()
def add_action(self, action, group=None):

39
rscder/gui/guicfg.py Normal file
View File

@ -0,0 +1,39 @@
from PyQt5.QtWidgets import QDialog, QFormLayout, QLineEdit, QCheckBox, QVBoxLayout, QHBoxLayout, QLabel, QPushButton, QTextEdit, QFileDialog, QMessageBox
from PyQt5 import QtCore, QtGui
from PyQt5.QtGui import QIcon
from rscder.utils.icons import IconInstance
from rscder.utils.setting import Settings
class GUICfg(QDialog):
def __init__(self, parent = None, flags = QtCore.Qt.WindowFlags() ) -> None:
super().__init__(parent, flags)
self.setWindowTitle("界面定制")
self.setWindowIcon(IconInstance(parent).LOGO)
form_layout = QFormLayout(self)
default_size_label = QLabel('默认格网')
default_size = QLineEdit()
default_size.setValidator(QtGui.QIntValidator(1, 1000))
def set_defaultsize():
Settings.General().size = (int(default_size.text()), int(default_size.text()))
# form_layout.addRow
default_size.textChanged.connect( set_defaultsize )
form_layout.addRow(default_size_label, default_size)
self.setLayout(form_layout)
auto_save_label = QLabel('自动保存')
auto_save = QCheckBox()
auto_save.setChecked(Settings.General().auto_save)
def set_autosave():
Settings.General().auto_save = auto_save.isChecked()
auto_save.stateChanged.connect(set_autosave)
form_layout.addRow(auto_save_label, auto_save)

67
rscder/gui/location.py Normal file
View File

@ -0,0 +1,67 @@
from PyQt5.QtWidgets import QDialog, QFormLayout, QLineEdit, QCheckBox, QVBoxLayout, QHBoxLayout, QLabel, QPushButton, QTextEdit, QFileDialog, QMessageBox
from PyQt5 import QtCore, QtGui
from PyQt5.QtGui import QIcon
from rscder.utils.icons import IconInstance
from rscder.utils.setting import Settings
from rscder.utils.project import Project
from qgis.core import QgsRectangle
class Location(QDialog):
extent = QtCore.pyqtSignal(object)
def __init__(self, parent = None, flags = QtCore.Qt.WindowFlags() ) -> None:
super().__init__(parent, flags)
self.setWindowTitle("定位")
self.setWindowIcon(IconInstance(parent).LOGO)
X_label = QLabel('X:')
Y_label = QLabel('Y:')
X = QLineEdit()
X.setValidator(QtGui.QDoubleValidator())
Y = QLineEdit()
Y.setValidator(QtGui.QDoubleValidator())
hlay = QHBoxLayout()
hlay.addWidget(X_label)
hlay.addWidget(X)
hlay.addWidget(Y_label)
hlay.addWidget(Y)
btns = QPushButton('确定')
hlay.addWidget(btns)
self.setLayout(hlay)
def loc():
x = float(X.text())
y = float(Y.text())
extent = QgsRectangle(x - 100, y - 100, x + 100, y + 100 )
self.extent.emit(extent)
btns.clicked.connect(loc)
# form_layout = QFormLayout(self)
# default_size_label = QLabel('默认格网')
# default_size = QLineEdit()
# default_size.setValidator(QtGui.QIntValidator(1, 1000))
# def set_defaultsize():
# Settings.General().size = (int(default_size.text()), int(default_size.text()))
# # form_layout.addRow
# default_size.textChanged.connect( set_defaultsize )
# form_layout.addRow(default_size_label, default_size)
# self.setLayout(form_layout)
# auto_save_label = QLabel('自动保存')
# auto_save = QCheckBox()
# auto_save.setChecked(Settings.General().auto_save)
# def set_autosave():
# Settings.General().auto_save = auto_save.isChecked()
# auto_save.stateChanged.connect(set_autosave)
# form_layout.addRow(auto_save_label, auto_save)

View File

@ -9,7 +9,8 @@ from rscder.gui.mainwindow import MainWindow
import multiprocessing
from rscder.gui import license
from rscder.utils.setting import Settings
import os
BASE_DIR = os.environ['ECD_BASEDIR']
class MulStart:
def __init__(self, **kargs) -> None:
@ -38,7 +39,7 @@ class MulStart:
else:
sys.exit(0)
# Create and display the splash screen
splash_pix = QPixmap("./icons/splash.png")
splash_pix = QPixmap(os.path.join(BASE_DIR, "./icons/splash.png"))
# splash_pix.scaledToWidth(800)
# splash_pix.scaledToHeight(600)

View File

@ -54,8 +54,8 @@ class IconInstance(QObject):
self.DATA_LOAD = QIcon(os.path.join(os.environ['ECD_BASEDIR'] , './icons/数据加载.png'))
self.EXCIT = QIcon(os.path.join(os.environ['ECD_BASEDIR'] , './icons/退出.png'))
self.ZOOM_IN = QIcon(os.path.join(os.environ['ECD_BASEDIR'] , './icons/放大.png'))
self.ZOOM_OUT = QIcon(os.path.join(os.environ['ECD_BASEDIR'] , './icons/缩小.png'))
self.ZOOM_OUT = QIcon(os.path.join(os.environ['ECD_BASEDIR'] , './icons/放大.png'))
self.ZOOM_IN = QIcon(os.path.join(os.environ['ECD_BASEDIR'] , './icons/缩小.png'))
self.TABLE = QIcon(os.path.join(os.environ['ECD_BASEDIR'] , './icons/table.png'))

View File

@ -1,18 +1,25 @@
from setuptools import setup, find_packages
# from __future__ import print_function
setup(
name='rscder',
version='1.0',
author='Wang Tong',
author_email='copper.w@foxmail.com',
description='RSCDER',
long_description=open('ReadMe.md', 'r'),
packages=find_packages(),
ext_package=[],
include_package_data=True,
# package_data={"opencv": ['opencv_ffmpeg3415_64.dll', 'opencv_world3415.dll']},
# data_files=[
# ('lib/site-packages', ['opencv_ffmpeg3415_64.dll', 'opencv_world3415.dll'])
# ],
entry_points=dict(
console_scripts=[
gui_scripts=[
'rscder = rscder.ECD:main',
'keygen = rscder.keygen:main'
]
)
)
)

36
test.py Normal file
View File

@ -0,0 +1,36 @@
import numpy as np
style = [
[0, 255, 0, 0],
[1, 0, 255, 0]
]
def get_color(v):
first_color = []
second_color = []
first_value = -1
second_value = -1
for s in style:
if s[0] <= v:
first_value = s[0]
first_color = s[1:]
else:
second_value = s[0]
second_color = s[1:]
break
if second_value == -1:
return np.array(style[-1][1:])
first_dis = (v - first_value) / (second_value - first_value)
second_dis = (second_value - v) / (second_value - first_value)
first_color = np.array(first_color)
second_color = np.array(second_color)
color = first_color* first_dis + second_color * second_dis
return color
get_color = np.frompyfunc(get_color, nin=1, nout=1)
value = np.array([0, 0.5, 0.7, 1])
print( np.stack(get_color(value)).reshape((2, 2, 3)))

View File

@ -1,24 +0,0 @@
1. lic文件生成
点击ECD.exe,复制所显示的mac地址
点击keygen.exe,粘贴mac地址设置截止日期并选择保存路径无需输入后缀名
点击Generate
2. lic文件导入
点击ECD.exe点击Open选择生成的lic文件
点击OK
3. 新建工程与数据导入
点击ECD.exe
点击新建工程
选择路径、名称
将会在路径下看到与名称相同的文件夹
点击载入数据
选择两幅不同时相的影像
4. 差分法检测
点击基本变化检测
点击差分法
选择图层
点击确定

42
安装方法.md Normal file
View File

@ -0,0 +1,42 @@
# 变化检测
王铜
CVEO团队
# 安装
1. 安装miniconda3/anaconda3
miniconda3安装包位于install\Miniconda3-py38_23.1.0-1-Windows-x86_64.exe
2. 打开cmd激活conda
3. 安装依赖
将install/opencvxxxx.dll复制到 `C:\Windows\System32`
4. 切换目录,安装环境
解压cveo_ss.tar.gz至 `cveo_ss`
```shell
cd <cveo_ss path>
.\Scripts\activate.bat
.\Scripts\conda-unpack.exe
cd <root-of-this>
python setup.py develop
# 启动keygen生成证书
keygen
# 启动rscder
rscder
```
4. 插件开发
# 功能
1. 证书检查与生成
1. 基于MAC地址与过期时间进行证书生成启动时检查证书过期则退出
2. 工程管理
1. 以工程为单位进行数据管理与生产
2. 提供工程保存与导入功能
3. 提供多种格式的栅格数据导入TIF、PNG、BMP、JPG
4. 提供矢量数据导入
3. 基本工具
1. 双视图同步浏览
2. 格网展示