Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
7
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Open sidebar
GEPARD
GEPARD
Commits
34439505
Commit
34439505
authored
Aug 27, 2020
by
Josef Brandt
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'CoordinateTransfer' into MergingIntoTiling2Develop
parents
11fdf4ed
228a27cc
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
570 additions
and
119 deletions
+570
-119
__main__.py
__main__.py
+13
-8
dataset.py
dataset.py
+27
-23
fakeData/image.bmp
fakeData/image.bmp
+0
-0
gui/coordTransferGUI.py
gui/coordTransferGUI.py
+275
-0
helperfunctions.py
helperfunctions.py
+15
-1
opticalbackground.py
opticalbackground.py
+1
-1
opticalscan.py
opticalscan.py
+44
-46
ramanscanui.py
ramanscanui.py
+11
-9
sampleview.py
sampleview.py
+41
-13
tests/test_simulatedStage.py
tests/test_simulatedStage.py
+127
-0
viewitems.py
viewitems.py
+3
-3
zeissimporter.py
zeissimporter.py
+13
-15
No files found.
__main__.py
View file @
34439505
...
...
@@ -83,8 +83,7 @@ class GEPARDMainWindow(QtWidgets.QMainWindow):
@
QtCore
.
pyqtSlot
()
def
open
(
self
,
fileName
=
False
):
if
fileName
is
False
:
fileName
=
QtWidgets
.
QFileDialog
.
getOpenFileName
(
self
,
"Open Project"
,
defaultPath
,
"*.pkl"
)[
0
]
fileName
=
QtWidgets
.
QFileDialog
.
getOpenFileName
(
self
,
"Open Project"
,
defaultPath
,
"*.pkl"
)[
0
]
if
fileName
:
self
.
fname
=
str
(
fileName
)
self
.
view
.
open
(
self
.
fname
)
...
...
@@ -204,6 +203,10 @@ class GEPARDMainWindow(QtWidgets.QMainWindow):
self
.
configRamanCtrlAct
.
triggered
.
connect
(
self
.
view
.
configureRamanControl
)
if
self
.
view
.
simulatedRaman
:
self
.
configRamanCtrlAct
.
setDisabled
(
True
)
self
.
recalculateCoordAct
=
QtWidgets
.
QAction
(
"&Recalculate Coordinate System"
)
self
.
recalculateCoordAct
.
setDisabled
(
True
)
self
.
recalculateCoordAct
.
triggered
.
connect
(
self
.
view
.
recalculateCoordinateSystem
)
self
.
noOverlayAct
=
QtWidgets
.
QAction
(
"&No Overlay"
,
self
)
self
.
noOverlayAct
.
setShortcut
(
"1"
)
...
...
@@ -224,18 +227,18 @@ class GEPARDMainWindow(QtWidgets.QMainWindow):
def
updateModes
(
self
,
active
=
None
,
maxenabled
=
None
):
ose
,
osc
,
pde
,
pdc
,
rse
,
rsc
=
[
False
]
*
6
if
maxenabled
==
"OpticalScan"
:
if
maxenabled
==
"OpticalScan"
:
ose
=
True
elif
maxenabled
==
"ParticleDetection"
:
elif
maxenabled
==
"ParticleDetection"
:
ose
,
pde
=
True
,
True
elif
maxenabled
==
"RamanScan"
:
elif
maxenabled
==
"RamanScan"
:
ose
,
pde
,
rse
=
True
,
True
,
True
if
active
==
"OpticalScan"
and
ose
:
if
active
==
"OpticalScan"
and
ose
:
osc
=
True
elif
active
==
"ParticleDetection"
and
pde
:
elif
active
==
"ParticleDetection"
and
pde
:
pdc
=
True
elif
active
==
"RamanScan"
and
rse
:
elif
active
==
"RamanScan"
and
rse
:
rsc
=
True
self
.
opticalScanAct
.
setEnabled
(
ose
)
...
...
@@ -293,6 +296,7 @@ class GEPARDMainWindow(QtWidgets.QMainWindow):
self
.
toolsMenu
=
QtWidgets
.
QMenu
(
"&Tools"
)
self
.
toolsMenu
.
addAction
(
self
.
snapshotAct
)
self
.
toolsMenu
.
addAction
(
self
.
configRamanCtrlAct
)
self
.
toolsMenu
.
addAction
(
self
.
recalculateCoordAct
)
self
.
dispMenu
=
QtWidgets
.
QMenu
(
"&Display"
,
self
)
self
.
overlayActGroup
=
QtWidgets
.
QActionGroup
(
self
.
dispMenu
)
...
...
@@ -334,6 +338,7 @@ class GEPARDMainWindow(QtWidgets.QMainWindow):
self
.
toolbar
.
setOrientation
(
QtCore
.
Qt
.
Vertical
)
self
.
addToolBar
(
QtCore
.
Qt
.
LeftToolBarArea
,
self
.
toolbar
)
if
__name__
==
'__main__'
:
import
sys
from
time
import
localtime
,
strftime
...
...
dataset.py
View file @
34439505
...
...
@@ -24,6 +24,7 @@ import numpy as np
import
sys
import
cv2
from
copy
import
copy
from
typing
import
List
from
.analysis.particleContainer
import
ParticleContainer
from
.legacyConvert
import
legacyConversion
,
currentVersion
from
.helperfunctions
import
cv2imwrite_fix
,
cv2imread_fix
...
...
@@ -31,9 +32,11 @@ from .helperfunctions import cv2imwrite_fix, cv2imread_fix
# (no relative import)
from
.
import
dataset
from
.
import
analysis
from
.coordinatetransform
import
TrayMarker
,
ImageMarker
sys
.
modules
[
'dataset'
]
=
dataset
sys
.
modules
[
'analysis'
]
=
analysis
def
loadData
(
fname
):
retds
=
None
with
open
(
fname
,
"rb"
)
as
fp
:
...
...
@@ -120,11 +123,11 @@ class DataSet(object):
self
.
version
=
currentVersion
self
.
lastpos
=
None
self
.
maxdim
=
None
self
.
pixelscale_df
=
None
# µm / pixel --> scale of DARK FIELD camera (used for image stitching)
self
.
pixelscale_bf
=
None
# µm / pixel of DARK FIELD camera (set to same as bright field, if both use the same camera)
self
.
pixelscale_df
=
None
# µm / pixel --> scale of DARK FIELD camera (used for image stitching)
self
.
pixelscale_bf
=
None
# µm / pixel of DARK FIELD camera (set to same as bright field, if both use the same camera)
self
.
imagedim_bf
=
None
# width, height, angle of BRIGHT FIELD camera
self
.
imagedim_df
=
None
# width, height, angle of DARK FIELD camera (set to same as bright field, if both use the same camera)
self
.
imagescanMode
=
'df'
#was the fullimage acquired in dark- or brightfield?
self
.
imagescanMode
=
'df'
#
was the fullimage acquired in dark- or brightfield?
self
.
fitpoints
=
[]
# manually adjusted positions aquired to define the specimen geometry
self
.
fitindices
=
[]
# which of the five positions in the ui are already known
self
.
boundary
=
[]
# scan boundary computed by a circle around the fitpoints + manual adjustments
...
...
@@ -132,7 +135,9 @@ class DataSet(object):
self
.
zpositions
=
[]
# z-positions for optical scan
self
.
heightmap
=
None
self
.
zvalimg
=
None
self
.
coordinatetransform
=
None
# if imported form extern source coordinate system may be rotated
self
.
coordinatetransform
=
None
# if imported form extern source coordinate system may be rotated
self
.
trayMarkers
:
List
[
TrayMarker
]
=
[]
# list of markers on the sample tray
self
.
imageMarkers
:
List
[
ImageMarker
]
=
[]
# list of coordinate markers within the image
self
.
signx
=
1.
self
.
signy
=
-
1.
...
...
@@ -141,7 +146,6 @@ class DataSet(object):
# parameters specifically for raman scan
self
.
pshift
=
None
# shift of raman scan position relative to image center
self
.
coordOffset
=
[
0
,
0
]
#offset of entire coordinate system
self
.
seedpoints
=
np
.
array
([])
self
.
seeddeletepoints
=
np
.
array
([])
self
.
detectParams
=
{
'points'
:
np
.
array
([[
50
,
0
],[
100
,
200
],[
200
,
255
]]),
...
...
@@ -219,31 +223,31 @@ class DataSet(object):
p0
=
copy
(
self
.
lastpos
)
if
self
.
coordinatetransform
is
not
None
:
z
=
0.
if
len
(
p
)
<
3
else
p
[
2
]
z
=
0.
if
len
(
p
)
<
3
else
p
[
2
]
T
,
pc
=
self
.
coordinatetransform
p
=
(
np
.
dot
(
np
.
array
([
p
[
0
],
p
[
1
],
z
])
-
pc
,
T
.
T
))
if
mode
==
'df'
:
p0
[
0
]
-=
self
.
signx
*
self
.
imagedim_df
[
0
]
/
2
p0
[
1
]
-=
self
.
signy
*
self
.
imagedim_df
[
1
]
/
2
x
,
y
=
self
.
signx
*
(
p
[
0
]
-
p0
[
0
])
/
self
.
pixelscale_df
,
self
.
signy
*
(
p
[
1
]
-
p0
[
1
])
/
self
.
pixelscale_df
elif
mode
==
'bf'
:
p0
[
0
]
-=
self
.
signx
*
self
.
imagedim_bf
[
0
]
/
2
p0
[
1
]
-=
self
.
signy
*
self
.
imagedim_bf
[
1
]
/
2
x
,
y
=
self
.
signx
*
(
p
[
0
]
-
p0
[
0
])
/
self
.
pixelscale_bf
,
self
.
signy
*
(
p
[
1
]
-
p0
[
1
])
/
self
.
pixelscale_bf
else
:
raise
ValueError
(
f
'mapToPixel mode:
{
mode
}
not understood'
)
assert
mode
in
[
'df'
,
'bf'
],
f
'mapToPixel mode:
{
mode
}
not understood'
pixelscale
:
float
=
self
.
pixelscale_bf
if
mode
==
'bf'
else
self
.
pixelscale_df
p0
[
0
]
-=
self
.
signx
*
self
.
imagedim_df
[
0
]
/
2
p0
[
1
]
-=
self
.
signy
*
self
.
imagedim_df
[
1
]
/
2
x
,
y
=
self
.
signx
*
(
p
[
0
]
-
p0
[
0
])
/
pixelscale
,
self
.
signy
*
(
p
[
1
]
-
p0
[
1
])
/
pixelscale
# TODO: SANITY CHECK AT REAL INSTRUMENT IF THE BELOW CODE CAN BE REMOVED (WAS SUBSTITUTED BY THE 4 LINES ABOVE)
# if mode == 'df':
# p0[0] -= self.signx*self.imagedim_df[0]/2
# p0[1] -= self.signy*self.imagedim_df[1]/2
# x, y = self.signx*(p[0] - p0[0])/self.pixelscale_df, self.signy*(p[1] - p0[1])/self.pixelscale_df
#
# elif mode == 'bf':
# p0[0] -= self.signx*self.imagedim_bf[0]/2
# p0[1] -= self.signy*self.imagedim_bf[1]/2
# x, y = self.signx*(p[0] - p0[0])/self.pixelscale_bf, self.signy*(p[1] - p0[1])/self.pixelscale_bf
return
x
,
y
def
mapToLength
(
self
,
pixelpos
,
mode
=
'df'
,
force
=
False
,
returnz
=
False
):
if
not
force
:
assert
not
self
.
readin
p0
=
copy
(
self
.
lastpos
)
p0
[
0
]
+=
self
.
coordOffset
[
0
]
p0
[
1
]
+=
self
.
coordOffset
[
1
]
if
mode
==
'df'
:
p0
[
0
]
-=
self
.
signx
*
self
.
imagedim_df
[
0
]
/
2
p0
[
1
]
-=
self
.
signy
*
self
.
imagedim_df
[
1
]
/
2
...
...
@@ -262,7 +266,7 @@ class DataSet(object):
if
self
.
coordinatetransform
is
not
None
:
T
,
pc
=
self
.
coordinatetransform
x
,
y
,
z
=
(
np
.
dot
(
np
.
array
([
x
,
y
,
z
]),
T
)
+
pc
)
x
,
y
,
z
=
(
np
.
dot
(
np
.
array
([
x
,
y
,
z
]),
T
)
+
pc
)
if
returnz
:
return
x
,
y
,
z
...
...
fakeData/image.bmp
deleted
100644 → 0
View file @
11fdf4ed
1.03 MB
gui/coordTransferGUI.py
0 → 100644
View file @
34439505
from
PyQt5
import
QtWidgets
,
QtGui
,
QtCore
import
numpy
as
np
from
typing
import
List
from
copy
import
deepcopy
from
..coordinatetransform
import
ImageMarker
,
TrayMarker
,
getTransform
from
..ramancom.ramanbase
import
RamanBase
class
CoordTransformUI
(
QtWidgets
.
QWidget
):
def
__init__
(
self
,
viewParent
):
super
(
CoordTransformUI
,
self
).
__init__
()
self
.
setWindowTitle
(
'Recalculate Coordinate System'
)
self
.
setWindowFlags
(
QtCore
.
Qt
.
WindowStaysOnTopHint
)
self
.
viewParent
=
viewParent
self
.
ramanctrl
:
RamanBase
=
self
.
viewParent
.
ramanctrl
self
.
imageMarkers
:
List
[
ImageMarker
]
=
[]
# in the new coord system
self
.
newImageMarkers
:
List
[
ImageMarker
]
=
[]
self
.
imageMarkerWidgets
:
List
[
CoordinateSystemMarker
]
=
[]
self
.
trayMarkers
:
List
[
TrayMarker
]
=
[]
# in the new coord system
self
.
newTrayMarkers
:
List
[
TrayMarker
]
=
[]
# in the new coord system
self
.
layout
=
QtWidgets
.
QVBoxLayout
()
self
.
setLayout
(
self
.
layout
)
selectionLayout
=
QtWidgets
.
QHBoxLayout
()
self
.
trayMarkersBtn
:
QtWidgets
.
QRadioButton
=
QtWidgets
.
QRadioButton
(
'Use Tray Markers'
)
self
.
trayMarkersBtn
.
pressed
.
connect
(
self
.
_useTrayMarkers
)
self
.
trayMarkersBtn
.
setChecked
(
True
)
self
.
imgMarkersBtn
:
QtWidgets
.
QRadioButton
=
QtWidgets
.
QRadioButton
(
'Use Image Markers'
)
self
.
imgMarkersBtn
.
pressed
.
connect
(
self
.
_useImageMarkers
)
selectionLayout
.
addWidget
(
self
.
trayMarkersBtn
)
selectionLayout
.
addWidget
(
self
.
imgMarkersBtn
)
self
.
addMarkerBtn
:
QtWidgets
.
QPushButton
=
QtWidgets
.
QPushButton
(
'Add New Markers'
)
self
.
addMarkerBtn
.
setStyleSheet
(
"background-color : lightgrey"
)
self
.
_formatAsToggleBtn
(
self
.
addMarkerBtn
)
self
.
transferResult
:
QtWidgets
.
QLabel
=
QtWidgets
.
QLabel
(
'No valid input'
)
self
.
trayMarkerGroup
:
QtWidgets
.
QGroupBox
=
self
.
_getTrayMarkerGroup
()
self
.
imgMarkerGroup
:
QtWidgets
.
QGroupBox
=
self
.
_getImageMarkerGroup
()
saveBtn
:
QtWidgets
.
QPushButton
=
QtWidgets
.
QPushButton
(
'Save to Dataset'
)
saveBtn
.
clicked
.
connect
(
self
.
_saveToDataset
)
self
.
layout
.
addLayout
(
selectionLayout
)
self
.
layout
.
addWidget
(
self
.
trayMarkerGroup
)
self
.
layout
.
addWidget
(
self
.
transferResult
)
self
.
layout
.
addWidget
(
saveBtn
)
self
.
_getMarkersFromDataset
()
def
_getMarkersFromDataset
(
self
)
->
None
:
if
self
.
viewParent
is
not
None
:
self
.
trayMarkers
=
deepcopy
(
self
.
viewParent
.
dataset
.
trayMarkers
)
self
.
imageMarkers
=
deepcopy
(
self
.
viewParent
.
dataset
.
imageMarkers
)
for
index
,
imgMarker
in
enumerate
(
self
.
imageMarkers
):
pxPos
:
tuple
=
(
imgMarker
.
imgCoordX
,
imgMarker
.
imgCoordY
)
newMarkerWidget
:
CoordinateSystemMarker
=
CoordinateSystemMarker
(
index
,
pxPos
)
self
.
imageMarkerWidgets
.
append
(
newMarkerWidget
)
self
.
viewParent
.
scene
().
addItem
(
newMarkerWidget
)
def
_formatAsToggleBtn
(
self
,
btn
:
QtWidgets
.
QPushButton
)
->
None
:
btn
.
setCheckable
(
True
)
btn
.
setChecked
(
False
)
btn
.
clicked
.
connect
(
lambda
:
self
.
_setBtnColor
(
btn
))
def
_getTrayMarkerGroup
(
self
)
->
QtWidgets
.
QGroupBox
:
layout
=
QtWidgets
.
QGridLayout
()
group
:
QtWidgets
.
QGroupBox
=
QtWidgets
.
QGroupBox
(
'Sample Tray Markers'
)
group
.
setLayout
(
layout
)
if
len
(
self
.
trayMarkers
)
==
0
:
layout
.
addWidget
(
QtWidgets
.
QLabel
(
'No tray markers found.'
))
for
i
in
range
(
3
):
layout
.
addWidget
(
QtWidgets
.
QLabel
(
'New Marker Placeholder'
))
return
group
def
_getImageMarkerGroup
(
self
)
->
QtWidgets
.
QGroupBox
:
def
makeCenterOnLambda
(
ind
):
return
lambda
:
self
.
_centerOnImageMarker
(
ind
)
def
makeDeleteLambda
(
ind
):
return
lambda
:
self
.
_deleteImageMarker
(
ind
)
def
makeReadNewPosLambda
(
ind
):
return
lambda
:
self
.
_readNewImageMarker
(
ind
)
layout
=
QtWidgets
.
QGridLayout
()
group
:
QtWidgets
.
QGroupBox
=
QtWidgets
.
QGroupBox
(
'Image Based Markers'
)
group
.
setLayout
(
layout
)
layout
.
addWidget
(
self
.
addMarkerBtn
)
if
len
(
self
.
imageMarkers
)
==
0
:
layout
.
addWidget
(
QtWidgets
.
QLabel
(
'No image markers found.'
))
else
:
layout
.
addWidget
(
QtWidgets
.
QLabel
(
'Number'
),
1
,
0
)
layout
.
addWidget
(
QtWidgets
.
QLabel
(
'Coordinates old'
),
1
,
1
)
layout
.
addWidget
(
QtWidgets
.
QLabel
(
'Coordinates new'
),
1
,
2
)
for
index
,
imgMarker
in
enumerate
(
self
.
imageMarkers
):
# reset indices, as they could have been reordered by deleting a marker..
imgMarker
.
index
=
index
self
.
imageMarkerWidgets
[
index
].
index
=
index
newMarker
:
ImageMarker
=
self
.
newImageMarkers
[
index
]
newMarker
.
index
=
index
newX
,
newY
,
newZ
=
newMarker
.
worldCoordX
,
newMarker
.
worldCoordY
,
newMarker
.
worldCoordZ
x
,
y
,
z
=
imgMarker
.
worldCoordX
,
imgMarker
.
worldCoordY
,
imgMarker
.
worldCoordZ
row
:
int
=
2
+
index
updateBtn
:
QtWidgets
.
QPushButton
=
QtWidgets
.
QPushButton
(
'Read Coordinates'
)
updateBtn
.
clicked
.
connect
(
makeReadNewPosLambda
(
index
))
focusBtn
:
QtWidgets
.
QPushButton
=
QtWidgets
.
QPushButton
(
'Center On'
)
focusBtn
.
clicked
.
connect
(
makeCenterOnLambda
(
index
))
delBtn
:
QtWidgets
.
QPushButton
=
QtWidgets
.
QPushButton
(
'Delete'
)
delBtn
.
clicked
.
connect
(
makeDeleteLambda
(
index
))
layout
.
addWidget
(
QtWidgets
.
QLabel
(
str
(
imgMarker
.
index
+
1
)),
row
,
0
)
layout
.
addWidget
(
QtWidgets
.
QLabel
(
f
'x:
{
round
(
x
)
}
µm
\n
y:
{
round
(
y
)
}
µm
\n
z:
{
round
(
z
)
}
µm'
),
row
,
1
)
if
np
.
nan
in
[
newX
,
newY
,
newZ
]:
layout
.
addWidget
(
QtWidgets
.
QLabel
(
'Coordinates not yet read.'
),
row
,
2
)
else
:
layout
.
addWidget
(
QtWidgets
.
QLabel
(
f
'x:
{
round
(
newX
)
}
µm
\n
y:
{
round
(
newY
)
}
µm
\n
z:
{
round
(
newZ
)
}
µm'
),
row
,
2
)
layout
.
addWidget
(
updateBtn
,
row
,
3
)
layout
.
addWidget
(
focusBtn
,
row
,
4
)
layout
.
addWidget
(
delBtn
,
row
,
5
)
return
group
def
_updateTransferResult
(
self
)
->
None
:
oldMarkers
:
list
=
self
.
trayMarkers
if
self
.
trayMarkersBtn
.
isChecked
()
else
self
.
imageMarkers
newMarkers
:
list
=
self
.
newTrayMarkers
if
self
.
trayMarkersBtn
.
isChecked
()
else
self
.
newImageMarkers
srcPoints
:
np
.
ndarray
=
np
.
array
(
[[
marker
.
worldCoordX
,
marker
.
worldCoordY
,
marker
.
worldCoordZ
]
for
marker
in
oldMarkers
])
dstPoints
:
np
.
ndarray
=
np
.
array
(
[[
marker
.
worldCoordX
,
marker
.
worldCoordY
,
marker
.
worldCoordZ
]
for
marker
in
newMarkers
])
hasNan
:
bool
=
(
np
.
any
(
np
.
isnan
(
srcPoints
))
or
np
.
any
(
np
.
isnan
(
dstPoints
)))
if
len
(
oldMarkers
)
==
len
(
newMarkers
)
and
len
(
oldMarkers
)
>=
3
and
not
hasNan
:
transformMatrix
,
pc
,
zpc
,
residuals
=
getTransform
(
srcPoints
,
dstPoints
)
self
.
transferResult
.
setText
(
f
'Transform residuals (µm):
{
residuals
}
'
)
else
:
self
.
transferResult
.
setText
(
'No valid inputs for coordinate transfer'
)
def
_setBtnColor
(
self
,
btn
:
QtWidgets
.
QPushButton
):
"""
Sets color of the toggle button to indicate its status.
"""
if
btn
.
isChecked
():
btn
.
setStyleSheet
(
"background-color : lightblue"
)
else
:
btn
.
setStyleSheet
(
"background-color : lightgrey"
)
def
_useTrayMarkers
(
self
)
->
None
:
"""
Use markers on the sample tray that are NOT in the microscope image.
"""
self
.
imgMarkerGroup
.
setParent
(
None
)
self
.
trayMarkerGroup
.
setParent
(
None
)
self
.
trayMarkerGroup
=
self
.
_getTrayMarkerGroup
()
self
.
layout
.
insertWidget
(
1
,
self
.
trayMarkerGroup
)
def
_useImageMarkers
(
self
)
->
None
:
"""
Use markers that are defined through characteristic spots within the microscope image.
"""
self
.
imgMarkerGroup
.
setParent
(
None
)
self
.
trayMarkerGroup
.
setParent
(
None
)
self
.
imgMarkerGroup
=
self
.
_getImageMarkerGroup
()
self
.
layout
.
insertWidget
(
1
,
self
.
imgMarkerGroup
)
self
.
_updateTransferResult
()
def
mousePressEvent
(
self
,
event
:
QtGui
.
QMouseEvent
)
->
None
:
if
self
.
addMarkerBtn
.
isChecked
()
and
event
.
button
()
==
QtCore
.
Qt
.
LeftButton
:
scenePos
=
self
.
viewParent
.
mapToScene
(
event
.
pos
())
self
.
_addNewImageMarker
((
scenePos
.
x
(),
scenePos
.
y
()))
def
_deleteImageMarker
(
self
,
markerIndex
:
int
)
->
None
:
self
.
imageMarkers
.
remove
(
self
.
imageMarkers
[
markerIndex
])
self
.
newImageMarkers
.
remove
(
self
.
newImageMarkers
[
markerIndex
])
self
.
viewParent
.
scene
().
removeItem
(
self
.
imageMarkerWidgets
[
markerIndex
])
self
.
imageMarkerWidgets
.
remove
(
self
.
imageMarkerWidgets
[
markerIndex
])
self
.
_useImageMarkers
()
def
_centerOnImageMarker
(
self
,
markerIndex
:
int
)
->
None
:
self
.
viewParent
.
centerOn
(
self
.
imageMarkerWidgets
[
markerIndex
])
def
_addNewImageMarker
(
self
,
pos
:
tuple
)
->
None
:
newImageMarker
:
ImageMarker
=
ImageMarker
()
newImageMarker
.
index
=
len
(
self
.
imageMarkers
)
x
,
y
,
z
=
self
.
ramanctrl
.
getPosition
()
newImageMarker
.
worldCoordX
=
x
newImageMarker
.
worldCoordY
=
y
newImageMarker
.
worldCoordZ
=
z
newImageMarker
.
imgCoordX
=
pos
[
0
]
newImageMarker
.
imgCoordY
=
pos
[
1
]
self
.
imageMarkers
.
append
(
newImageMarker
)
newNewImageMarker
:
ImageMarker
=
ImageMarker
()
newNewImageMarker
.
imgCoordX
=
pos
[
0
]
newNewImageMarker
.
imgCoordY
=
pos
[
1
]
self
.
newImageMarkers
.
append
(
newNewImageMarker
)
newMarkerWidget
:
CoordinateSystemMarker
=
CoordinateSystemMarker
(
len
(
self
.
imageMarkers
),
pos
)
self
.
imageMarkerWidgets
.
append
(
newMarkerWidget
)
self
.
viewParent
.
scene
().
addItem
(
newMarkerWidget
)
self
.
_useImageMarkers
()
def
_readNewImageMarker
(
self
,
index
:
int
)
->
None
:
"""Reads current instrument coordinates and assignes them to the respective "new image marker" """
x
,
y
,
z
=
self
.
ramanctrl
.
getPosition
()
self
.
newImageMarkers
[
index
].
worldCoordX
=
x
self
.
newImageMarkers
[
index
].
worldCoordY
=
y
self
.
newImageMarkers
[
index
].
worldCoordZ
=
z
self
.
_useImageMarkers
()
def
_saveToDataset
(
self
)
->
None
:
if
self
.
trayMarkersBtn
.
isChecked
():
print
(
'saving tray markers to dataset'
)
else
:
print
(
'saving image makers to dataset'
)
def
closeEvent
(
self
,
a0
:
QtGui
.
QCloseEvent
)
->
None
:
reply
=
QtWidgets
.
QMessageBox
.
question
(
self
,
'Close without saving'
,
'The window is about to be closed.
\n
Save markers prior to closing?'
,
QtWidgets
.
QMessageBox
.
Yes
|
QtWidgets
.
QMessageBox
.
No
,
QtWidgets
.
QMessageBox
.
Yes
)
if
reply
==
QtWidgets
.
QMessageBox
.
Yes
:
self
.
_saveToDataset
()
if
self
.
viewParent
is
not
None
:
self
.
viewParent
.
showHiddenWidgets
()
self
.
viewParent
.
coordTransferWidget
=
None
del
self
class
CoordinateSystemMarker
(
QtWidgets
.
QGraphicsItem
):
def
__init__
(
self
,
index
:
int
,
position
:
tuple
):
super
().
__init__
()
self
.
setPos
(
position
[
0
],
position
[
1
])
self
.
setFlag
(
QtWidgets
.
QGraphicsItem
.
ItemIsMovable
)
self
.
setCacheMode
(
QtWidgets
.
QGraphicsItem
.
DeviceCoordinateCache
)
self
.
index
=
index
self
.
pxSize
:
int
=
101
self
.
gapSize
:
int
=
10
# self.setFlag(QtWidgets.QGraphicsItem.ItemSendsGeometryChanges)
# self.poschanged = False
def
boundingRect
(
self
)
->
QtCore
.
QRectF
:
return
QtCore
.
QRectF
(
-
self
.
pxSize
/
2
,
-
self
.
pxSize
/
2
,
self
.
pxSize
,
self
.
pxSize
)
def
paint
(
self
,
painter
:
QtGui
.
QPainter
,
option
,
widget
)
->
None
:
halfSize
:
int
=
int
(
round
(
self
.
pxSize
/
2
))
halfGapSize
:
int
=
int
(
round
(
self
.
gapSize
/
2
))
painter
.
setPen
(
QtCore
.
Qt
.
green
)
painter
.
setBrush
(
QtGui
.
QColor
(
30
,
255
,
30
,
64
))
painter
.
drawEllipse
(
-
halfSize
,
-
halfSize
,
self
.
pxSize
,
self
.
pxSize
)
# horizontal lines
painter
.
drawLine
(
-
halfSize
,
0
,
-
halfGapSize
,
0
)
painter
.
drawLine
(
halfGapSize
,
0
,
halfSize
,
0
)
# vertical lines
painter
.
drawLine
(
0
,
-
halfSize
,
0
,
-
halfGapSize
)
painter
.
drawLine
(
0
,
halfGapSize
,
0
,
halfSize
)
painter
.
drawText
(
-
halfSize
,
-
halfSize
,
str
(
f
'Marker
{
self
.
index
+
1
}
'
))
if
__name__
==
'__main__'
:
import
sys
app
=
QtWidgets
.
QApplication
(
sys
.
argv
)
coordUI
=
CoordTransformUI
(
None
)
coordUI
.
show
()
ret
=
app
.
exec_
()
helperfunctions.py
View file @
34439505
...
...
@@ -30,6 +30,9 @@ except ImportError:
skimread
=
None
skimsave
=
None
from
.ramancom.ramanbase
import
RamanBase
from
logging
import
Logger
def
cv2imread_fix
(
fname
,
flags
=
cv2
.
IMREAD_COLOR
):
if
skimread
is
not
None
:
return
skimread
(
fname
,
as_gray
=
(
flags
==
cv2
.
IMREAD_GRAYSCALE
))
...
...
@@ -95,4 +98,15 @@ def polygoncovering(boundary, wx, wy):
poslist
.
extend
([[
xi
,
yi
+
.
5
*
wy
]
for
xi
in
(
x
if
i
%
2
==
0
else
x
[::
-
1
])])
x0clast
,
x1clast
=
x0c
,
x1c
return
poslist
\ No newline at end of file
def
getRamanControl
(
controlclass
:
RamanBase
,
logger
:
Logger
)
->
RamanBase
:
simulatedInterface
:
bool
=
False
if
'simulatedInterface'
in
controlclass
.
__dict__
.
keys
():
if
controlclass
.
__dict__
[
'simulatedInterface'
]
==
True
:
simulatedInterface
=
True
if
simulatedInterface
:
ramanctrl
=
controlclass
(
logger
,
ui
=
False
)
else
:
ramanctrl
=
controlclass
(
logger
)
return
ramanctrl
opticalbackground.py
View file @
34439505
...
...
@@ -133,7 +133,7 @@ class BackGroundManager(QtWidgets.QWidget):
if
img
is
not
None
:
prevImg
=
img
else
:
prevImg
=
np
.
zeros
((
300
,
300
))
prevImg
=
np
.
zeros
((
300
,
300
,
3
))
if
convertColors
:
prevImg
=
cv2
.
cvtColor
(
img
,
cv2
.
COLOR_RGB2BGR
)
...
...
opticalscan.py
View file @
34439505
...
...
@@ -23,12 +23,13 @@ from PyQt5 import QtCore, QtWidgets
import
numpy
as
np
from
multiprocessing
import
Process
,
Queue
,
Event
import
queue
from
.imagestitch
import
imageStacking
import
os
,
sys
import
os
import
logging
import
logging.handlers
import
cv2
from
.helperfunctions
import
cv2imread_fix
,
cv2imwrite_fix
from
typing
import
List
from
.imagestitch
import
imageStacking
from
.helperfunctions
import
cv2imread_fix
,
cv2imwrite_fix
,
getRamanControl
from
time
import
time
,
localtime
,
strftime
from
.opticalbackground
import
BackGroundManager
from
.uielements
import
TimeEstimateProgressbar
...
...
@@ -51,7 +52,7 @@ def scan(path, sol, zpositions, grid, controlclass, dataqueue,
logger
.
info
(
'starting new optical scan'
)
try
:
ramanctrl
=
controlclass
(
logger
)
ramanctrl
=
getRamanControl
(
controlclass
,
logger
)
ramanctrl
.
connect
()
zlist
=
list
(
enumerate
(
zpositions
))
for
i
,
p
in
enumerate
(
grid
):
...
...
@@ -135,8 +136,8 @@ def removeSrcTiles(names, path):
os
.
remove
(
fpath
)
def
loadAndPasteImage
(
srcnames
,
pyramid
,
fullzval
,
width
,
heigh
t
,
rotationvalue
,
p0
,
p1
,
p
,
logger
,
background
=
None
):
def
loadAndPasteImage
(
srcnames
:
List
[
str
]
,
pyramid
,
fullzval
:
np
.
ndarray
,
width
:
float
,
height
:
floa
t
,
rotationvalue
:
float
,
p0
:
List
[
float
],
p1
:
List
[
float
],
p
:
List
[
float
]
,
logger
,
background
=
None
):
"""
:param list of str srcnames: list of stacked scan files to merge
:param ScenePyramid pyramid: the scene pyramid
...
...
@@ -147,6 +148,7 @@ def loadAndPasteImage(srcnames, pyramid, fullzval, width, height,
:param list of float p0: (min x; max y) of scan tile positions
:param list of float p1: (max x; min y) of scan tile positions
:param list of float p: position of current scan tile
:param logger: the logger to use
:param numpy.ndarray background:
:return:
"""
...
...
@@ -193,6 +195,7 @@ class PointCoordinates(QtWidgets.QGridLayout):
def
__init__
(
self
,
N
,
ramanctrl
,
parent
=
None
,
names
=
None
):
super
().
__init__
(
parent
)
self
.
validpoints
=
[
False
]
*
N
self
.
dswidgets
=
[]
self
.
N
=
0
self
.
ramanctrl
=
ramanctrl
...
...
@@ -204,20 +207,20 @@ class PointCoordinates(QtWidgets.QGridLayout):
@
QtCore
.
pyqtSlot
()
def
createWidgets
(
self
,
N
,
pointsgiven
=
[]):
self
.
validpoints
=
[
False
]
*
N
points
=
np
.
zeros
((
N
,
3
))
points
=
np
.
zeros
((
N
,
3
))
def
connect
(
button
,
index
):
button
.
released
.
connect
(
QtCore
.
pyqtSlot
()(
lambda
:
self
.
read
(
index
)))
button
.
released
.
connect
(
QtCore
.
pyqtSlot
()(
lambda
:
self
.
read
(
index
)))
for
i
in
range
(
self
.
N
,
min
(
N
,
len
(
self
.
dswidgets
))):
self
.
itemAtPosition
(
i
+
1
,
0
).
setVisible
(
True
)
self
.
itemAtPosition
(
i
+
1
,
1
).
setVisible
(
True
)
self
.
itemAtPosition
(
i
+
1
,
2
).
setVisible
(
True
)
self
.
itemAtPosition
(
i
+
1
,
3
).
setVisible
(
True
)
self
.
itemAtPosition
(
i
+
1
,
4
).
setVisible
(
True
)
self
.
itemAtPosition
(
i
+
1
,
5
).
setVisible
(
True
)
self
.
itemAtPosition
(
i
+
1
,
6
).
setVisible
(
True
)
for
i
in
range
(
self
.
N
,
min
(
N
,
len
(
self
.
dswidgets
))):
self
.
itemAtPosition
(
i
+
1
,
0
).
setVisible
(
True
)
self
.
itemAtPosition
(
i
+
1
,
1
).
setVisible
(
True
)
self
.
itemAtPosition
(
i
+
1
,
2
).
setVisible
(
True
)
self
.
itemAtPosition
(
i
+
1
,
3
).
setVisible
(
True
)
self
.
itemAtPosition
(
i
+
1
,
4
).
setVisible
(
True
)
self
.
itemAtPosition
(
i
+
1
,
5
).
setVisible
(
True
)
self
.
itemAtPosition
(
i
+
1
,
6
).
setVisible
(
True
)
for
i
in
range
(
self
.
N
,
N
):
if
self
.
names
is
not
None
:
lx
=
QtWidgets
.
QLabel
(
f
"
{
self
.
names
[
i
]
}
-> x:"
)
...
...
@@ -228,15 +231,12 @@ class PointCoordinates(QtWidgets.QGridLayout):
wx
=
QtWidgets
.
QDoubleSpinBox
()
wy
=
QtWidgets
.
QDoubleSpinBox
()
wz
=
QtWidgets
.
QDoubleSpinBox
()
wx
.
setDecimals
(
1
)
wy
.
setDecimals
(
1
)
wz
.
setDecimals
(
1
)
wx
.
setRange
(
-
500_000
,
500_000
)
wy
.
setRange
(
-
500_000
,
500_000
)
wz
.
setRange
(
-
500_000
,
500_000
)
wx
.
setValue
(
points
[
i
,
0
])
wy
.
setValue
(
points
[
i
,
1
])
wz
.
setValue
(
points
[
i
,
2
])
for
index
,
spinbox
in
enumerate
([
wx
,
wy
,
wz
]):
spinbox
.
setDecimals
(
1
)
spinbox
.
setRange
(
-
500_000
,
500_000
)
spinbox
.
setValue
(
points
[
i
,
index
])
spinbox
.
setMaximumWidth
(
75
)
self
.
addWidget
(
lx
,
i
+
1
,
0
,
QtCore
.
Qt
.
AlignLeft
)
self
.
addWidget
(
wx
,
i
+
1
,
1
,
QtCore
.
Qt
.
AlignRight
)
self
.
addWidget
(
ly
,
i
+
1
,
2
,
QtCore
.
Qt
.
AlignLeft
)
...
...
@@ -247,15 +247,15 @@ class PointCoordinates(QtWidgets.QGridLayout):
connect
(
pread
,
i
)
self
.
addWidget
(
pread
,
i
+
1
,
6
,
QtCore
.
Qt
.
AlignRight
)