fixbug;remove bug
This commit is contained in:
parent
1e32f960db
commit
08550bd746
6
.gitignore
vendored
6
.gitignore
vendored
@ -222,7 +222,11 @@ share
|
||||
|
||||
nuitka.help
|
||||
log.txt
|
||||
|
||||
logs/
|
||||
*.7z
|
||||
*.zip*
|
||||
*.tar.gz
|
||||
install/
|
||||
!plugins/unsupervised_method/scripts/*.pyd
|
||||
!plugins/*/scripts/*.pyd
|
||||
|
||||
|
52
ReadMe.md
52
ReadMe.md
@ -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. 格网展示
|
11
build.bat
11
build.bat
@ -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
|
23
conda.yaml
23
conda.yaml
@ -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
|
@ -1 +0,0 @@
|
||||
IieXktda+1nRK9zLwe87uPPn2VpCwmUrEOPfyenaW/Sek70/CqqbCr7nangL1+pVXSkzDELia7Qq8e+pDMuHCXzxyJOALRj4j3bhFVExwqSTLuXwdev1e26nr7vnECl7H0SCVynr8To7ciwcnmK6HJXre6i+mBdTjACmKseTMlWp480XOt7uHysltORbTA3J
|
@ -1 +0,0 @@
|
||||
vd4FiYncytyziGH9GNCAA8hGGr1/79Xmphtc5+PHPJDpxvqj1hP7+985QMojYO4M5Qn/aqEAvFgeDN3CA8x1YAK8SdCgSXSBJpRBK8wqPQjBY1ak96QfdPCrTLunr+xuPxK3Gxe772adTTsee2+ot7WePYUsC4y4NcS5+rlP1if87xtYqVeSwx3c64cOmAGP
|
@ -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)
|
||||
|
||||
@ -112,3 +118,81 @@ class ExportPlugin(BasicPlugin):
|
||||
if result:
|
||||
shutil.copy(result.path, out)
|
||||
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
|
@ -6,3 +6,6 @@ from .mean_filter import MeanFilter
|
||||
from filter_collection.main import *
|
||||
from .morphology_filter import MorphologyFilter
|
||||
from .bilater_filter import BilaterFilter
|
||||
from .lee_filter import LeeFilter
|
||||
from .lms_filter import AdaptiveFilter
|
||||
from .lmsnp_filter import AdaptiveNPFilter
|
112
plugins/filter_collection/lee_filter.py
Normal file
112
plugins/filter_collection/lee_filter.py
Normal 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
|
140
plugins/filter_collection/lms_filter.py
Normal file
140
plugins/filter_collection/lms_filter.py
Normal 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
|
128
plugins/filter_collection/lmsnp_filter.py
Normal file
128
plugins/filter_collection/lmsnp_filter.py
Normal 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
|
@ -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
53
res.qrc
@ -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
118
result.txt
Normal 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
|
@ -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()
|
||||
|
||||
|
@ -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
39
rscder/gui/guicfg.py
Normal 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
67
rscder/gui/location.py
Normal 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)
|
@ -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)
|
||||
|
||||
|
@ -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'))
|
||||
|
||||
|
11
setup.py
11
setup.py
@ -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
36
test.py
Normal 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)))
|
24
使用手册.txt
24
使用手册.txt
@ -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
42
安装方法.md
Normal 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. 格网展示
|
Loading…
x
Reference in New Issue
Block a user