Skip to content
This repository was archived by the owner on Apr 1, 2026. It is now read-only.

Commit 95ddb39

Browse files
author
LAKESIDE\LindaT18
committed
initial work on image analysis
1 parent 079a67f commit 95ddb39

3 files changed

Lines changed: 269 additions & 2 deletions

File tree

PythonGUI_apps/DataBrowser.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
from UV_Vis_analysis import uv_vis_analysis
1919
from PLQE_analysis import plqe_analysis
2020
from H5_Pkl import h5_pkl_view, h5_view_and_plot
21-
21+
from Image_analysis import Image_analysis
2222
pg.mkQApp()
2323
#pg.setConfigOption('background', 'w')
2424

@@ -38,7 +38,7 @@ def __init__(self):
3838
self.ui = WindowTemplate()
3939
self.ui.setupUi(self)
4040
self.ui.select_comboBox.addItems(["Lifetime Analysis", "Spectrum Analysis", "FLIM Analysis",
41-
"UV-Vis Analysis", "PLQE Analysis", "H5 View/Plot", "H5/PKL Viewer"])
41+
"UV-Vis Analysis", "PLQE Analysis", "H5 View/Plot", "H5/PKL Viewer", "Image Analysis"])
4242
self.ui.load_pushButton.clicked.connect(self.load_app)
4343

4444
self.show()
@@ -69,6 +69,9 @@ def load_app(self):
6969
elif analysis_software == "H5/PKL Viewer":
7070
app = h5_pkl_view.H5PklView(sys.argv)
7171
#sys.exit(app.exec_())
72+
elif analysis_software == "Image Analysis":
73+
self.image_window = Image_analysis.MainWindow()
74+
self.image_window.show()
7275

7376

