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
d6af372b
Commit
d6af372b
authored
Jul 20, 2019
by
Josef Brandt
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'Thresholding,Background' into RefactoringAnalysisModules
parents
92f24fb4
48537f7f
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
497 additions
and
157 deletions
+497
-157
analysis/particleContainer.py
analysis/particleContainer.py
+7
-1
dataset.py
dataset.py
+19
-44
detectionview.py
detectionview.py
+8
-7
gepard.py
gepard.py
+5
-4
imagestitch.py
imagestitch.py
+9
-6
opticalbackground.py
opticalbackground.py
+251
-0
opticalscan.py
opticalscan.py
+90
-35
ramancom/WITecCOM.py
ramancom/WITecCOM.py
+16
-4
ramanscanui.py
ramanscanui.py
+3
-5
sampleview.py
sampleview.py
+6
-10
segmentation.py
segmentation.py
+77
-36
viewitems.py
viewitems.py
+6
-5
No files found.
analysis/particleContainer.py
View file @
d6af372b
...
@@ -42,7 +42,13 @@ class ParticleContainer(object):
...
@@ -42,7 +42,13 @@ class ParticleContainer(object):
self
.
measurements
.
append
(
Measurement
())
self
.
measurements
.
append
(
Measurement
())
indexOfNewMeas
=
len
(
self
.
measurements
)
-
1
indexOfNewMeas
=
len
(
self
.
measurements
)
-
1
return
indexOfNewMeas
return
indexOfNewMeas
def
clearParticles
(
self
):
self
.
particles
=
[]
def
clearMeasurements
(
self
):
self
.
measurements
=
[]
def
setMeasurementScanIndex
(
self
,
indexOfMeasurment
,
scanIndex
):
def
setMeasurementScanIndex
(
self
,
indexOfMeasurment
,
scanIndex
):
self
.
measurements
[
indexOfMeasurment
].
ramanScanIndex
=
scanIndex
self
.
measurements
[
indexOfMeasurment
].
ramanScanIndex
=
scanIndex
...
...
dataset.py
View file @
d6af372b
...
@@ -149,6 +149,7 @@ class DataSet(object):
...
@@ -149,6 +149,7 @@ class DataSet(object):
# self.particlestats = []
# self.particlestats = []
# self.ramanscansortindex = None
# self.ramanscansortindex = None
self
.
particleContainer
=
ParticleContainer
(
self
)
self
.
particleContainer
=
ParticleContainer
(
self
)
self
.
particleDetectionDone
=
False
self
.
ramanscandone
=
False
self
.
ramanscandone
=
False
# self.results = {'polymers': None,
# self.results = {'polymers': None,
...
@@ -246,40 +247,30 @@ class DataSet(object):
...
@@ -246,40 +247,30 @@ class DataSet(object):
self
.
imagedim_bf
=
self
.
imagedim
self
.
imagedim_bf
=
self
.
imagedim
self
.
imagedim_df
=
self
.
imagedim
self
.
imagedim_df
=
self
.
imagedim
del
self
.
imagedim
del
self
.
imagedim
if
not
hasattr
(
self
,
'particles2spectra'
):
self
.
particles2spectra
=
[[
int
(
np
.
where
(
self
.
ramanscansortindex
==
i
)[
0
])]
for
i
in
range
(
len
(
self
.
ramanscansortindex
))]
self
.
version
=
2
self
.
version
=
2
if
self
.
version
==
2
:
if
self
.
version
==
2
:
self
.
particleContainer
=
ParticleContainer
(
self
)
self
.
particleContainer
=
ParticleContainer
(
self
)
def
recreateMeasurement2ParticleFromScanIndices
():
measurements2particles
=
[[
int
(
np
.
where
(
self
.
ramanscansortindex
==
i
)[
0
])]
for
i
in
range
(
len
(
self
.
ramanscansortindex
))]
return
measurements2particles
self
.
particleContainer
.
initializeParticles
(
len
(
self
.
particlestats
))
self
.
particleContainer
.
initializeParticles
(
len
(
self
.
particlestats
))
self
.
particleContainer
.
setParticleContours
(
self
.
particlecontours
)
self
.
particleContainer
.
setParticleContours
(
self
.
particlecontours
)
self
.
particleContainer
.
setParticleStats
(
self
.
particlestats
)
self
.
particleContainer
.
setParticleStats
(
self
.
particlestats
)
self
.
particleContainer
.
applyPixelScaleToParticleStats
(
self
.
getPixelScale
())
self
.
particleContainer
.
applyPixelScaleToParticleStats
(
self
.
getPixelScale
())
if
hasattr
(
self
,
'particles2spectra'
):
if
len
(
self
.
particlestats
)
>
0
:
#i.e., particle detection was completed and particle data is there
if
self
.
particles2spectra
is
not
None
:
for
particleIndex
,
listOfScanIndices
in
enumerate
(
self
.
particles2spectra
):
measurements2particles
=
self
.
particles2spectra
curParticle
=
self
.
particleContainer
.
getParticleOfIndex
(
particleIndex
)
else
:
for
scanIndex
in
listOfScanIndices
:
measurements2particles
=
recreateMeasurement2ParticleFromScanIndices
()
indexOfNewMeas
=
self
.
particleContainer
.
addEmptyMeasurement
()
else
:
x
,
y
=
self
.
ramanpoints
[
particleIndex
][
0
],
self
.
ramanpoints
[
particleIndex
][
1
]
measurements2particles
=
recreateMeasurement2ParticleFromScanIndices
()
self
.
particleContainer
.
setMeasurementPixelCoords
(
indexOfNewMeas
,
x
,
y
)
self
.
particleContainer
.
setMeasurementScanIndex
(
indexOfNewMeas
,
scanIndex
)
for
particleIndex
,
listOfScanIndices
in
enumerate
(
measurements2particles
):
curParticle
.
addMeasurement
(
self
.
particleContainer
.
measurements
[
indexOfNewMeas
])
curParticle
=
self
.
particleContainer
.
getParticleOfIndex
(
particleIndex
)
for
scanIndex
in
listOfScanIndices
:
# curParticle.addEmptyMeasurement()
# curParticle.setMeasurementPixelCoords(measIndex, x, y)
# curParticle.setMeasurementScanIndex(measIndex, scanIndex)
indexOfNewMeas
=
self
.
particleContainer
.
addEmptyMeasurement
()
x
,
y
=
self
.
ramanpoints
[
particleIndex
][
0
],
self
.
ramanpoints
[
particleIndex
][
1
]
self
.
particleContainer
.
setMeasurementPixelCoords
(
indexOfNewMeas
,
x
,
y
)
self
.
particleContainer
.
setMeasurementScanIndex
(
indexOfNewMeas
,
scanIndex
)
curParticle
.
addMeasurement
(
self
.
particleContainer
.
measurements
[
indexOfNewMeas
])
for
particle
in
self
.
particleContainer
.
particles
:
for
particle
in
self
.
particleContainer
.
particles
:
for
meas
in
particle
.
measurements
:
for
meas
in
particle
.
measurements
:
...
@@ -292,8 +283,6 @@ class DataSet(object):
...
@@ -292,8 +283,6 @@ class DataSet(object):
# self.version = 3
# self.version = 3
# add later conversion for higher version numbers here
# add later conversion for higher version numbers here
def
getSubImage
(
self
,
img
,
index
,
draw
=
True
):
def
getSubImage
(
self
,
img
,
index
,
draw
=
True
):
contour
=
self
.
particlecontours
[
index
]
contour
=
self
.
particlecontours
[
index
]
x0
,
x1
=
contour
[:,
0
,
0
].
min
(),
contour
[:,
0
,
0
].
max
()
x0
,
x1
=
contour
[:,
0
,
0
].
min
(),
contour
[:,
0
,
0
].
max
()
...
@@ -395,28 +384,14 @@ class DataSet(object):
...
@@ -395,28 +384,14 @@ class DataSet(object):
def
getLegacyDetectImageName
(
self
):
def
getLegacyDetectImageName
(
self
):
return
os
.
path
.
join
(
self
.
path
,
"detectimage.png"
)
return
os
.
path
.
join
(
self
.
path
,
"detectimage.png"
)
def
getBackgroundImageName
(
self
):
return
os
.
path
.
join
(
self
.
path
,
"background.bmp"
)
def
getDetectImageName
(
self
):
def
getDetectImageName
(
self
):
raise
NotImplementedError
(
"No longer implemented due to change in API"
)
raise
NotImplementedError
(
"No longer implemented due to change in API"
)
def
getTmpImageName
(
self
):
def
getTmpImageName
(
self
):
return
os
.
path
.
join
(
self
.
path
,
"tmp.bmp"
)
return
os
.
path
.
join
(
self
.
path
,
"tmp.bmp"
)
def
saveParticleData
(
self
):
print
(
'Not saving ParticleData into text file...:
\n
The current output format might be wrong, if multiple spectra per particle are present...'
)
# if len(self.ramanscansortindex)>0:
# data = []
# pixelscale = (self.pixelscale_df if self.imagescanMode == 'df' else self.pixelscale_bf)
# for i in self.ramanscansortindex:
# data.append(list(self.ramanpoints[i])+list(self.particlestats[i]))
# data = np.array(data)
# data[:,0], data[:,1], z = self.mapToLengthRaman((data[:,0], data[:,1]), microscopeMode=self.imagescanMode, noz=True)
# data[:,2:7] *= pixelscale
# header = "x [µm], y [µm], length [µm], height [µm], length_ellipse [µm], height_ellipse [µm]"
# if data.shape[1]>6:
# header = header + ", area [µm^2]"
# data[:,6] *= pixelscale
# np.savetxt(os.path.join(self.path, "particledata.txt"), data,
# header=header)
def
save
(
self
):
def
save
(
self
):
saveData
(
self
,
self
.
fname
)
saveData
(
self
,
self
.
fname
)
...
...
detectionview.py
View file @
d6af372b
...
@@ -20,7 +20,7 @@ If not, see <https://www.gnu.org/licenses/>.
...
@@ -20,7 +20,7 @@ If not, see <https://www.gnu.org/licenses/>.
"""
"""
import
numpy
as
np
import
numpy
as
np
from
PyQt5
import
QtCore
,
QtWidgets
,
QtGui
from
PyQt5
import
QtCore
,
QtWidgets
,
QtGui
from
segmentation
import
Segmentation
from
segmentation
import
Segmentation
,
MeasurementPoint
from
matplotlib.backends.backend_qt5agg
import
FigureCanvasQTAgg
from
matplotlib.backends.backend_qt5agg
import
FigureCanvasQTAgg
import
matplotlib.pyplot
as
plt
import
matplotlib.pyplot
as
plt
from
threading
import
Thread
from
threading
import
Thread
...
@@ -248,7 +248,9 @@ class ImageView(QtWidgets.QLabel):
...
@@ -248,7 +248,9 @@ class ImageView(QtWidgets.QLabel):
painter
.
setPen
(
QtCore
.
Qt
.
red
)
painter
.
setPen
(
QtCore
.
Qt
.
red
)
painter
.
setBrush
(
QtCore
.
Qt
.
red
)
painter
.
setBrush
(
QtCore
.
Qt
.
red
)
for
p
in
self
.
measpoints
:
for
p
in
self
.
measpoints
:
painter
.
drawEllipse
(
p
[
0
]
-
2
,
p
[
1
]
-
2
,
5
,
5
)
for
point
in
self
.
measpoints
[
p
]:
# painter.drawEllipse(p[0]-2, p[1]-2, 5, 5)
painter
.
drawEllipse
(
point
.
x
-
2
,
point
.
y
-
2
,
5
,
5
)
if
self
.
showseedpoints
:
if
self
.
showseedpoints
:
painter
.
setPen
(
QtCore
.
Qt
.
white
)
painter
.
setPen
(
QtCore
.
Qt
.
white
)
...
@@ -581,10 +583,9 @@ class ParticleDetectionView(QtWidgets.QWidget):
...
@@ -581,10 +583,9 @@ class ParticleDetectionView(QtWidgets.QWidget):
@
QtCore
.
pyqtSlot
()
@
QtCore
.
pyqtSlot
()
def
clearDetection
(
self
):
def
clearDetection
(
self
):
if
self
.
dataset
is
not
None
:
if
self
.
dataset
is
not
None
:
self
.
dataset
.
ramanpoints
=
[]
self
.
dataset
.
particleContainer
.
clearParticles
()
self
.
dataset
.
particlecontours
=
[]
self
.
dataset
.
particleContainer
.
clearMeasurements
()
self
.
dataset
.
particlestats
=
[]
self
.
dataset
.
particleDetectionDone
=
False
self
.
dataset
.
ramanscansortindex
=
[]
self
.
dataset
.
ramanscandone
=
False
self
.
dataset
.
ramanscandone
=
False
self
.
dataset
.
mode
=
"opticalscan"
self
.
dataset
.
mode
=
"opticalscan"
self
.
dataset
.
save
()
self
.
dataset
.
save
()
...
@@ -676,7 +677,7 @@ class ParticleDetectionView(QtWidgets.QWidget):
...
@@ -676,7 +677,7 @@ class ParticleDetectionView(QtWidgets.QWidget):
curParticle
.
addMeasurement
(
particleContainer
.
measurements
[
indexOfNewMeas
])
curParticle
.
addMeasurement
(
particleContainer
.
measurements
[
indexOfNewMeas
])
self
.
dataset
.
particleDetectionDone
=
True
# self.dataset.ramanpoints = measurementPoints #consider moving that to particleContainer
# self.dataset.ramanpoints = measurementPoints #consider moving that to particleContainer
# self.dataset.particlecontours = contours
# self.dataset.particlecontours = contours
# self.dataset.particlestats = particlestats
# self.dataset.particlestats = particlestats
...
...
gepard.py
View file @
d6af372b
...
@@ -102,12 +102,13 @@ class GEPARDMainWindow(QtWidgets.QMainWindow):
...
@@ -102,12 +102,13 @@ class GEPARDMainWindow(QtWidgets.QMainWindow):
if
fileName
:
if
fileName
:
isValid
,
msg
=
self
.
testFilename
(
fileName
)
isValid
,
msg
=
self
.
testFilename
(
fileName
)
if
isValid
:
if
isValid
:
self
.
fname
=
str
(
fileName
)
#TODO: No spaces for Renishaw Interface!!
self
.
fname
=
str
(
fileName
)
self
.
view
.
new
(
self
.
fname
)
self
.
view
.
new
(
self
.
fname
)
self
.
scalingChanged
(
1.
)
self
.
scalingChanged
(
1.
)
else
:
else
:
QtWidgets
.
QMessageBox
.
critical
(
self
,
"Error"
,
msg
)
QtWidgets
.
QMessageBox
.
critical
(
self
,
"Error"
,
msg
)
@
QtCore
.
pyqtSlot
()
def
testFilename
(
self
,
fileName
):
def
testFilename
(
self
,
fileName
):
if
self
.
view
.
ramanctrl
.
name
==
'RenishawCOM'
:
#the renishawCom does not allow Spaces within filePath
if
self
.
view
.
ramanctrl
.
name
==
'RenishawCOM'
:
#the renishawCom does not allow Spaces within filePath
if
fileName
.
find
(
' '
)
==
0
:
if
fileName
.
find
(
' '
)
==
0
:
...
@@ -116,7 +117,7 @@ class GEPARDMainWindow(QtWidgets.QMainWindow):
...
@@ -116,7 +117,7 @@ class GEPARDMainWindow(QtWidgets.QMainWindow):
return
True
,
""
return
True
,
""
else
:
else
:
return
True
,
""
return
True
,
""
@
QtCore
.
pyqtSlot
()
@
QtCore
.
pyqtSlot
()
def
about
(
self
):
def
about
(
self
):
QtWidgets
.
QMessageBox
.
about
(
self
,
'GEPARD'
,
QtWidgets
.
QMessageBox
.
about
(
self
,
'GEPARD'
,
...
@@ -202,7 +203,7 @@ class GEPARDMainWindow(QtWidgets.QMainWindow):
...
@@ -202,7 +203,7 @@ class GEPARDMainWindow(QtWidgets.QMainWindow):
self
.
configRamanCtrlAct
.
triggered
.
connect
(
self
.
view
.
configureRamanControl
)
self
.
configRamanCtrlAct
.
triggered
.
connect
(
self
.
view
.
configureRamanControl
)
if
self
.
view
.
simulatedRaman
:
if
self
.
view
.
simulatedRaman
:
self
.
configRamanCtrlAct
.
setDisabled
(
True
)
self
.
configRamanCtrlAct
.
setDisabled
(
True
)
def
updateModes
(
self
,
active
=
None
,
maxenabled
=
None
):
def
updateModes
(
self
,
active
=
None
,
maxenabled
=
None
):
ose
,
osc
,
pde
,
pdc
,
rse
,
rsc
,
pae
,
pac
=
[
False
]
*
8
ose
,
osc
,
pde
,
pdc
,
rse
,
rsc
,
pae
,
pac
=
[
False
]
*
8
if
maxenabled
==
"OpticalScan"
:
if
maxenabled
==
"OpticalScan"
:
...
...
imagestitch.py
View file @
d6af372b
...
@@ -48,15 +48,17 @@ def imageStacking(colimgs):
...
@@ -48,15 +48,17 @@ def imageStacking(colimgs):
return
im
,
zval
return
im
,
zval
def
combineImages
(
path
,
nx
,
ny
,
nk
,
width
,
height
,
angle
):
def
combineImages
(
path
,
nx
,
ny
,
nk
,
width
,
height
,
angle
):
imgs
=
[]
full
=
None
full
=
None
for
i
in
range
(
nx
):
for
i
in
range
(
nx
):
for
j
in
range
(
ny
):
for
j
in
range
(
ny
):
colimgs
=
[]
if
nk
>
1
:
for
k
in
range
(
nk
):
colimgs
=
[]
colimgs
.
append
(
cv2
.
imread
(
path
+
f
'test_
{
i
}
_
{
j
}
_
{
k
}
.bmp'
))
for
k
in
range
(
nk
):
img
=
imageStacking
(
colimgs
)
colimgs
.
append
(
cv2
.
imread
(
path
+
f
'test_
{
i
}
_
{
j
}
_
{
k
}
.bmp'
))
imgs
.
append
(
img
)
img
=
imageStacking
(
colimgs
)
else
:
img
=
cv2
.
imread
(
path
+
f
'test_
{
i
}
_
{
j
}
_1.bmp'
)
dx
=
i
*
.
9
*
img
.
shape
[
1
]
dx
=
i
*
.
9
*
img
.
shape
[
1
]
dy
=
j
*
.
8
*
img
.
shape
[
0
]
dy
=
j
*
.
8
*
img
.
shape
[
0
]
c
,
s
=
np
.
cos
(
np
.
radians
(
angle
)),
np
.
sin
(
np
.
radians
(
angle
))
c
,
s
=
np
.
cos
(
np
.
radians
(
angle
)),
np
.
sin
(
np
.
radians
(
angle
))
...
@@ -67,6 +69,7 @@ def combineImages(path, nx, ny, nk, width, height, angle):
...
@@ -67,6 +69,7 @@ def combineImages(path, nx, ny, nk, width, height, angle):
full
=
dst
full
=
dst
else
:
else
:
full
=
cv2
.
max
(
full
,
dst
)
full
=
cv2
.
max
(
full
,
dst
)
cv2
.
imwrite
(
"full_dunkel.png"
,
full
)
cv2
.
imwrite
(
"full_dunkel.png"
,
full
)
...
...
opticalbackground.py
0 → 100644
View file @
d6af372b
# -*- coding: utf-8 -*-
"""
GEPARD - Gepard-Enabled PARticle Detection
Copyright (C) 2018 Lars Bittrich and Josef Brandt, Leibniz-Institut für
Polymerforschung Dresden e. V. <bittrich-lars@ipfdd.de>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program, see COPYING.
If not, see <https://www.gnu.org/licenses/>.
"""
from
PyQt5
import
QtCore
,
QtWidgets
,
QtGui
import
cv2
import
numpy
as
np
import
os
from
helperfunctions
import
cv2imread_fix
class
BackGroundManager
(
QtWidgets
.
QWidget
):
managerClosed
=
QtCore
.
pyqtSignal
()
readBackground
=
QtCore
.
pyqtSignal
(
int
)
def
__init__
(
self
,
parentOSwidget
):
super
(
BackGroundManager
,
self
).
__init__
()
self
.
setFixedSize
(
1500
,
900
)
self
.
setWindowTitle
(
'Optical Background Manager'
)
self
.
parentOSwidget
=
parentOSwidget
self
.
parentOSwidget
.
backGroundSavedToPath
.
connect
(
self
.
updateChildImage
)
self
.
ramanctrl
=
self
.
parentOSwidget
.
ramanctrl
layout
=
QtWidgets
.
QHBoxLayout
()
self
.
setLayout
(
layout
)
self
.
imagesGroup
=
QtWidgets
.
QGroupBox
(
'Current Background Images'
)
self
.
imagesLayout
=
QtWidgets
.
QGridLayout
()
self
.
imgContainers
=
[]
self
.
avgImg
=
None
self
.
presetIndividualImages
()
self
.
previewImage
=
QtWidgets
.
QGraphicsView
()
self
.
setupGraphicsView
(
self
.
previewImage
,
scaleFactor
=
0.8
)
previewGroup
=
QtWidgets
.
QGroupBox
()
previewLayout
=
QtWidgets
.
QVBoxLayout
()
self
.
blurspinbox
=
QtWidgets
.
QSpinBox
(
self
)
self
.
blurspinbox
.
setMinimum
(
3
)
self
.
blurspinbox
.
setMaximum
(
99
)
self
.
blurspinbox
.
setSingleStep
(
2
)
self
.
blurspinbox
.
setValue
(
5
)
self
.
blurspinbox
.
valueChanged
.
connect
(
self
.
calculateAverageImage
)
self
.
blurspinbox
.
setMaximumWidth
(
150
)
self
.
previewCurrentViewBtn
=
QtWidgets
.
QPushButton
(
'Acquire 3x3 area and preview subtracted result'
)
self
.
previewCurrentViewBtn
.
clicked
.
connect
(
self
.
previewStitchedArea
)
self
.
previewArea
=
QtWidgets
.
QGraphicsView
()
self
.
setupGraphicsView
(
self
.
previewArea
,
scaleFactor
=
0.5
)
previewLayout
.
addWidget
(
QtWidgets
.
QLabel
(
'Radius for blur'
))
previewLayout
.
addWidget
(
self
.
blurspinbox
)
previewLayout
.
addWidget
(
QtWidgets
.
QLabel
(
'Preview of averaged and smoothed image'
))
previewLayout
.
addWidget
(
self
.
previewImage
)
previewLayout
.
addWidget
(
self
.
previewCurrentViewBtn
)
previewLayout
.
addWidget
(
self
.
previewArea
)
previewGroup
.
setLayout
(
previewLayout
)
layout
.
addWidget
(
self
.
imagesGroup
)
layout
.
addWidget
(
previewGroup
)
def
presetIndividualImages
(
self
,
nrows
=
3
,
ncols
=
2
):
index
=
0
for
row
in
range
(
nrows
):
for
col
in
range
(
ncols
):
self
.
imgContainers
.
append
(
SingleImageContainer
(
self
,
index
))
self
.
imagesLayout
.
addWidget
(
self
.
imgContainers
[
-
1
],
row
,
col
)
index
+=
1
self
.
imagesGroup
.
setLayout
(
self
.
imagesLayout
)
def
previewStitchedArea
(
self
):
if
self
.
avgImg
is
None
:
QtWidgets
.
QMessageBox
.
about
(
self
,
'Warning'
,
'No Background Image is aquired'
)
return
else
:
from
opticalscan
import
loadAndPasteImage
self
.
dataset
=
self
.
parentOSwidget
.
dataset
#acquire images in 3x3 area to preview quality of background subtraction
x
,
y
,
z
=
self
.
ramanctrl
.
getPosition
()
micMode
=
self
.
parentOSwidget
.
view
.
microscopeMode
width
,
height
,
angle
=
self
.
ramanctrl
.
getImageDimensions
(
micMode
)
startPoint
=
[
x
-
width
,
y
-
height
]
endPoint
=
[
x
+
width
,
y
+
height
]
points
=
np
.
concatenate
(([
startPoint
],
[
endPoint
]),
axis
=
0
)
p0
=
[
points
[:,
0
].
min
(),
points
[:,
1
].
max
()]
p1
=
[
points
[:,
0
].
max
(),
points
[:,
1
].
min
()]
reply
=
QtWidgets
.
QMessageBox
.
question
(
self
,
'Message'
,
f
"The stage will move
{
round
(
3
*
width
)
}
in x and
{
round
(
3
*
height
)
}
in y.
\n
Continue?"
,
QtWidgets
.
QMessageBox
.
Yes
|
QtWidgets
.
QMessageBox
.
No
,
QtWidgets
.
QMessageBox
.
No
)
if
reply
==
QtWidgets
.
QMessageBox
.
Yes
:
fullimg
=
None
zimg
=
None
for
row
in
range
(
3
):
for
col
in
range
(
3
):
curPoint
=
[
startPoint
[
0
]
+
row
*
width
,
startPoint
[
1
]
+
col
*
height
]
self
.
ramanctrl
.
moveToAbsolutePosition
(
curPoint
[
0
],
curPoint
[
1
])
self
.
ramanctrl
.
saveImage
(
self
.
dataset
.
getTmpImageName
())
fullimg
,
zimg
=
loadAndPasteImage
([
self
.
dataset
.
getTmpImageName
()],
fullimg
,
zimg
,
width
,
height
,
angle
,
p0
,
p1
,
curPoint
,
background
=
self
.
avgImg
)
self
.
updateGraphicsView
(
self
.
previewArea
,
fullimg
,
convertColors
=
True
)
def
setupGraphicsView
(
self
,
graphView
,
scaleFactor
=
1.
):
graphView
.
item
=
QtWidgets
.
QGraphicsPixmapItem
()
scene
=
QtWidgets
.
QGraphicsScene
(
graphView
)
scene
.
addItem
(
graphView
.
item
)
graphView
.
setScene
(
scene
)
graphView
.
scale
(
scaleFactor
,
scaleFactor
)
def
updateGraphicsView
(
self
,
graphView
,
img
,
convertColors
=
False
):
if
img
is
not
None
:
prevImg
=
img
else
:
prevImg
=
np
.
zeros
((
300
,
300
))
if
convertColors
:
prevImg
=
cv2
.
cvtColor
(
img
,
cv2
.
COLOR_RGB2BGR
)
height
,
width
=
prevImg
.
shape
[:
2
]
bytesPerLine
=
3
*
width
pix
=
QtGui
.
QPixmap
()
pix
.
convertFromImage
(
QtGui
.
QImage
(
prevImg
,
width
,
height
,
bytesPerLine
,
QtGui
.
QImage
.
Format_RGB888
))
graphView
.
item
.
setPixmap
(
pix
)
@
QtCore
.
pyqtSlot
(
int
,
str
)
def
updateChildImage
(
self
,
index
,
path
):
self
.
imgContainers
[
index
].
updateImage
(
path
)
self
.
calculateAverageImage
()
def
calculateAverageImage
(
self
):
curImgs
=
[
i
.
getImage
()
for
i
in
self
.
imgContainers
if
i
.
getImage
()
is
not
None
]
if
len
(
curImgs
)
>
0
:
curImgs
=
np
.
array
(
curImgs
)
self
.
avgImg
=
np
.
sum
(
curImgs
,
axis
=
0
)
/
len
(
curImgs
)
radius
=
self
.
blurspinbox
.
value
()
if
radius
%
2
==
0
:
radius
+=
1
if
radius
<
0
:
radius
=
1
self
.
avgImg
=
cv2
.
GaussianBlur
(
self
.
avgImg
,
(
radius
,
radius
),
0
)
self
.
avgImg
=
np
.
uint8
(
self
.
avgImg
)
self
.
parentOSwidget
.
writeBackGroundImage
(
self
.
avgImg
)
else
:
self
.
avgImg
=
None
self
.
parentOSwidget
.
deleteBackGroundImage
()
self
.
updateGraphicsView
(
self
.
previewImage
,
self
.
avgImg
)
def
closeEvent
(
self
,
event
):
self
.
managerClosed
.
emit
()
event
.
accept
()
class
SingleImageContainer
(
QtWidgets
.
QGroupBox
):
def
__init__
(
self
,
parent
,
index
):
super
(
SingleImageContainer
,
self
).
__init__
()
self
.
index
=
index
self
.
parent
=
parent
layout
=
QtWidgets
.
QVBoxLayout
()
layout
.
addWidget
(
QtWidgets
.
QLabel
(
f
'Background
{
index
+
1
}
'
))
readBtn
=
QtWidgets
.
QPushButton
(
'ReadImage'
)
readBtn
.
clicked
.
connect
(
self
.
readImage
)
self
.
image
=
ImagePixmap
()
delBtn
=
QtWidgets
.
QPushButton
(
'Delete Image'
)
delBtn
.
clicked
.
connect
(
self
.
clearImage
)
layout
.
addWidget
(
readBtn
)
layout
.
addWidget
(
self
.
image
)
layout
.
addWidget
(
delBtn
)
self
.
setLayout
(
layout
)
def
readImage
(
self
):
self
.
parent
.
readBackground
.
emit
(
self
.
index
)
def
updateImage
(
self
,
path
):
self
.
image
.
updateImage
(
path
)
def
clearImage
(
self
):
self
.
image
.
clearImage
()
self
.
parent
.
calculateAverageImage
()
def
getImage
(
self
):
return
self
.
image
.
imgdata
class
ImagePixmap
(
QtWidgets
.
QGraphicsView
):
def
__init__
(
self
):
super
(
ImagePixmap
,
self
).
__init__
()
self
.
item
=
QtWidgets
.
QGraphicsPixmapItem
()
self
.
item
.
setPos
(
0
,
0
)
self
.
item
.
setAcceptedMouseButtons
(
QtCore
.
Qt
.
NoButton
)
self
.
imgdata
=
None
scene
=
QtWidgets
.
QGraphicsScene
(
self
)
scene
.
addItem
(
self
.
item
)
self
.
setScene
(
scene
)
self
.
scale
(
0.4
,
0.4
)
self
.
updateImage
()
def
updateImage
(
self
,
img_path
=
None
):
if
img_path
is
None
:
self
.
loadImageIntoPixmap
(
self
.
createBlancImage
())
elif
os
.
path
.
exists
(
img_path
):
self
.
imgdata
=
cv2
.
cvtColor
(
cv2imread_fix
(
img_path
),
cv2
.
COLOR_BGR2RGB
)
self
.
loadImageIntoPixmap
(
self
.
imgdata
)
def
createBlancImage
(
self
):
blancImg
=
np
.
zeros
((
300
,
500
,
3
))
cv2
.
putText
(
blancImg
,
'None selected'
,
(
150
,
150
),
cv2
.
FONT_HERSHEY_COMPLEX
,
1
,
(
255
,
255
,
255
),
2
)
return
blancImg
def
loadImageIntoPixmap
(
self
,
img
):
height
,
width
=
img
.
shape
[:
2
]
bytesPerLine
=
3
*
width
pix
=
QtGui
.
QPixmap
()
pix
.
convertFromImage
(
QtGui
.
QImage
(
img
,
width
,
height
,
bytesPerLine
,
QtGui
.
QImage
.
Format_RGB888
))
self
.
item
.
setPixmap
(
pix
)
def
clearImage
(
self
):
self
.
imgdata
=
None
self
.
updateImage
()
opticalscan.py
View file @
d6af372b
...
@@ -30,12 +30,13 @@ from helperfunctions import cv2imread_fix, cv2imwrite_fix
...
@@ -30,12 +30,13 @@ from helperfunctions import cv2imread_fix, cv2imwrite_fix
from
time
import
time
from
time
import
time
import
datetime
import
datetime
import
sys
import
sys
from
opticalbackground
import
BackGroundManager
def
scan
(
path
,
sol
,
zpositions
,
grid
,
controlclass
,
dataqueue
,
def
scan
(
path
,
sol
,
zpositions
,
grid
,
controlclass
,
dataqueue
,
stopevent
,
logpath
=
''
,
ishdr
=
False
):
stopevent
,
logpath
=
''
,
ishdr
=
False
):
if
ishdr
:
if
ishdr
:
merge_mertens
=
cv2
.
createMergeMertens
()
merge_mertens
=
cv2
.
createMergeMertens
()
fp
=
None
fp
=
None
if
logpath
!=
''
:
if
logpath
!=
''
:
try
:
try
:
...
@@ -81,18 +82,21 @@ def scan(path, sol, zpositions, grid, controlclass, dataqueue,
...
@@ -81,18 +82,21 @@ def scan(path, sol, zpositions, grid, controlclass, dataqueue,
if
fp
is
not
None
:
if
fp
is
not
None
:
fp
.
close
()
fp
.
close
()
def
subtractBackground
(
image
,
background
):
avg
=
np
.
mean
(
background
)
subtracted
=
np
.
clip
(
np
.
array
(
image
-
background
+
avg
,
dtype
=
np
.
uint8
),
0
,
255
)
return
subtracted
def
loadAndPasteImage
(
srcnames
,
fullimage
,
fullzval
,
width
,
height
,
def
loadAndPasteImage
(
srcnames
,
fullimage
,
fullzval
,
width
,
height
,
rotationvalue
,
p0
,
p1
,
p
,
halfResolution
=
Fals
e
):
rotationvalue
,
p0
,
p1
,
p
,
background
=
Non
e
):
colimgs
=
[]
colimgs
=
[]
for
name
in
srcnames
:
for
name
in
srcnames
:
colimgs
.
append
(
cv2
.
cvtColor
(
cv2imread_fix
(
name
),
cv2
.
COLOR_BGR2RGB
))
curImg
=
cv2imread_fix
(
name
)
if
background
is
not
None
:
curImg
=
subtractBackground
(
curImg
,
background
)