1. hpi定标:采集影像时,实时扣暗电流,仅生成gain;

2. 300tc定标:采集时单独采集暗电流影像,生成gain+offset;
This commit is contained in:
tangchao0503
2023-03-12 20:15:10 +08:00
commit 8f143e51cc
8 changed files with 1653 additions and 0 deletions

243
.gitignore vendored Normal file
View File

@ -0,0 +1,243 @@
# tc
/.idea
*.xlsx
*.cal
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock
# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
#pdm.lock
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
# in version control.
# https://pdm.fming.dev/#use-with-ide
.pdm.toml
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/
# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
# User-specific stuff
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/**/usage.statistics.xml
.idea/**/dictionaries
.idea/**/shelf
# AWS User-specific
.idea/**/aws.xml
# Generated files
.idea/**/contentModel.xml
# Sensitive or high-churn files
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
.idea/**/dbnavigator.xml
# Gradle
.idea/**/gradle.xml
.idea/**/libraries
# Gradle and Maven with auto-import
# When using Gradle or Maven with auto-import, you should exclude module files,
# since they will be recreated, and may cause churn. Uncomment if using
# auto-import.
# .idea/artifacts
# .idea/compiler.xml
# .idea/jarRepositories.xml
# .idea/modules.xml
# .idea/*.iml
# .idea/modules
# *.iml
# *.ipr
# CMake
cmake-build-*/
# Mongo Explorer plugin
.idea/**/mongoSettings.xml
# File-based project format
*.iws
# IntelliJ
out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Cursive Clojure plugin
.idea/replstate.xml
# SonarLint plugin
.idea/sonarlint/
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties
# Editor-based Rest Client
.idea/httpRequests
# Android studio 3.1+ serialized cache file
.idea/caches/build_file_checksums.ser

View File