7477

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
import sys
2+
from pathlib import Path
3+
import os.path
4+
import pyqtgraph as pg
5+
from pyqtgraph.Qt import QtCore, QtGui, QtWidgets#, QColorDialog
6+
import numpy as np
7+
import matplotlib.pyplot as plt
8+
from PIL import Image
9+
10+
# local modules
11+
12+
pg.mkQApp()
13+
14+
base_path = Path(__file__).parent
15+
file_path = (base_path / "image_analysis_gui.ui").resolve()
16+
17+
uiFile = file_path
18+
19+
WindowTemplate, TemplateBaseClass = pg.Qt.loadUiType(uiFile)
20+
21+
class MainWindow(TemplateBaseClass):
22+
23+
def __init__(self):
24+
super(TemplateBaseClass, self).__init__()
25+
26+
# Create the main window
27+
self.ui = WindowTemplate()
28+
self.ui.setupUi(self)
29+
30+
#setup imageview
31+
self.imv = pg.ImageView()
32+
self.imv.getView().setAspectLocked(lock=False, ratio=1)
33+
self.imv.getView().setMouseEnabled(x=True, y=True)
34+
self.imv.getView().invertY(False)
35+
self.roi = self.imv.roi
36+
self.roi.translateSnap = True
37+
self.roi.scaleSnap = True
38+
self.calc_scaling_factor() #initialize scaling_factor
39+
self.roi.snapSize = self.scaling_factor #roi snaps to multiples of scaling_factor
40+
self.roi.sigRegionChanged.connect(self.line_profile_update_plot)
41+
self.roi_plot = self.imv.getRoiPlot().getPlotItem()
42+
43+
self.ui.image_groupBox.layout().addWidget(self.imv)
44+
45+
#set up ui signals
46+
self.ui.load_image_pushButton.clicked.connect(self.load_image)
47+
self.ui.custom_pixel_size_checkBox.stateChanged.connect(self.switch_custom_pixel_size)
48+
49+
self.show()
50+
51+
def load_image(self):
52+
"""
53+
Prompts the user to select a text file containing image data.
54+
"""
55+
try:
56+
file = QtWidgets.QFileDialog.getOpenFileName(self, 'Open file', os.getcwd())
57+
image = Image.open(file[0])
58+
image = image.rotate(-90, expand=True)
59+
image_array = np.asarray(image)
60+
try:
61+
width = image_array.shape[0]
62+
height = image_array.shape[1]
63+
x_vals = np.arange(width)
64+
self.imv.setImage(img=image_array, xvals= x_vals)
65+
self.calc_scaling_factor()
66+
self.roi.setPos((0,0))
67+
self.roi.setSize([width, height*self.scaling_factor]) #set line roi
68+
self.line_profile_update_plot()
69+
except:
70+
pass
71+
except Exception as err:
72+
print(format(err))
73+
74+
def line_profile_update_plot(self):
75+
""" Handle line profile for intensity sum viewbox """
76+
#if hasattr(self, "intensity_sums"):
77+
self.roi_plot.clear()
78+
79+
image = self.imv.getProcessedImage()
80+
81+
# Extract image data from ROI
82+
axes = (self.imv.axes['x'], self.imv.axes['y'])
83+
data, coords = self.roi.getArrayRegion(image.view(np.ndarray), self.imv.imageItem, axes, returnMappedCoords=True)
84+
if data is None:
85+
return
86+
87+
self.calc_scaling_factor()
88+
x_values = coords[1][0] * self.scaling_factor #adjust x-axis roi plot
89+
90+
#calculate sums along columns in region
91+
if len(data.shape) == 2: #if grayscale, average intensities
92+
sums_to_plot = np.mean(data, axis=0)
93+
try:
94+
self.roi_plot.plot(x_values, sums_to_plot)
95+
except:
96+
pass
97+
elif len(data.shape) > 2: #if rgb arrays, plot individual components
98+
r_values = data[:,:,0]
99+
g_values = data[:,:,1]
100+
b_values = data[:,:,2]
101+
r_avg = np.mean(r_values, axis=0) #average red values across columns
102+
g_avg = np.mean(g_values, axis=0) #average green values
103+
b_avg = np.mean(b_values, axis=0) #average blue values
104+
try:
105+
self.roi_plot.plot(x_values, r_avg, pen='r')
106+
self.roi_plot.plot(x_values, g_avg, pen='g')
107+
self.roi_plot.plot(x_values, b_avg, pen='b')
108+
except:
109+
pass
110+
111+
def calc_scaling_factor(self):
112+
"""
113+
Calculate scaling factor
114+
"""
115+
if self.ui.custom_pixel_size_checkBox.isChecked():
116+
self.scaling_factor = self.ui.custom_pixel_size_spinBox.value()
117+
else:
118+
pixel_size = 7.4
119+
self.scaling_factor = pixel_size/int(self.ui.magnification_comboBox.currentText())
120+
121+
def switch_custom_pixel_size(self):
122+
checked = self.ui.custom_pixel_size_checkBox.isChecked()
123+
self.ui.custom_pixel_size_spinBox.setEnabled(checked)
124+
self.ui.magnification_comboBox.setEnabled(not checked)
125+
126+
def close_application(self):
127+
choice = QtGui.QMessageBox.question(self, 'EXIT!',
128+
"Do you want to exit the app?",
129+
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No)
130+
if choice == QtGui.QMessageBox.Yes:
131+
sys.exit()
132+
else:
133+
pass
134+
135+
"""Run the Main Window"""
136+
def run():
137+
win = MainWindow()
138+
QtGui.QApplication.instance().exec_()
139+
return win
140+
141+
#Uncomment below if you want to run this as standalone
142+
#run()
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<ui version="4.0">
3+
<class>MainWindow</class>
4+
<widget class="QMainWindow" name="MainWindow">
5+
<property name="geometry">
6+
<rect>
7+
<x>0</x>
8+
<y>0</y>
9+
<width>1050</width>
10+
<height>743</height>
11+
</rect>
12+
</property>
13+
<property name="windowTitle">
14+
<string>MainWindow</string>
15+
</property>
16+
<property name="tabShape">
17+
<enum>QTabWidget::Triangular</enum>
18+
</property>
19+
<widget class="QWidget" name="centralwidget">
20+
<layout class="QGridLayout" name="gridLayout_2">
21+
<item row="0" column="0">
22+
<widget class="QGroupBox" name="image_groupBox">
23+
<property name="sizePolicy">
24+
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
25+
<horstretch>0</horstretch>
26+
<verstretch>0</verstretch>
27+
</sizepolicy>
28+
</property>
29+
<property name="minimumSize">
30+
<size>
31+
<width>600</width>
32+
<height>0</height>
33+
</size>
34+
</property>
35+
<property name="title">
36+
<string>Image</string>
37+
</property>
38+
<layout class="QGridLayout" name="gridLayout_3"/>
39+
</widget>
40+
</item>
41+
<item row="0" column="1">
42+
<widget class="QGroupBox" name="groupBox_2">
43+
<property name="title">
44+
<string>Settings</string>
45+
</property>
46+
<layout class="QGridLayout" name="gridLayout_4">
47+
<item row="2" column="0">
48+
<widget class="QWidget" name="line_profile_placeholder" native="true">
49+
<layout class="QGridLayout" name="gridLayout_7"/>
50+
</widget>
51+
</item>
52+
<item row="0" column="0">
53+
<layout class="QGridLayout" name="gridLayout">
54+
<item row="0" column="0" colspan="2">
55+
<widget class="QPushButton" name="load_image_pushButton">
56+
<property name="text">
57+
<string>Load image</string>
58+
</property>
59+
</widget>
60+
</item>
61+
<item row="0" column="3">
62+
<widget class="QComboBox" name="magnification_comboBox">
63+
<item>
64+
<property name="text">
65+
<string>50</string>
66+
</property>
67+
</item>
68+
<item>
69+
<property name="text">
70+
<string>75</string>
71+
</property>
72+
</item>
73+
<item>
74+
<property name="text">
75+
<string>100</string>
76+
</property>
77+
</item>
78+
</widget>
79+
</item>
80+
<item row="0" column="2">
81+
<widget class="QLabel" name="label_7">
82+
<property name="text">
83+
<string>Magnification</string>
84+
</property>
85+
</widget>
86+
</item>
87+
<item row="1" column="2">
88+
<widget class="QCheckBox" name="custom_pixel_size_checkBox">
89+
<property name="text">
90+
<string>Custom pixel size (um)</string>
91+
</property>
92+
</widget>
93+
</item>
94+
<item row="1" column="3">
95+
<widget class="QDoubleSpinBox" name="custom_pixel_size_spinBox">
96+
<property name="enabled">
97+
<bool>false</bool>
98+
</property>
99+
</widget>
100+
</item>
101+
</layout>
102+
</item>
103+
</layout>
104+
</widget>
105+
</item>
106+
</layout>
107+
</widget>
108+
<widget class="QMenuBar" name="menubar">
109+
<property name="geometry">
110+
<rect>
111+
<x>0</x>
112+
<y>0</y>
113+
<width>1050</width>
114+
<height>31</height>
115+
</rect>
116+
</property>
117+
</widget>
118+
<widget class="QStatusBar" name="statusbar"/>
119+
</widget>
120+
<resources/>
121+
<connections/>
122+
</ui>

0 commit comments

Comments
 (0)