Browse Source

added a simple gui

master
Holger Frey 6 years ago
parent
commit
7248403012
  1. 1
      mtor/__init__.py
  2. 54
      mtor/cli.py
  3. 93
      mtor/dataproc.py
  4. 186
      mtor/gui.py
  5. 4
      setup.py
  6. 316
      test.py

1
mtor/__init__.py

@ -13,6 +13,7 @@ warnings.filterwarnings("ignore") @@ -13,6 +13,7 @@ warnings.filterwarnings("ignore")
__version__ = "0.1.0"
def run():
# pw = prescan_workflow("mtor-bilder", 50, 910, 300, 660)
pw = prescan_workflow("mtor-bilder", 50, 725 + 150, 300, 725)

54
mtor/cli.py

@ -1,16 +1,54 @@ @@ -1,16 +1,54 @@
# -*- coding: utf-8 -*-
"""Console script for mtor."""
import sys
import click
import sys
import warnings
from .workflows import (
prescan_workflow,
image_workflow,
data_workflow,
postprocessing_workflow,
)
warnings.filterwarnings("ignore")
@click.command()
def main(args=None):
"""Console script for mtor."""
click.echo("Replace this message by putting your code into "
"mtor.cli.main")
click.echo("See click documentation at http://click.pocoo.org/")
@click.argument(
"folder",
type=click.Path(
exists=True,
file_okay=False,
dir_okay=True,
writable=True,
readable=True,
resolve_path=True,
allow_dash=False,
),
)
@click.argument("top", type=click.INT)
@click.argument("right", type=click.INT)
@click.argument("bottom", type=click.INT)
@click.argument("left", type=click.INT)
def main(folder, top, right, bottom, left):
"""Console script for analysing mtor images.
You need to provide the following information:
\b
FOLDER path to the directory containing tif images to analyse
TOP top edge position of the ROI in pixels
RIGHT right edge position of the ROI in pixels
BOTTOM bottom edge position of the ROI in pixels
LEFT left edge position of the ROI in pixels
"""
pw = prescan_workflow(folder, top, right, bottom, left)
iw = image_workflow(pw.parameters)
dw = data_workflow(iw.data, iw.parameters)
fw = postprocessing_workflow(dw.data, dw.parameters) # noqa: F841
return 0

93
mtor/dataproc.py