@ -0,0 +1,262 @@
'''
C:\Program Files\SpectrononPro\plugins\cube\correct
NOTES AND ASSUMPTIONS:
-Response of camera is linear after dark noise removal
- If additive binning is utilized, it must be in the header file
- If frame windowing infomation is stored on-cameras (like the Basler Ace), gain cube is collected windowed and no window header item is utilized. Otherwise,
the spatial/band windowing header item must be included.
- There is only one gain cube in vault. It is not binned or averaged.
- Offset cubes can be binned. They are located by the # of bands, not by binning numbers.
- Georeg cubes must be windowed and binned to match. This code will average down to match size, just in case, but GeoReg won't!
- If Auto Dark Noise removal is unchecked and not dark noise cube is given, no dark noise will be removed
- If Auto Dark Noise removal is unchecked, and a dark noise cube supplied, its dimensions must match the given cube
'''
from resonon.utils import cubetools as tools
from spectronon.workbench.plugin import CubePlugin
import numpy
from resonon.utils.spec import SpecFilename, SpecBool, SpecCube
from resonon.utils.cubevault import CubeVault
from resonon.core.data.cube import Cube, DummyCube
from resonon.core.data import _util
class RadianceConversion(CubePlugin):
"""Calculate radiance units based on a calibration pack (.zip) or cube"""
label = "Radiance From Raw Data"
position = 3
userLevel = 1
def setup(self):
datacube = self.datacube
self.calpack_path = SpecFilename('Imager Calibration',
wildcard='Imager Calibration Pack, Calibration Pack, Calibration Cube (*.icp, *.zip, *.bip)|*.icp;*.zip; *.bip',
must_exist=True)
self.removedark = SpecBool("Auto Remove Dark Noise?", defaultValue=True)
self.darkcube = SpecCube("Dark Noise Cube", datacube, self.wb, requireMatchedBandCount=True,
requireMatchedSampleCount=True)
self.returnfloat = SpecBool("Return floating point?", defaultValue=False)
def update(self):
datacube = self.datacube
if self.removedark.value:
self.darkcube.hidden = True
else:
self.darkcube.hidden = False
def action(self):
datacube = self.datacube
data_bands = datacube.getBandCount()
data_samples = datacube.getSampleCount()
# 这里的windowing parameters是指传感器CCD的有效窗口参数-------------------------------------------------------------------
# get the windowing parameters, falling back on full frames
try:
spatial_window = eval(datacube.getMetaValue('spatial window')) # 有效窗口的列数
except:
spatial_window = None # (0,data_samples)
try:
band_window = eval(datacube.getMetaValue('band window')) # 有效窗口的行数
except:
band_window = None # (0,data_bands)
try:
camera_binning = int(datacube.getMetaValue('camera spectral binning')) # ??????????????????????????????????????????????
except:
camera_binning = 1
try:
spectral_binning = int(datacube.getMetaValue('spectral binning')) # ??????????????????????????????????????????????
except:
spectral_binning = 1
try:
sample_binning = int(datacube.getMetaValue('sample binning'))
except:
sample_binning = 1
try:
data_gain_db = int(round(datacube.getMetaValue('gain')))
except KeyError:
data_gain_db = None
try:
data_shutter = float(round(datacube.getMetaValue('shutter')))
except KeyError:
data_shutter = None
try:
flip_frame = eval(datacube.getMetaValue('flip radiometric calibration'))
except:
try:
direction = datacube.getMetaValue('direction')
if direction == 'logo left':
flip_frame = False
else:
flip_frame = True
except:
flip_frame = False
# self.calpack_path.value是定标文件icp文件路径
if self.calpack_path.value[-3:] == 'zip' or self.calpack_path.value[-3:] == 'icp':
cvault = CubeVault(self.calpack_path.value) # 打开定标文件定标文件中包含一个gainCube和一系列offsetCube
gainCube = cvault.get_gain_cube(meta={
'camera spectral binning': camera_binning}) # cube dict prefers any header item to none unless exact_match=True, is this the right behavior?
offsetCube = cvault.get_offset_cube(meta={'camera spectral binning': camera_binning,
# is it a duplicate to ask for spectral binning on top of bands?
'samples': data_samples,
'bands': data_bands,
'gain': data_gain_db,
'shutter': data_shutter})
print offsetCube.getPath()
# window the data从一帧中裁剪出有效窗口对应的图像矩阵
gain_cube_array = gainCube.getFrame(0, asBIP=True)
offset_cube_array = offsetCube.getFrame(0, asBIP=True)
if spatial_window: # 有效窗口的列数
gain_cube_array = gain_cube_array[spatial_window[0]:spatial_window[1], :]
offset_cube_array = offset_cube_array[spatial_window[0]:spatial_window[1], :]
if band_window: # 有效窗口的行数
gain_cube_array = gain_cube_array[:, band_window[0]:band_window[1]]
offset_cube_array = offset_cube_array[:, band_window[0]:band_window[1]]
# a binned cube is scaled too large by the binning factors, so we need to divide the data by the binning.
# since the data gets multiplied by the gain_cube_array, we can just divide it by the binning factor
try:
gain_spectral_binning = int(gainCube.getMetaValue('spectral binning'))
except:
gain_spectral_binning = 1
try:
gain_sample_binning = int(gainCube.getMetaValue('sample binning'))
except:
gain_sample_binning = 1
try:
offset_spectral_binning = int(offsetCube.getMetaValue('spectral binning'))
except:
offset_spectral_binning = 1
try:
offset_sample_binning = int(offsetCube.getMetaValue('sample binning'))
except:
offset_sample_binning = 1
gc_binned_gain = gain_cube_array / ( # 这里是除法!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!已理解,这是对的!!!!!!!!!!!!!!!!!!
float(spectral_binning) * sample_binning / (gain_spectral_binning * gain_sample_binning))
# the offset of binned data is also scaled by the binning, so we need multiply the measured offset by the binning factor.
gc_binned_offset = offset_cube_array * ( # 这里成乘法!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!已理解,这是对的!!!!!!!!!!!!!!!!!!
float(spectral_binning) * sample_binning / (offset_spectral_binning * offset_sample_binning))
else:
georegcube = Cube(self.calpack_path.value)
# just copying the cube so that the legacy code still works
gainCube = georegcube
# window the data
gain_cube_array = georegcube.getFrame(1, asBIP=True)
offset_cube_array = georegcube.getFrame(0, asBIP=True)
gc_binned_gain = gain_cube_array
gc_binned_offset = offset_cube_array
if self.darkcube.value is not None:
correctionCube = self.wb.tree.getCube(self.darkcube.value)
if correctionCube.getSampleCount() != datacube.getSampleCount() or \
correctionCube.getBandCount() != datacube.getBandCount():
self.wb.postMessage('Dark Noise Cube frame size (%s) does not equal datacube frame size count(%s).' % \
(str((correctionCube.getSampleCount(), correctionCube.getBandCount())),
str((datacube.getSampleCount(), datacube.getBandCount()))))
return
gc_binned_offset = tools.meanFrameOfCube(correctionCube, asBIP=True)
# determine how the frames should be averaged (to get frame sizes to match)
gc_samples = gc_binned_gain.shape[0]
gc_bands = gc_binned_gain.shape[1]
oc_samples = gc_binned_offset.shape[0]
oc_bands = gc_binned_offset.shape[1]
if data_samples > gc_samples or data_bands > gc_bands:
self.wb.postMessage('Correction Cube frame size (%s) is smaller than datacube frame size count(%s).' % \
(str((gc_samples, gc_bands)),
str((datacube.getSampleCount(), datacube.getBandCount()))))
return
gain_sample_aveby = gc_samples / data_samples
gain_band_aveby = gc_bands / data_bands
# ave the correction cube to fit the incoming datacube (doesn't assume that the shape of the gain and offset are the same)
gc_binned_gain = tools.aveFrame(gc_binned_gain, spectralAve=gain_band_aveby, spatialAve=gain_sample_aveby, #
interleave="bip")
offset_sample_aveby = oc_samples / data_samples
offset_band_aveby = oc_bands / data_bands
gc_binned_offset = tools.aveFrame(gc_binned_offset, spectralAve=offset_band_aveby,
spatialAve=offset_sample_aveby, interleave="bip")
if flip_frame:
gc_binned_gain = numpy.flipud(gc_binned_gain)
gc_binned_offset = numpy.flipud(gc_binned_offset)
# calculate the gain and shutter differences计算校正gain和offset在ASD计算反射率时也有类似的操作这相当于消除积分时间和暗电流的影响
try:
gc_gain = 10 ** (gainCube.getMetaValue('gain') / 20.)
except (AttributeError, KeyError):
gc_gain = 1.0
gc_shutter = gainCube.getMetaValue('shutter')
try:
data_gain = 10 ** (datacube.getMetaValue('gain') / 20.)
except (AttributeError, KeyError):
data_gain = 1.0
data_shutter = datacube.getMetaValue('shutter')
gain_factor = (gc_shutter * gc_gain) / (data_shutter * data_gain)
# produce the correction frames*******************************************
adjusted_gain = gain_factor * gc_binned_gain
adjusted_offset = gc_binned_offset # we no longer have any adjustment to offset cubes
# setup the outgoing cube*************************************************
newcube = datacube.getFramelessCopy(makeTypeFloat=self.returnfloat.value)
newcube.setMetaValue("interleave", "bip")
for hdr_item in ("reflectance scale factor", "ceiling", "bit depth"):
try:
del (newcube._metadata[hdr_item])
except:
pass
# bug fix - calculate maxAllowed based on the dtype BEFORE converting to float
dtype = _util._enviType2NumpyDType(newcube.getMetaValue("data type"))
maxAllowed = _util.dataTypeMax(dtype)
lines = self.datacube.getLineCount()
# For memory cubes, it is *much* for efficient to preallocate memory
try:
newcube.extendLineBuffer(lines)
except AttributeError:
# Disk cubes don't have this ability
pass
# produce the new cube, scaling and clipping as necessary
for f in range(datacube.getLineCount()):
frame = datacube.getFrame(f, asBIP=True).astype('f')
if self.removedark.value or (self.darkcube.value is not None):
frame = numpy.clip((frame - adjusted_offset) * adjusted_gain, 0, maxAllowed)
else:
frame = numpy.clip((frame) * adjusted_gain, 0, maxAllowed)
newcube.appendFrame(frame.astype(dtype))
return newcube
def getDummyResult(self):
meta = self.datacube.getMetaDictCopy()
meta['interleave'] = 'bip'
for hdr_item in ("reflectance scale factor", "ceiling", "bit depth"):
if hdr_item in meta:
del meta[hdr_item]
return DummyCube(meta)

View File

@ -0,0 +1,251 @@
'''
1、此版本所需文件dn影像、dark影像和asd测定的积分球辐亮度曲线
2、处理过程1扣除暗电流2通过辐亮度曲线生成定标文件
'''
import numpy as np
import pandas as pd
import sys, os, traceback, re
import shutil
from radiance_calibration_ui import Ui_MainWindow
from library.multithread import Worker
import sys, traceback
from osgeo import gdal
from PyQt5.QtWidgets import QMainWindow, QFileDialog, QApplication
from PyQt5.QtCore import Qt
class EnterWindow(QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
super(EnterWindow, self).__init__(parent)
self.setupUi(self)
self.radiance_calibration_object = RadianceCalibration()
# self.setWindowState(Qt.WindowMaximized) # 初始化时就最大化窗口
self.rad_bt.clicked.connect(self.select_rad)
self.dn_bt.clicked.connect(self.select_dn)
self.dark_bt.clicked.connect(self.select_dark)
self.out_file_bt.clicked.connect(self.select_out_file)
self.operate_bt.clicked.connect(self.operate)
self.tmp_rad_file_path = None # 用于保存当前路径,下次打开就默认在此路径下
self.tmp_dn_file_path = None # 用于保存当前路径,下次打开就默认在此路径下
self.tmp_dark_file_path = None # 用于保存当前路径,下次打开就默认在此路径下
self.tmp_out_file_path = None # 用于保存当前路径,下次打开就默认在此路径下
def select_rad(self):
if self.tmp_rad_file_path == None:
rad_file_path = QFileDialog.getOpenFileName(self, '选择asd辐亮度文件', os.path.dirname(__file__))[0]
self.tmp_rad_file_path = os.path.dirname(rad_file_path)
elif self.tmp_rad_file_path is not None:
rad_file_path = QFileDialog.getOpenFileName(self, '选择asd辐亮度文件', self.tmp_rad_file_path)[0]
self.tmp_rad_file_path = os.path.dirname(rad_file_path)
self.radiance_calibration_object.asd_radiance_file_path = rad_file_path
self.rad_le.setText(rad_file_path)
def select_dn(self):
if self.tmp_dn_file_path == None:
dn_file_path = QFileDialog.getOpenFileName(self, '选择dn影像', os.path.dirname(__file__))[0]
self.tmp_dn_file_path = os.path.dirname(dn_file_path)
elif self.tmp_dn_file_path is not None:
dn_file_path = QFileDialog.getOpenFileName(self, '选择dn影像', self.tmp_dn_file_path)[0]
self.tmp_dn_file_path = os.path.dirname(dn_file_path)
self.radiance_calibration_object.dn_file_path = dn_file_path
self.dn_le.setText(dn_file_path)
def select_dark(self):
if self.tmp_dark_file_path == None:
dark_file_path = QFileDialog.getOpenFileName(self, '选择dark影像', os.path.dirname(__file__))[0]
self.tmp_dark_file_path = os.path.dirname(dark_file_path)
elif self.tmp_dark_file_path is not None:
dark_file_path = QFileDialog.getOpenFileName(self, '选择dark影像', self.tmp_dark_file_path)[0]
self.tmp_dark_file_path = os.path.dirname(dark_file_path)
self.radiance_calibration_object.dark_file_path = dark_file_path
self.dark_le.setText(dark_file_path)
def select_out_file(self):
if self.tmp_out_file_path == None:
out_file_path = QFileDialog.getExistingDirectory(self, '选择输出路径', os.path.dirname(__file__))
self.tmp_out_file_path = out_file_path
elif self.tmp_out_file_path is not None:
out_file_path = QFileDialog.getExistingDirectory(self, '选择输出路径', self.tmp_out_file_path)
self.tmp_out_file_path = out_file_path
self.radiance_calibration_object.out_file_path = out_file_path
self.out_file_le.setText(out_file_path)
def operate(self):
self.radiance_calibration_object.operate()
class RadianceCalibration():
def __init__(self):
# asd_radiance_file = os.path.dirname(__file__) + '\\corning_radance.txt'
# img_file_path = os.path.dirname(__file__) + '\\jfq_dn'
# img_dark_file_path = os.path.dirname(__file__) + '\\jfq_dn_dark'
# out_file = os.path.dirname(__file__) + '\\jfq_dn_gain'
self.asd_radiance_file_path = None
self.dn_file_path = None
self.dark_file_path = None
self.img_data = None
self.img_dark_data = None
self.out_file_path = None
def get_envi_header_dict(self, hdr_file):
with open(hdr_file, encoding='utf-8') as file_obj:
contents = file_obj.read()
# Get all "key = {val}" type matches
regex = re.compile(r'^(.+?)\s*=\s*({\s*.*?\n*.*?})$', re.M | re.I)
matches = regex.findall(contents)
# Remove them from the header
subhdr = regex.sub('', contents)
# Get all "key = val" type matches
regex = re.compile(r'^(.+?)\s*=\s*(.*?)$', re.M | re.I)
matches.extend(regex.findall(subhdr))
hdr_fields = dict(matches)
keys_delete = []
for key in hdr_fields.keys():
if (
key == "interleave" or key == "byte order" or key == "data type" or key == "samples" or key == "bands" or key == "lines" or key == "framerate"):
keys_delete.append(key)
for x in range(len(keys_delete)):
hdr_fields.pop(keys_delete[x])
return hdr_fields
def get_hdr_filename(self, file_path):
return os.path.splitext(file_path)[0] + ".hdr"
def get_hdr_filename_with_bip(self, file_path):
return os.path.splitext(file_path)[0] + ".bip.hdr"
def write_fields_to_hdrfile(self, fields, hdr_file):
with open(hdr_file, "a", encoding='utf-8') as f:
for key in fields.keys():
f.write(key + " = " + fields[key] + "\n")
def process_hdr(self, hdr_file_path, envi_header_dict):
self.write_fields_to_hdrfile(envi_header_dict, self.get_hdr_filename(hdr_file_path))
shutil.copyfile(self.get_hdr_filename(hdr_file_path), self.get_hdr_filename_with_bip(hdr_file_path))
os.remove(self.get_hdr_filename(hdr_file_path))
# 读图像文件
def read_img(self, filename, xoff=0, yoff=0, im_width=None, im_height=None):
try:
dataset = gdal.Open(filename) # 打开文件
if im_width == None:
im_width = dataset.RasterXSize # 栅格矩阵的列数
if im_height == None:
im_height = dataset.RasterYSize # 栅格矩阵的行数
num_bands = dataset.RasterCount # 栅格矩阵的波段数
im_geotrans = dataset.GetGeoTransform() # 仿射矩阵
im_proj = dataset.GetProjection() # 地图投影信息
im_data = dataset.ReadAsArray(xoff, yoff, im_width, im_height) # 将数据写成数组,对应栅格矩阵
del dataset
return im_proj, im_geotrans, im_data
except AttributeError:
print('gdal打开影像没有文件')
except Exception:
traceback.print_exc()
pass
# 写文件以写成tif为例
def write_img(self, dst_filename, data):
format = "ENVI"
driver = gdal.GetDriverByName(format)
RasterXSize = data.shape[2] # 遥感影像的sample列数
RasterYSize = data.shape[1] # 遥感影像的line行数
band = data.shape[0]
# driver.Create()函数中RasterXSize代表影像的sample列数RasterYSize代表影像的line行数
dst_ds = driver.Create(dst_filename, RasterXSize, RasterYSize, band, gdal.GDT_Float64,
options=["INTERLEAVE=BIP"])
for i in range(band):
dst_ds.GetRasterBand(i + 1).WriteArray(data[i, :, :]) # gdal的band从1开始所以dst_ds.GetRasterBand(i+1)
dst_ds = None
def operate(self):
try:
# 读取asd辐亮度数据
data = pd.read_csv(self.asd_radiance_file_path, sep='\t', dtype=np.float64, header=None)
self.asd_radiance = np.array(data)
# 读取影像
img_proj, img_geotrans, self.img_data = self.read_img(self.dn_file_path)
dn_hdr = self.get_envi_header_dict(self.get_hdr_filename(self.dn_file_path))
img_dark_proj, img_dark_geotrans, self.img_dark_data = self.read_img(self.dark_file_path)
dark_hdr = self.get_envi_header_dict(self.get_hdr_filename(self.dark_file_path))
# 将影像所有行平均,得到一行(帧)影像
img_data_ave = np.mean(self.img_data, axis=1)
img_dark_data_ave = np.mean(self.img_dark_data, axis=1)
# 去除暗电流
img_data_ave_rmdark = img_data_ave - img_dark_data_ave
img_dark_data_ave = img_dark_data_ave + 50
gain = np.empty((img_data_ave_rmdark.shape[0], 1, img_data_ave_rmdark.shape[1]))
offset = np.empty((img_data_ave_rmdark.shape[0], 1, img_data_ave_rmdark.shape[1]))
for i in range(gain.shape[2]):
gain[:, 0, i] = self.asd_radiance[:, 1] / img_data_ave_rmdark[:, i]
offset[:, 0, i] = img_dark_data_ave[:, i]
gain_name = os.path.join(self.out_file_path, "gain.bip")
offset_name = os.path.join(self.out_file_path, "offset.bip")
self.write_img(gain_name, gain)
self.process_hdr(gain_name, dn_hdr)
self.write_img(offset_name, offset)
self.process_hdr(offset_name, dark_hdr)
except:
traceback.print_exc()
def operate_without_dark(self):
try:
# 读取asd辐亮度数据
data = pd.read_csv(self.asd_radiance_file_path, sep='\t', dtype=np.float64, header=None)
self.asd_radiance = np.array(data)
# 读取影像
img_proj, img_geotrans, self.img_data = self.read_img(self.dn_file_path)
# 将影像所有行平均,得到一行(帧)影像
img_data_ave = np.mean(self.img_data, axis=1)
gain = np.empty((img_data_ave.shape[0], 1, img_data_ave.shape[1]))
for i in range(gain.shape[2]):
gain[:, 0, i] = self.asd_radiance[:, 1] / img_data_ave[:, i]
self.write_img(self.out_file_path, gain)
except:
traceback.print_exc()
if __name__ == '__main__':
app = QApplication(sys.argv)
# 实例化主窗口
enter_window_instance = EnterWindow()
enter_window_instance.show()
sys.exit(app.exec_())

View File

@ -0,0 +1,119 @@
'''
1、此版本所需文件dn影像和asd测定的积分球辐亮度曲线
2、处理过程不需要扣除暗电流因为dn影像在采集时已经扣除了暗电流
1通过辐亮度曲线生成定标文件
'''
import numpy as np
import pandas as pd
import sys, os, traceback
from library.image_reader_writer import ImageReaderWriter
from radiance_calibration_ui import Ui_MainWindow
from library.multithread import Worker
from PyQt5.QtWidgets import QMainWindow, QFileDialog, QApplication
from PyQt5.QtCore import Qt
class EnterWindow(QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
super(EnterWindow, self).__init__(parent)
self.setupUi(self)
self.radiance_calibration_object = RadianceCalibration()
# self.setWindowState(Qt.WindowMaximized) # 初始化时就最大化窗口
self.rad_bt.clicked.connect(self.select_rad)
self.dn_bt.clicked.connect(self.select_dn)
self.out_file_bt.clicked.connect(self.select_out_file)
self.operate_bt.clicked.connect(self.operate)
self.tmp_rad_file_path = None # 用于保存当前路径,下次打开就默认在此路径下
self.tmp_dn_file_path = None # 用于保存当前路径,下次打开就默认在此路径下
self.tmp_out_file_path = None # 用于保存当前路径,下次打开就默认在此路径下
def select_rad(self):
if self.tmp_rad_file_path == None:
rad_file_path = QFileDialog.getOpenFileName(self, '选择asd辐亮度文件', os.path.dirname(__file__))[0]
self.tmp_rad_file_path = os.path.dirname(rad_file_path)
elif self.tmp_rad_file_path is not None:
rad_file_path = QFileDialog.getOpenFileName(self, '选择asd辐亮度文件', self.tmp_rad_file_path)[0]
self.tmp_rad_file_path = os.path.dirname(rad_file_path)
self.radiance_calibration_object.asd_radiance_file_path = rad_file_path
self.rad_le.setText(rad_file_path)
def select_dn(self):
if self.tmp_dn_file_path == None:
dn_file_path = QFileDialog.getOpenFileName(self, '选择dn影像', os.path.dirname(__file__))[0]
self.tmp_dn_file_path = os.path.dirname(dn_file_path)
elif self.tmp_dn_file_path is not None:
dn_file_path = QFileDialog.getOpenFileName(self, '选择dn影像', self.tmp_dn_file_path)[0]
self.tmp_dn_file_path = os.path.dirname(dn_file_path)
self.radiance_calibration_object.dn_file_path = dn_file_path
self.dn_le.setText(dn_file_path)
def select_out_file(self):
if self.tmp_out_file_path == None:
out_file_path = QFileDialog.getSaveFileName(self, '选择输出文件路径和文件名', os.path.dirname(__file__))[0]
self.tmp_out_file_path = os.path.dirname(out_file_path)
elif self.tmp_out_file_path is not None:
out_file_path = QFileDialog.getSaveFileName(self, '选择输出文件路径和文件名', self.tmp_out_file_path)[0]
self.tmp_out_file_path = os.path.dirname(out_file_path)
self.radiance_calibration_object.out_file_path = out_file_path
self.out_file_le.setText(out_file_path)
def operate(self):
self.radiance_calibration_object.operate()
class RadianceCalibration():
def __init__(self):
# asd_radiance_file = os.path.dirname(__file__) + '\\corning_radance.txt'
# img_file_path = os.path.dirname(__file__) + '\\jfq_dn'
# out_file = os.path.dirname(__file__) + '\\jfq_dn_gain'
self.asd_radiance_file_path = None
self.dn_file_path = None
self.img_data = None
self.out_file_path = None
def operate(self):
try:
# 读取asd辐亮度数据
data = pd.read_csv(self.asd_radiance_file_path, sep='\t', dtype=np.float64, header=None)
self.asd_radiance = np.array(data)
# 读取影像
img_proj, img_geotrans, self.img_data = ImageReaderWriter.read_img(self.dn_file_path)
# 将影像所有行平均,得到一行(帧)影像
img_data_ave = np.mean(self.img_data, axis=1)
gain = np.empty((img_data_ave.shape[0], 1, img_data_ave.shape[1]))
for i in range(gain.shape[2]):
gain[:, 0, i] = self.asd_radiance[:, 1] / img_data_ave[:, i]
ImageReaderWriter.write_img(self.out_file_path, gain)
except:
traceback.print_exc()
if __name__ == '__main__':
app = QApplication(sys.argv)
# 实例化主窗口
enter_window_instance = EnterWindow()
enter_window_instance.show()
sys.exit(app.exec_())

View File

@ -0,0 +1,101 @@
'''
https://blog.csdn.net/vonuo/article/details/74783291
本方法是使用asd的方法来进行corning的辐亮度定标resonon的方法感觉和此方法差不多
'''
from osgeo import gdal
import os, math
import sys
import easygui
import numpy as np
import pandas as pd
import xlwt
# 读写影像类
class Grid(object):
#读图像文件
@classmethod
def read_img(cls, filename, xoff=0, yoff=0, im_width=None, im_height=None):
try:
dataset = gdal.Open(filename) # 打开文件
if im_width == None:
im_width = dataset.RasterXSize # 栅格矩阵的列数
if im_height == None:
im_height = dataset.RasterYSize # 栅格矩阵的行数
num_bands = dataset.RasterCount # 栅格矩阵的波段数
im_geotrans = dataset.GetGeoTransform() # 仿射矩阵
im_proj = dataset.GetProjection() # 地图投影信息
im_data = dataset.ReadAsArray(xoff, yoff, im_width, im_height) # 将数据写成数组,对应栅格矩阵
del dataset
return im_proj, im_geotrans, im_data
except:
sys.exit()
#写文件以写成tif为例
@classmethod
def write_img(cls, dst_filename, data):
format = "ENVI"
driver = gdal.GetDriverByName(format)
RasterXSize = data.shape[2] # 遥感影像的sample列数
RasterYSize = data.shape[1] # 遥感影像的line行数
band = data.shape[0]
# driver.Create()函数中RasterXSize代表影像的sample列数RasterYSize代表影像的line行数
dst_ds = driver.Create(dst_filename, RasterXSize, RasterYSize, band, gdal.GDT_Float32)
for i in range(band):
dst_ds.GetRasterBand(i + 1).WriteArray(data[i, :, :]) # gdal的band从1开始所以dst_ds.GetRasterBand(i+1)
dst_ds = None
# 是否转辐亮度0→不转1→转
rad_switch = 0
img = r'D:\py_program\corning410\record_system_v24\baiban_record'
img_baiban = r'D:\py_program\corning410\record_system_v24\baiban'
img_gain = r'D:\py_program\corning410\corning410_radiance_calibration\jfq_dn_gain'
img_offset = r'D:\py_program\corning410\record_system_v24\dark'
dirpath = os.path.splitext(img)
# 读取影像
proj, geotrans, data = Grid.read_img(img)
proj_baiban, geotrans_baiban, data_baiban = Grid.read_img(img_baiban)
proj_gain, geotrans_gain, data_gain = Grid.read_img(img_gain)
proj_offset, geotrans_offset, data_offset = Grid.read_img(img_offset)
data_baiban = np.mean(data_baiban, axis=1)
data_offset = np.mean(data_offset, axis=1)
if rad_switch == 1:
# 计算辐射定标参数
cal_it = 6059
target_it = 200004
gain_scale = cal_it / target_it
data_gain_adjust = data_gain * gain_scale
# 影像和白板1、扣除暗电流2、转换成辐亮度
data_baiban = data_baiban - data_offset # 白板扣除暗电流
data_baiban_rad = data_baiban * data_gain_adjust[:, 0, :] # 白板转辐亮度
data_rad = np.empty(data.shape)
for i in range(data.shape[1]):
data_rad[:, i, :] = (data[:, i, :] - data_offset) * data_gain_adjust[:, 0, :] # 转辐亮度
Grid.write_img(dirpath[0] + '_rad', data_rad)
# 转换成反射率
data_rad_ref = np.empty(data.shape)
for i in range(data.shape[1]):
data_rad_ref[:, i, :] = data_rad[:, i, :] / data_baiban_rad # 转反射率
Grid.write_img(dirpath[0] + '_rad_ref', data_rad_ref)
elif rad_switch == 0:
# 影像和白板扣除暗电流
data_baiban = data_baiban - data_offset
data_rmdark = np.empty(data.shape)
for i in range(data.shape[1]):
data_rmdark[:, i, :] = (data[:, i, :] - data_offset)
# 转反射率
data_ref = np.empty(data.shape)
for i in range(data.shape[1]):
data_ref[:, i, :] = data_rmdark[:, i, :] / data_baiban # 转反射率
Grid.write_img(dirpath[0] + '_ref', data_ref)

300
corning_radance.txt Normal file
View File

@ -0,0 +1,300 @@
397.959198 0.016826
399.958771 0.017833
401.958313 0.018945
403.957886 0.020166
405.957458 0.021402
407.957031 0.022727
409.956573 0.024146
411.956146 0.025537
413.955719 0.026962
415.955261 0.028384
417.954834 0.029758
419.954407 0.031123
421.953949 0.032428
423.953522 0.033733
425.953094 0.034996
427.952667 0.036257
429.952209 0.037488
431.951782 0.038767
433.951355 0.040043
435.950897 0.041326
437.95047 0.0426
439.950043 0.043897
441.949615 0.045203
443.949158 0.046568
445.94873 0.047932
447.948303 0.049302
449.947845 0.050722
451.947418 0.052172
453.946991 0.053657
455.946564 0.055149
457.946106 0.056651
459.945679 0.058194
461.945251 0.059754
463.944794 0.061342
465.944366 0.062949
467.943939 0.064564
469.943512 0.066216
471.943054 0.06789
473.942627 0.069578
475.9422 0.07129
477.941742 0.073023
479.941315 0.07477
481.940887 0.07657
483.94046 0.078357
485.940002 0.080167
487.939575 0.081986
489.939148 0.083853
491.93869 0.085709
493.938263 0.087612
495.937836 0.089504
497.937408 0.091452
499.936951 0.093356
501.936523 0.095327
503.936096 0.097268
505.935638 0.099255
507.935211 0.101218
509.934784 0.103205
511.934357 0.105188
513.933899 0.107211
515.933472 0.109212
517.933044 0.111223
519.932617 0.11324
521.93219 0.115274
523.931702 0.117286
525.931274 0.119314
527.930847 0.121342
529.93042 0.123381
531.929993 0.125442
533.929565 0.127516
535.929138 0.129566
537.92865 0.131653
539.928223 0.1337
541.927795 0.13577
543.927368 0.137831
545.926941 0.1399
547.926514 0.141954
549.926086 0.144
551.925598 0.146041
553.925171 0.148075
555.924744 0.150128
557.924316 0.152166
559.923889 0.154153
561.923462 0.156169
563.923035 0.158193
565.922546 0.160218
567.922119 0.162267
569.921692 0.164324
571.921265 0.166323
573.920837 0.168311
575.92041 0.170291
577.919983 0.172281
579.919495 0.17428
581.919067 0.176234
583.91864 0.178223
585.918213 0.180202
587.917786 0.182168
589.917358 0.184131
591.916931 0.186068
593.916443 0.187966
595.916016 0.189889
597.915588 0.191788
599.915161 0.193692
601.914734 0.195588
603.914307 0.197465
605.913879 0.199339
607.913391 0.201193
609.912964 0.203046
611.912537 0.204877
613.912109 0.20672
615.911682 0.208548
617.911255 0.210348
619.910828 0.212157
621.910339 0.21397
623.909912 0.215746
625.909485 0.217497
627.909058 0.219244
629.90863 0.220984
631.908203 0.222711
633.907776 0.224391
635.907288 0.226061
637.90686 0.227713
639.906433 0.229346
641.906006 0.230951
643.905579 0.232568
645.905151 0.234142
647.904724 0.235708
649.904236 0.23727
651.903809 0.238786
653.903381 0.24031
655.902954 0.241785
657.902527 0.243246
659.9021 0.244666
661.901672 0.246061
663.901184 0.247443
665.900757 0.248771
667.90033 0.250111
669.899902 0.251449
671.899475 0.252819
673.899048 0.254173
675.898621 0.255553
677.898132 0.256968
679.897705 0.258384
681.897278 0.259837
683.896851 0.261271
685.896423 0.262646
687.895996 0.264113
689.895569 0.265597
691.895081 0.267087
693.894653 0.26856
695.894226 0.270029
697.893799 0.271537
699.893372 0.273024
701.892944 0.274497
703.892517 0.27598
705.892029 0.277394
707.891602 0.278829
709.891174 0.280229
711.890747 0.281586
713.89032 0.282901
715.889893 0.284185
717.889465 0.285366
719.888977 0.286532
721.88855 0.287701
723.888123 0.288782
725.887695 0.289826
727.887268 0.290799
729.886841 0.291714
731.886414 0.292611
733.885925 0.293465
735.885498 0.294267
737.885071 0.295024
739.884644 0.295758
741.884216 0.296422
743.883789 0.297081
745.883362 0.297755
747.882874 0.2983
749.882446 0.298894
751.882019 0.299411
753.881592 0.299927
755.881165 0.300439
757.880737 0.300789
759.88031 0.300426
761.879822 0.300811
763.879395 0.301391
765.878967 0.302141
767.87854 0.302745
769.878113 0.303104
771.877686 0.303389
773.877258 0.303661
775.87677 0.303844
777.876343 0.304019
779.875916 0.304218
781.875488 0.304372
783.875061 0.304507
785.874634 0.304636
787.874146 0.304772
789.873718 0.3049
791.873291 0.305011
793.872864 0.305106
795.872437 0.305178
797.872009 0.305277
799.871582 0.305334
801.871094 0.305394
803.870667 0.305456
805.870239 0.30557
807.869812 0.305647
809.869385 0.305704
811.868958 0.305731
813.86853 0.305728
815.868042 0.305726
817.867615 0.305811
819.867188 0.305906
821.86676 0.306007
823.866333 0.30608
825.865906 0.306267
827.865479 0.306351
829.86499 0.306463
831.864563 0.306576
833.864136 0.306741
835.863708 0.306931
837.863281 0.307127
839.862854 0.307383
841.862427 0.307674
843.861938 0.307943
845.861511 0.308249
847.861084 0.308576
849.860657 0.308906
851.860229 0.309256
853.859802 0.309625
855.859375 0.310032
857.858887 0.310487
859.858459 0.310902
861.858032 0.311381
863.857605 0.311833
865.857178 0.312303
867.85675 0.312768
869.856323 0.313248
871.855835 0.313723
873.855408 0.314215
875.85498 0.314768
877.854553 0.315275
879.854126 0.315828
881.853699 0.316369
883.853271 0.316931
885.852783 0.3174
887.852356 0.317971
889.851929 0.318538
891.851501 0.319065
893.851074 0.319602
895.850647 0.32009
897.85022 0.320544
899.849731 0.320979
901.849304 0.321402
903.848877 0.321871
905.84845 0.32228
907.848022 0.322704
909.847595 0.323072
911.847168 0.323442
913.84668 0.323902
915.846252 0.324326
917.845825 0.324707
919.845398 0.325192
921.844971 0.325606
923.844543 0.326058
925.844116 0.326512
927.843628 0.326828
929.843201 0.326976
931.842773 0.327033
933.842346 0.327205
935.841919 0.327592
937.841492 0.32804
939.841064 0.328472
941.840576 0.328777
943.840149 0.32892
945.839722 0.329077
947.839294 0.329235
949.838867 0.329399
951.83844 0.329527
953.838013 0.329495
955.837524 0.32966
957.837097 0.329701
959.83667 0.329649
961.836243 0.329759
963.835815 0.329742
965.835388 0.329725
967.834961 0.329847
969.834473 0.329885
971.834045 0.329977
973.833618 0.330035
975.833191 0.330221
977.832764 0.33022
979.832336 0.330393
981.831909 0.330477
983.831421 0.330686
985.830994 0.330845
987.830566 0.331049
989.830139 0.331023
991.829712 0.331329
993.829285 0.331352
995.828857 0.331532

151
radiance_calibration_ui.py Normal file
View File

@ -0,0 +1,151 @@
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'radiance_calibration_ui.ui'
#
# Created by: PyQt5 UI code generator 5.13.0
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(964, 621)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.gridLayout_2 = QtWidgets.QGridLayout(self.centralwidget)
self.gridLayout_2.setObjectName("gridLayout_2")
self.frame = QtWidgets.QFrame(self.centralwidget)
self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
self.frame.setObjectName("frame")
self.gridLayout = QtWidgets.QGridLayout(self.frame)
self.gridLayout.setObjectName("gridLayout")
self.label = QtWidgets.QLabel(self.frame)
self.label.setAlignment(QtCore.Qt.AlignCenter)
self.label.setObjectName("label")
self.gridLayout.addWidget(self.label, 0, 0, 1, 1)
self.rad_le = QtWidgets.QLineEdit(self.frame)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.rad_le.sizePolicy().hasHeightForWidth())
self.rad_le.setSizePolicy(sizePolicy)
font = QtGui.QFont()
font.setPointSize(18)
self.rad_le.setFont(font)
self.rad_le.setReadOnly(True)
self.rad_le.setObjectName("rad_le")
self.gridLayout.addWidget(self.rad_le, 0, 1, 1, 1)
self.rad_bt = QtWidgets.QPushButton(self.frame)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.rad_bt.sizePolicy().hasHeightForWidth())
self.rad_bt.setSizePolicy(sizePolicy)
self.rad_bt.setObjectName("rad_bt")
self.gridLayout.addWidget(self.rad_bt, 0, 2, 1, 1)
self.label_3 = QtWidgets.QLabel(self.frame)
self.label_3.setAlignment(QtCore.Qt.AlignCenter)
self.label_3.setObjectName("label_3")
self.gridLayout.addWidget(self.label_3, 1, 0, 1, 1)
self.dn_le = QtWidgets.QLineEdit(self.frame)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.dn_le.sizePolicy().hasHeightForWidth())
self.dn_le.setSizePolicy(sizePolicy)
font = QtGui.QFont()
font.setPointSize(18)
self.dn_le.setFont(font)
self.dn_le.setReadOnly(True)
self.dn_le.setObjectName("dn_le")
self.gridLayout.addWidget(self.dn_le, 1, 1, 1, 1)
self.dn_bt = QtWidgets.QPushButton(self.frame)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.dn_bt.sizePolicy().hasHeightForWidth())
self.dn_bt.setSizePolicy(sizePolicy)
self.dn_bt.setObjectName("dn_bt")
self.gridLayout.addWidget(self.dn_bt, 1, 2, 1, 1)
self.dark_checkBox = QtWidgets.QCheckBox(self.frame)
self.dark_checkBox.setObjectName("dark_checkBox")
self.gridLayout.addWidget(self.dark_checkBox, 2, 0, 1, 1)
self.dark_le = QtWidgets.QLineEdit(self.frame)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.dark_le.sizePolicy().hasHeightForWidth())
self.dark_le.setSizePolicy(sizePolicy)
font = QtGui.QFont()
font.setPointSize(18)
self.dark_le.setFont(font)
self.dark_le.setReadOnly(True)
self.dark_le.setObjectName("dark_le")
self.gridLayout.addWidget(self.dark_le, 2, 1, 1, 1)
self.dark_bt = QtWidgets.QPushButton(self.frame)
self.dark_bt.setEnabled(True)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.dark_bt.sizePolicy().hasHeightForWidth())
self.dark_bt.setSizePolicy(sizePolicy)
self.dark_bt.setObjectName("dark_bt")
self.gridLayout.addWidget(self.dark_bt, 2, 2, 1, 1)
self.label_4 = QtWidgets.QLabel(self.frame)
self.label_4.setAlignment(QtCore.Qt.AlignCenter)
self.label_4.setObjectName("label_4")
self.gridLayout.addWidget(self.label_4, 3, 0, 1, 1)
self.out_file_le = QtWidgets.QLineEdit(self.frame)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.out_file_le.sizePolicy().hasHeightForWidth())
self.out_file_le.setSizePolicy(sizePolicy)
font = QtGui.QFont()
font.setPointSize(18)
self.out_file_le.setFont(font)
self.out_file_le.setReadOnly(True)
self.out_file_le.setObjectName("out_file_le")
self.gridLayout.addWidget(self.out_file_le, 3, 1, 1, 1)
self.out_file_bt = QtWidgets.QPushButton(self.frame)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.out_file_bt.sizePolicy().hasHeightForWidth())
self.out_file_bt.setSizePolicy(sizePolicy)
self.out_file_bt.setObjectName("out_file_bt")
self.gridLayout.addWidget(self.out_file_bt, 3, 2, 1, 1)
self.gridLayout_2.addWidget(self.frame, 0, 0, 1, 1)
self.operate_bt = QtWidgets.QPushButton(self.centralwidget)
self.operate_bt.setMaximumSize(QtCore.QSize(16777215, 60))
self.operate_bt.setObjectName("operate_bt")
self.gridLayout_2.addWidget(self.operate_bt, 1, 0, 1, 1)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 964, 26))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.label.setText(_translate("MainWindow", "ASD辐亮度"))
self.rad_bt.setText(_translate("MainWindow", "浏览..."))
self.label_3.setText(_translate("MainWindow", "DN"))
self.dn_bt.setText(_translate("MainWindow", "浏览..."))
self.dark_checkBox.setText(_translate("MainWindow", "dark_checkBox"))
self.dark_bt.setText(_translate("MainWindow", "浏览..."))
self.label_4.setText(_translate("MainWindow", "输出路径"))
self.out_file_bt.setText(_translate("MainWindow", "浏览..."))
self.operate_bt.setText(_translate("MainWindow", "执行"))

226
radiance_calibration_ui.ui Normal file
View File

@ -0,0 +1,226 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>964</width>
<height>621</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QFrame" name="frame">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>ASD辐亮度</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="rad_le">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>18</pointsize>
</font>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QPushButton" name="rad_bt">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>浏览...</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>DN</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="dn_le">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>18</pointsize>
</font>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QPushButton" name="dn_bt">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>浏览...</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="dark_checkBox">
<property name="text">
<string>dark</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="dark_le">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>18</pointsize>
</font>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QPushButton" name="dark_bt">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>浏览...</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>输出路径</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="out_file_le">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>18</pointsize>
</font>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="QPushButton" name="out_file_bt">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>浏览...</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="1" column="0">
<widget class="QPushButton" name="operate_bt">
<property name="maximumSize">
<size>
<width>16777215</width>
<height>60</height>
</size>
</property>
<property name="text">
<string>执行</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>964</width>
<height>23</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<resources/>
<connections/>
</ui>