@ -23,6 +23,20 @@ from scipy.signal import savgol_filter @@ -23,6 +23,20 @@ from scipy.signal import savgol_filter
from .commons import ROI_STATISTIC_FUNCTIONS
IMAGE_NAMES = {
1: "1-histogram-of-guard-avarages-not-filtered.png",
2: "2-histogram-of-guard-avarages-filtered.png",
3: "3-histogram-of-guard-avarages-filtered-with-first-minima.png",
4: "4-image-selection-based-on-guard-values.png",
5: "5-selected-values-based-on-guard-values.png",
6: "6-boxplot-of-guarded-values.png",
7: "7-selected-images-outliers-removed.png",
8: "8-selected-images-outliers-removed-rolling-min-applied.png",
9: "9-selected-images-outliers-removed-rolling-min-savgol-filtered.png",
10: "11-finding-minima-and-maxima.png",
}
def peakplot_iloc(x, y, ix1, ix1_label="peaks", ix2=None, ix2_label="peaks"):
"""
Plots the original data with the peaks that were identified
@ -112,9 +126,7 @@ def find_guard_threshold(data_frame, parameters): @@ -112,9 +126,7 @@ def find_guard_threshold(data_frame, parameters):
pyplot.title("Histogram of Guard Avarages (not filtered)")
pyplot.xlabel("Average Intensity [au]")
pyplot.ylabel("Number of Observations [1]")
path = (
parameters.data_dir / "1-histogram-of-guard-avarages-not-filtered.png"
)
path = parameters.data_dir / IMAGE_NAMES[1]
pyplot.savefig(str(path))
guard_counts_filtered = savgol_filter(
@ -128,7 +140,7 @@ def find_guard_threshold(data_frame, parameters): @@ -128,7 +140,7 @@ def find_guard_threshold(data_frame, parameters):
pyplot.title("Histogram of Guard Avarages (Savitzky-Golay filter)")
pyplot.xlabel("Average Intensity [au]")
pyplot.ylabel("Number of Observations [1]")
path = parameters.data_dir / "2-histogram-of-guard-avarages-filtered.png"
path = parameters.data_dir / IMAGE_NAMES[2]
pyplot.savefig(str(path))
# Finding the first minima after the first peak
@ -165,10 +177,7 @@ def find_guard_threshold(data_frame, parameters): @@ -165,10 +177,7 @@ def find_guard_threshold(data_frame, parameters):
)
pyplot.xlabel("Average Intensity [au]")
pyplot.ylabel("Number of Observations [1]")
path = (
parameters.data_dir
/ "3-histogram-of-guard-avarages-filtered-with-first-minima.png"
)
path = parameters.data_dir / IMAGE_NAMES[3]
pyplot.savefig(str(path))
@ -201,7 +210,7 @@ def check_guards(data_frame, parameters): @@ -201,7 +210,7 @@ def check_guards(data_frame, parameters):
pyplot.title("Selection based on guard values")
pyplot.ylabel("Average Intensity [au]")
pyplot.ylabel("Frame Number [1]")
path = parameters.data_dir / "4-image-selection-based-on-guard-values.png"
path = parameters.data_dir / IMAGE_NAMES[4]
pyplot.savefig(str(path))
parameters.charts_y_limit = ax.get_ylim()
@ -220,7 +229,7 @@ def check_guards(data_frame, parameters): @@ -220,7 +229,7 @@ def check_guards(data_frame, parameters):
pyplot.xlabel("Frame Number [1]")
pyplot.ylabel("Average Intensity [au]")
ax.set_ylim(parameters.charts_y_limit)
path = parameters.data_dir / "5-selected-values-based-on-guard-values.png"
path = parameters.data_dir / IMAGE_NAMES[5]
pyplot.savefig(str(path))
return data_frame
@ -235,7 +244,7 @@ def find_outliers(data_frame, parameters): @@ -235,7 +244,7 @@ def find_outliers(data_frame, parameters):
seaborn.boxplot(data=guarded_df, x=parameters.roi_column)
pyplot.title(f"Boxblot of guarded values")
pyplot.xlabel("Average Intensity [au]")
path = parameters.data_dir / "6-boxplot-of-guarded-values.png"
path = parameters.data_dir / IMAGE_NAMES[6]
pyplot.savefig(str(path))
lower_quartil = guarded_df[parameters.roi_column].quantile(0.25)
@ -264,7 +273,7 @@ def select_on_guards_and_outliers(data_frame, parameters): @@ -264,7 +273,7 @@ def select_on_guards_and_outliers(data_frame, parameters):
pyplot.xlabel("Frame Number [1]")
pyplot.ylabel("Average Intensity [au]")
ax.set_ylim(parameters.charts_y_limit)
path = parameters.data_dir / "7-selected-images-outliers-removed.png"
path = parameters.data_dir / IMAGE_NAMES[7]
pyplot.savefig(str(path))
return selected_df
@ -291,10 +300,7 @@ def smooth_rolling_min(selected_df, parameters): @@ -291,10 +300,7 @@ def smooth_rolling_min(selected_df, parameters):
pyplot.xlabel("Frame Number [1]")
pyplot.ylabel("Average Intensity [au]")
ax.set_ylim(parameters.charts_y_limit)
path = (
parameters.data_dir
/ "8-selected-images-outliers-removed-rolling-min-applied.png"
)
path = parameters.data_dir / IMAGE_NAMES[8]
pyplot.savefig(str(path))
return selected_df
@ -320,10 +326,7 @@ def smooth_savgol_filter(selected_df, parameters): @@ -320,10 +326,7 @@ def smooth_savgol_filter(selected_df, parameters):
)
pyplot.xlabel("Frame Number [1]")
pyplot.ylabel("Average Intensity [au]")
path = (
parameters.data_dir
/ "9-selected-images-outliers-removed-rolling-min-savgol-filtered.png"
)
path = parameters.data_dir / IMAGE_NAMES[9]
pyplot.savefig(str(path))
return selected_df
@ -337,20 +340,6 @@ def find_extremas(selected_df, parameters): @@ -337,20 +340,6 @@ def find_extremas(selected_df, parameters):
min_dist=parameters.peak_min_distance,
)
maximas = selected_df.iloc[max_indexes].copy()
pyplot.clf()
peakplot_iloc(
selected_df["frame"],
selected_df[f"{parameters.roi_name}.savgol"],
max_indexes,
"maxima",
)
pyplot.title(f"Finding Maximas")
pyplot.xlabel("Frame Number [1]")
pyplot.ylabel("Average Intensity [au]")
path = parameters.data_dir / "10-finding-maximas.png"
pyplot.savefig(str(path))
inverted_series = (
max(selected_df[f"{parameters.roi_name}.savgol"])
- selected_df[f"{parameters.roi_name}.savgol"]
@ -372,7 +361,7 @@ def find_extremas(selected_df, parameters): @@ -372,7 +361,7 @@ def find_extremas(selected_df, parameters):
pyplot.title(f"Finding Minimas")
pyplot.xlabel("Frame Number [1]")
pyplot.ylabel("Average Intensity [au]")
path = parameters.data_dir / "11-finding-minimas.png"
path = parameters.data_dir / IMAGE_NAMES[10]
pyplot.savefig(str(path))
maximas["is_maxima"] = True
@ -423,12 +412,14 @@ def create_report(data_frame, selected_df, extremas_df, parameters): @@ -423,12 +412,14 @@ def create_report(data_frame, selected_df, extremas_df, parameters):
num_selected = len(selected_df)
num_discarded = num_images - num_selected
def text_and_graph(text, name):
def text_and_graph(image_nr, text):
flowable = KeepTogether(
[
Paragraph(text, style_text),
Image(
str(data_dir / name), width=img_width, height=img_height
str(data_dir / IMAGE_NAMES[image_nr]),
width=img_width,
height=img_height,
),
Spacer(1, 7 * mm),
]
@ -440,80 +431,72 @@ def create_report(data_frame, selected_df, extremas_df, parameters): @@ -440,80 +431,72 @@ def create_report(data_frame, selected_df, extremas_df, parameters):
Spacer(1, 10 * mm),
Paragraph("Estimating Guard Threshold", style_section),
text_and_graph(
1,
(
"In a first step, the histogram of the combined left and "
"right guard values is calculated."
),
"1-histogram-of-guard-avarages-not-filtered.png",
),
text_and_graph(
2,
(
"A Savitzky-Golay filter is applied to the histogram to "
"smooth the curve."
),
"2-histogram-of-guard-avarages-filtered.png",
),
text_and_graph(
3,
(
"The first minima after the first peak is used as the guard "
f"threshold value: {int(parameters.guard_max_value)} au"
),
"3-histogram-of-guard-avarages-filtered-with-first-minima.png",
),
text_and_graph(
4,
(
"The images with one of the guard values above the threshold "
"are discarded."
),
"4-image-selection-based-on-guard-values.png",
),
Image(
str(data_dir / "5-selected-values-based-on-guard-values.png"),
width=img_width,
height=img_height,
str(data_dir / IMAGE_NAMES[5]), width=img_width, height=img_height
),
PageBreak(),
Paragraph("Removing Outliers", style_section),
text_and_graph(6, "From the remaining values, outliers are removed."),
text_and_graph(
"From the remaining values, outliers are removed.",
"6-boxplot-of-guarded-values.png",
),
text_and_graph(
7,
(
f"From {num_images} images {num_discarded} images were "
f"discarded, leaving {num_selected} selected. The finally "
"selected values are listed in the excel sheet 'selection' "
"in the data file."
),
"7-selected-images-outliers-removed.png",
),
PageBreak(),
Paragraph(
"Experimental: Applying a rolling min calculation", style_section
),
text_and_graph(
8,
(
"Due to the nature of the experiment, unusable images tend "
"to have a higher value as the desiered ones. Therfore a "
"rolling min filter is applied"
),
"8-selected-images-outliers-removed-rolling-min-applied.png",
),
Paragraph("Experimental: Finding Maxima and Minima", style_section),
text_and_graph(
9,
"To smooth the resulting curve, a Savitzky-Golay filter is used.",
(
"9-selected-images-outliers-"
"removed-rolling-min-savgol-filtered.png"
),
),
text_and_graph(
10,
(
"The most interesting data points should be the maxima and "
"minima of this curve. These are listed in the sheet "
"'extremas' in the data file"
),
"11-finding-minimas.png",
),
]
doc.build(story)

186
mtor/gui.py

@ -0,0 +1,186 @@ @@ -0,0 +1,186 @@
from pathlib import Path
home = Path.home()
import sys
from PyQt5.QtWidgets import (
QApplication,
QMainWindow,
QPushButton,
QDesktopWidget,
QHBoxLayout,
QVBoxLayout,
QWidget,
QLabel,
QLineEdit,
QGridLayout,
QFileDialog,
)
from PyQt5.QtGui import QIcon, QIntValidator
from .workflows import (
prescan_workflow,
image_workflow,
data_workflow,
cached_data_workflow,
postprocessing_workflow,
)
class MtorImageAnalysis(QWidget):
def __init__(self):
super().__init__()
self.init_ui()
def init_ui(self):
# analysis parameters
self.analysis_parameters = None
# directory browser
self.dir_label = QLabel("Image Folder")
self.dir_btn = QPushButton("Browse")
self.dir_btn.clicked.connect(self.get_tif_dir)
self.dir_selected = QLabel()
# roi input fields
self.roi_top_label = QLabel("Top edge of ROI")
self.roi_top_input = QLineEdit()
self.roi_top_input.setValidator(QIntValidator())
self.roi_top_input.textChanged.connect(self.check_button_state)
self.roi_left_label = QLabel("Left edge of ROI")
self.roi_left_input = QLineEdit()
self.roi_left_input.setValidator(QIntValidator())
self.roi_left_input.textChanged.connect(self.check_button_state)
self.roi_right_label = QLabel("Right edge of ROI")
self.roi_right_input = QLineEdit()
self.roi_right_input.setValidator(QIntValidator())
self.roi_right_input.textChanged.connect(self.check_button_state)
self.roi_bottom_label = QLabel("Bottom edge of ROI")
self.roi_bottom_input = QLineEdit()
self.roi_bottom_input.setValidator(QIntValidator())
self.roi_bottom_input.textChanged.connect(self.check_button_state)
# action buttons
self.btn_run = QPushButton("Run", self)
self.btn_run.setEnabled(False)
self.btn_run.clicked.connect(self.run_analysis)
self.btn_exit = QPushButton("Exit", self)
self.btn_exit.clicked.connect(QApplication.instance().quit)
# Layout
grid = QGridLayout()
grid.setSpacing(10)
grid.addWidget(self.dir_label, 1, 0)
grid.addWidget(self.dir_btn, 1, 1)
grid.addWidget(self.dir_selected, 2, 0, 1, 2)
grid.addWidget(QLabel(), 3, 0, 1, 2)
grid.addWidget(self.roi_top_label, 4, 0)
grid.addWidget(self.roi_top_input, 4, 1)
grid.addWidget(self.roi_right_label, 5, 0)
grid.addWidget(self.roi_right_input, 5, 1)
grid.addWidget(self.roi_bottom_label, 6, 0)
grid.addWidget(self.roi_bottom_input, 6, 1)
grid.addWidget(self.roi_left_label, 7, 0)
grid.addWidget(self.roi_left_input, 7, 1)
grid.addWidget(QLabel(), 8, 0, 1, 2)
grid.addWidget(self.btn_exit, 9, 0)
grid.addWidget(self.btn_run, 9, 1)
self.setLayout(grid)
#self.resize(350, 300)
self.center_window_on_desktop()
self.setWindowTitle("mTor Image Analysis")
self.setWindowIcon(QIcon("web.png"))
# helpers
self.dir_selected.setText("/Users/holgerfrey/Developer/mtor/mtor-bilder")
self.roi_top_input.setText("50")
self.roi_right_input.setText("875")
self.roi_bottom_input.setText("300")
self.roi_left_input.setText("725")
self.show()
def center_window_on_desktop(self):
cp = QDesktopWidget().availableGeometry().center()
fg = self.frameGeometry()
fg.moveCenter(cp)
self.move(fg.topLeft())
def get_tif_dir(self):
dlg = QFileDialog(directory=str(home))
dlg.setFileMode(QFileDialog.Directory)
if dlg.exec_():
filenames = dlg.selectedFiles()
folder = Path(filenames[0])
items = (i for i in folder.iterdir() if not i.stem.startswith("."))
tifs = [i for i in items if i.suffix == ".tif"]
if len(tifs) == 0:
self.dir_selected.setText("")
self.check_button_state()
else:
self.dir_selected.setText(filenames[0])
self.check_button_state()
def check_button_state(self):
values = self.get_values()
self.btn_run.setEnabled(all(values))
def get_values(self):
fields = [
(self.dir_selected, str),
(self.roi_top_input, int),
(self.roi_right_input, int),
(self.roi_bottom_input, int),
(self.roi_left_input, int),
]
result = []
for field, func in fields:
raw_data = field.text().strip()
if raw_data:
if func is int:
# in qt5, a point as 1000 separator is allowed
raw_data = raw_data.replace(".", "")
result.append(func(raw_data))
else:
result.append(None)
return tuple(result)
def run_analysis(self):
parameters = self.get_values()
if all(parameters):
self.analysis_parameters = parameters
self.hide()
QApplication.instance().quit()
def run_gui():
app = QApplication(sys.argv)
mia = MtorImageAnalysis()
app.exec_()
if mia.analysis_parameters is not None:
analysis_parameters = tuple( (p for p in mia.analysis_parameters) )
pw = prescan_workflow(*analysis_parameters)
iw = image_workflow(pw.parameters)
dw = data_workflow(iw.data, iw.parameters)
fw = postprocessing_workflow(dw.data, dw.parameters) # noqa: F841
sys.exit()

4
setup.py

@ -8,9 +8,6 @@ from setuptools import setup, find_packages @@ -8,9 +8,6 @@ from setuptools import setup, find_packages
with open("README.md") as readme_file:
readme = readme_file.read()
with open("HISTORY.rst") as history_file:
history = history_file.read()
requirements = [
"Click>=6.0",
"pandas>=0.24",
@ -25,6 +22,7 @@ requirements = [ @@ -25,6 +22,7 @@ requirements = [
"xlwt>=1.3",
"xlsxwriter>=1.1",
"reportlab>=3.5",
"PyQt5>=5.12"
]
setup_requirements = [ ]

316
test.py

@ -1,316 +1,4 @@ @@ -1,316 +1,4 @@
from pathlib import Path
from PIL import Image, ImageOps
from tqdm import tqdm
import numpy
import skimage
import warnings
from mtor.gui import run_gui
FIRE_LUT = [
0, 0, 0,
0, 0, 7,
0, 0, 15,
0, 0, 22,
0, 0, 30,
0, 0, 38,
0, 0, 45,
0, 0, 53,
0, 0, 61,
0, 0, 65,
0, 0, 69,
0, 0, 74,
0, 0, 78,
0, 0, 82,
0, 0, 87,
0, 0, 91,
1, 0, 96,
4, 0, 100,
7, 0, 104,
10, 0, 108,
13, 0, 113,
16, 0, 117,
19, 0, 121,
22, 0, 125,
25, 0, 130,
28, 0, 134,
31, 0, 138,
34, 0, 143,
37, 0, 147,
40, 0, 151,
43, 0, 156,
46, 0, 160,
49, 0, 165,
52, 0, 168,
55, 0, 171,
58, 0, 175,
61, 0, 178,
64, 0, 181,
67, 0, 185,
70, 0, 188,
73, 0, 192,
76, 0, 195,
79, 0, 199,
82, 0, 202,
85, 0, 206,
88, 0, 209,
91, 0, 213,
94, 0, 216,
98, 0, 220,
101, 0, 220,
104, 0, 221,
107, 0, 222,
110, 0, 223,
113, 0, 224,
116, 0, 225,
119, 0, 226,
122, 0, 227,
125, 0, 224,
128, 0, 222,
131, 0, 220,
134, 0, 218,
137, 0, 216,
140, 0, 214,
143, 0, 212,
146, 0, 210,
148, 0, 206,
150, 0, 202,
152, 0, 199,
154, 0, 195,
156, 0, 191,
158, 0, 188,
160, 0, 184,
162, 0, 181,
163, 0, 177,
164, 0, 173,
166, 0, 169,
167, 0, 166,
168, 0, 162,
170, 0, 158,
171, 0, 154,
173, 0, 151,
174, 0, 147,
175, 0, 143,
177, 0, 140,
178, 0, 136,
179, 0, 132,
181, 0, 129,
182, 0, 125,
184, 0, 122,
185, 0, 118,
186, 0, 114,
188, 0, 111,
189, 0, 107,
190, 0, 103,
192, 0, 100,
193, 0, 96,
195, 0, 93,
196, 1, 89,
198, 3, 85,
199, 5, 82,
201, 7, 78,
202, 8, 74,
204, 10, 71,
205, 12, 67,
207, 14, 64,
208, 16, 60,
209, 19, 56,
210, 21, 53,
212, 24, 49,
213, 27, 45,
214, 29, 42,
215, 32, 38,
217, 35, 35,
218, 37, 31,
220, 40, 27,
221, 43, 23,
223, 46, 20,
224, 48, 16,
226, 51, 12,
227, 54, 8,
229, 57, 5,
230, 59, 4,
231, 62, 3,
233, 65, 3,
234, 68, 2,
235, 70, 1,
237, 73, 1,
238, 76, 0,
240, 79, 0,
241, 81, 0,
243, 84, 0,
244, 87, 0,
246, 90, 0,
247, 92, 0,
249, 95, 0,
250, 98, 0,
252, 101, 0,
252, 103, 0,
252, 105, 0,
253, 107, 0,
253, 109, 0,
253, 111, 0,
254, 113, 0,
254, 115, 0,
255, 117, 0,
255, 119, 0,
255, 121, 0,
255, 123, 0,
255, 125, 0,
255, 127, 0,
255, 129, 0,
255, 131, 0,
255, 133, 0,
255, 134, 0,
255, 136, 0,
255, 138, 0,
255, 140, 0,
255, 141, 0,
255, 143, 0,
255, 145, 0,
255, 147, 0,
255, 148, 0,
255, 150, 0,
255, 152, 0,
255, 154, 0,
255, 155, 0,
255, 157, 0,
255, 159, 0,
255, 161, 0,
255, 162, 0,
255, 164, 0,
255, 166, 0,
255, 168, 0,
255, 169, 0,
255, 171, 0,
255, 173, 0,
255, 175, 0,
255, 176, 0,
255, 178, 0,
255, 180, 0,
255, 182, 0,
255, 184, 0,
255, 186, 0,
255, 188, 0,
255, 190, 0,
255, 191, 0,
255, 193, 0,
255, 195, 0,
255, 197, 0,
255, 199, 0,
255, 201, 0,
255, 203, 0,
255, 205, 0,
255, 206, 0,
255, 208, 0,
255, 210, 0,
255, 212, 0,
255, 213, 0,
255, 215, 0,
255, 217, 0,
255, 219, 0,
255, 220, 0,
255, 222, 0,
255, 224, 0,
255, 226, 0,
255, 228, 0,
255, 230, 0,
255, 232, 0,
255, 234, 0,
255, 235, 4,
255, 237, 8,
255, 239, 13,
255, 241, 17,
255, 242, 21,
255, 244, 26,
255, 246, 30,
255, 248, 35,
255, 248, 42,
255, 249, 50,
255, 250, 58,
255, 251, 66,
255, 252, 74,
255, 253, 82,
255, 254, 90,
255, 255, 98,
255, 255, 105,
255, 255, 113,
255, 255, 121,
255, 255, 129,
255, 255, 136,
255, 255, 144,
255, 255, 152,
255, 255, 160,
255, 255, 167,
255, 255, 175,
255, 255, 183,
255, 255, 191,
255, 255, 199,
255, 255, 207,
255, 255, 215,
255, 255, 223,
255, 255, 227,
255, 255, 231,
255, 255, 235,
255, 255, 239,
255, 255, 243,
255, 255, 247,
255, 255, 251,
255, 255, 255,
255, 255, 255,
255, 255, 255,
255, 255, 255,
255, 255, 255,
255, 255, 255,
255, 255, 255,
255, 255, 255,
]
run_gui()
tif_dir = Path("original_tifs")
png_dir = Path("auto_pngs")
for item in png_dir.iterdir():
item.unlink()
visible_items = (i for i in tif_dir.iterdir() if not i.stem.startswith("."))
tifs = [i for i in visible_items if i.suffix == ".tif"]
lowest = 2**16
lowest = 309
highest = 0
highest = 23922//4
print("1/3: scanning tifs for common autocontrast values")
for path in tqdm(tifs):
break
with path.open("rb") as filehandle:
image = Image.open(filehandle)
mi, ma = image.getextrema()
lowest = min(lowest, mi)
highest = max(highest, ma)
print("lowest intensity found: ", lowest)
print("highest intensity found: ", highest)
scaling_factor = highest / 255
print("2/3: adjusting contrast, converting to png")
for path in tqdm(tifs):
break
with path.open("rb") as filehandle:
image = Image.open(filehandle)
image_array = numpy.array(image, dtype=numpy.int32)
converted = Image.fromarray((image_array - lowest) // scaling_factor)
adjusted = converted.convert(mode="L").convert(mode="P")
adjusted.putpalette(FIRE_LUT)
png_path = png_dir / (path.stem + ".png")
with png_path.open("wb") as outhandle:
adjusted.save(outhandle)
cut = image_array[50:300,660:910]
import mtor
print(mtor.analyse_cut(cut))
#x = 660, 50,
#w, h = 250, 250

Loading…
Cancel
Save