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):
self
.
measurements
.
append
(
Measurement
())
indexOfNewMeas
=
len
(
self
.
measurements
)
-
1
return
indexOfNewMeas
def
clearParticles
(
self
):
self
.
particles
=
[]
def
clearMeasurements
(
self
):
self
.
measurements
=
[]
def
setMeasurementScanIndex
(
self
,
indexOfMeasurment
,
scanIndex
):
self
.
measurements
[
indexOfMeasurment
].
ramanScanIndex
=
scanIndex
...
...
dataset.py
View file @
d6af372b
...
...
@@ -149,6 +149,7 @@ class DataSet(object):
# self.particlestats = []
# self.ramanscansortindex = None
self
.
particleContainer
=
ParticleContainer
(
self
)
self
.
particleDetectionDone
=
False
self
.
ramanscandone
=
False
# self.results = {'polymers': None,
...
...
@@ -246,40 +247,30 @@ class DataSet(object):
self
.
imagedim_bf
=
self
.
imagedim
self
.
imagedim_df
=
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
if
self
.
version
==
2
:
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
.
setParticleContours
(
self
.
particlecontours
)
self
.
particleContainer
.
setParticleStats
(
self
.
particlestats
)
self
.
particleContainer
.
applyPixelScaleToParticleStats
(
self
.
getPixelScale
())
if
hasattr
(
self
,
'particles2spectra'
):
if
self
.
particles2spectra
is
not
None
:
measurements2particles
=
self
.
particles2spectra
else
:
measurements2particles
=
recreateMeasurement2ParticleFromScanIndices
()
else
:
measurements2particles
=
recreateMeasurement2ParticleFromScanIndices
()
for
particleIndex
,
listOfScanIndices
in
enumerate
(
measurements2particles
):
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
])
if
len
(
self
.
particlestats
)
>
0
:
#i.e., particle detection was completed and particle data is there
for
particleIndex
,
listOfScanIndices
in
enumerate
(
self
.
particles2spectra
):
curParticle
=
self
.
particleContainer
.
getParticleOfIndex
(
particleIndex
)
for
scanIndex
in
listOfScanIndices
:
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
meas
in
particle
.
measurements
:
...
...
@@ -292,8 +283,6 @@ class DataSet(object):
# self.version = 3
# add later conversion for higher version numbers here
def
getSubImage
(
self
,
img
,
index
,
draw
=
True
):
contour
=
self
.
particlecontours
[
index
]
x0
,
x1
=
contour
[:,
0
,
0
].
min
(),
contour
[:,
0
,
0
].
max
()
...
...
@@ -395,28 +384,14 @@ class DataSet(object):
def
getLegacyDetectImageName
(
self
):
return
os
.
path
.
join
(
self
.
path
,
"detectimage.png"
)
def
getBackgroundImageName
(
self
):
return
os
.
path
.
join
(
self
.
path
,
"background.bmp"
)
def
getDetectImageName
(
self
):
raise
NotImplementedError
(
"No longer implemented due to change in API"
)
def
getTmpImageName
(
self
):
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
):
saveData
(
self
,
self
.
fname
)
...
...
detectionview.py
View file @
d6af372b
...
...
@@ -20,7 +20,7 @@ If not, see <https://www.gnu.org/licenses/>.
"""
import
numpy
as
np
from
PyQt5
import
QtCore
,
QtWidgets
,
QtGui
from
segmentation
import
Segmentation
from
segmentation
import
Segmentation
,
MeasurementPoint
from
matplotlib.backends.backend_qt5agg
import
FigureCanvasQTAgg
import
matplotlib.pyplot
as
plt
from
threading
import
Thread
...
...
@@ -248,7 +248,9 @@ class ImageView(QtWidgets.QLabel):
painter
.
setPen
(
QtCore
.
Qt
.
red
)
painter
.
setBrush
(
QtCore
.
Qt
.
red
)
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
:
painter
.
setPen
(
QtCore
.
Qt
.
white
)
...
...
@@ -581,10 +583,9 @@ class ParticleDetectionView(QtWidgets.QWidget):
@
QtCore
.
pyqtSlot
()
def
clearDetection
(
self
):
if
self
.
dataset
is
not
None
:
self
.
dataset
.
ramanpoints
=
[]
self
.
dataset
.
particlecontours
=
[]
self
.
dataset
.
particlestats
=
[]
self
.
dataset
.
ramanscansortindex
=
[]
self
.
dataset
.
particleContainer
.
clearParticles
()
self
.
dataset
.
particleContainer
.
clearMeasurements
()
self
.
dataset
.
particleDetectionDone
=
False
self
.
dataset
.
ramanscandone
=
False
self
.
dataset
.
mode
=
"opticalscan"
self
.
dataset
.
save
()
...
...
@@ -676,7 +677,7 @@ class ParticleDetectionView(QtWidgets.QWidget):
curParticle
.
addMeasurement
(
particleContainer
.
measurements
[
indexOfNewMeas
])
self
.
dataset
.
particleDetectionDone
=
True
# self.dataset.ramanpoints = measurementPoints #consider moving that to particleContainer
# self.dataset.particlecontours = contours
# self.dataset.particlestats = particlestats
...
...
gepard.py
View file @
d6af372b
...
...
@@ -102,12 +102,13 @@ class GEPARDMainWindow(QtWidgets.QMainWindow):
if
fileName
:
isValid
,
msg
=
self
.
testFilename
(
fileName
)
if
isValid
:
self
.
fname
=
str
(
fileName
)
#TODO: No spaces for Renishaw Interface!!
self
.
fname
=
str
(
fileName
)
self
.
view
.
new
(
self
.
fname
)
self
.
scalingChanged
(
1.
)
else
:
QtWidgets
.
QMessageBox
.
critical
(
self
,
"Error"
,
msg
)
@
QtCore
.
pyqtSlot
()
def
testFilename
(
self
,
fileName
):
if
self
.
view
.
ramanctrl
.
name
==
'RenishawCOM'
:
#the renishawCom does not allow Spaces within filePath
if
fileName
.
find
(
' '
)
==
0
:
...
...
@@ -116,7 +117,7 @@ class GEPARDMainWindow(QtWidgets.QMainWindow):
return
True
,
""
else
:
return
True
,
""
@
QtCore
.
pyqtSlot
()
def
about
(
self
):
QtWidgets
.
QMessageBox
.
about
(
self
,
'GEPARD'
,
...
...
@@ -202,7 +203,7 @@ class GEPARDMainWindow(QtWidgets.QMainWindow):
self
.
configRamanCtrlAct
.
triggered
.
connect
(
self
.
view
.
configureRamanControl
)
if
self
.
view
.
simulatedRaman
:
self
.
configRamanCtrlAct
.
setDisabled
(
True
)
def
updateModes
(
self
,
active
=
None
,
maxenabled
=
None
):
ose
,
osc
,
pde
,
pdc
,
rse
,
rsc
,
pae
,
pac
=
[
False
]
*
8
if
maxenabled
==
"OpticalScan"
:
...
...
imagestitch.py
View file @
d6af372b
...
...
@@ -48,15 +48,17 @@ def imageStacking(colimgs):
return
im
,
zval
def
combineImages
(
path
,
nx
,
ny
,
nk
,
width
,
height
,
angle
):
imgs
=
[]
full
=
None
for
i
in
range
(
nx
):
for
j
in
range
(
ny
):
colimgs
=
[]
for
k
in
range
(
nk
):
colimgs
.
append
(
cv2
.
imread
(
path
+
f
'test_
{
i
}
_
{
j
}
_
{
k
}
.bmp'
))
img
=
imageStacking
(
colimgs
)
imgs
.
append
(
img
)
if
nk
>
1
:
colimgs
=
[]
for
k
in
range
(
nk
):
colimgs
.
append
(
cv2
.
imread
(
path
+
f
'test_
{
i
}
_
{
j
}
_
{
k
}
.bmp'
))
img
=
imageStacking
(
colimgs
)
else
:
img
=
cv2
.
imread
(
path
+
f
'test_
{
i
}
_
{
j
}
_1.bmp'
)
dx
=
i
*
.
9
*
img
.
shape
[
1
]
dy
=
j
*
.
8
*
img
.
shape
[
0
]
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):
full
=
dst
else
:
full
=
cv2
.
max
(
full
,
dst
)
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
from
time
import
time
import
datetime
import
sys
from
opticalbackground
import
BackGroundManager
def
scan
(
path
,
sol
,
zpositions
,
grid
,
controlclass
,
dataqueue
,
stopevent
,
logpath
=
''
,
ishdr
=
False
):
if
ishdr
:
merge_mertens
=
cv2
.
createMergeMertens
()
fp
=
None
if
logpath
!=
''
:
try
:
...
...
@@ -81,18 +82,21 @@ def scan(path, sol, zpositions, grid, controlclass, dataqueue,
if
fp
is
not
None
:
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
,
rotationvalue
,
p0
,
p1
,
p
,
halfResolution
=
Fals
e
):
rotationvalue
,
p0
,
p1
,
p
,
background
=
Non
e
):
colimgs
=
[]
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
)
colimgs
.
append
(
cv2
.
cvtColor
(
curImg
,
cv2
.
COLOR_BGR2RGB
))
img
,
zval
=
imageStacking
(
colimgs
)
if
halfResolution
:
#halve resolution, if fullimage would become too large otherwise
img
=
cv2
.
resize
(
img
,
None
,
fx
=
0.5
,
fy
=
0.5
,
interpolation
=
cv2
.
INTER_CUBIC
)
zval
=
cv2
.
resize
(
zval
,
None
,
fx
=
0.5
,
fy
=
0.5
,
interpolation
=
cv2
.
INTER_CUBIC
)
x
,
y
=
p
Nx
,
Ny
=
int
((
p1
[
0
]
-
p0
[
0
]
+
width
)
/
width
*
img
.
shape
[
1
]),
int
((
p0
[
1
]
-
p1
[
1
]
+
height
)
/
height
*
img
.
shape
[
0
])
+
10
# + 10 because of rotation and hopefully it will be small
c
,
s
=
np
.
cos
(
np
.
radians
(
rotationvalue
)),
np
.
sin
(
np
.
radians
(
rotationvalue
))
...
...
@@ -179,6 +183,7 @@ class PointCoordinates(QtWidgets.QGridLayout):
self
.
itemAtPosition
(
i
+
1
,
5
).
setVisible
(
False
)
self
.
itemAtPosition
(
i
+
1
,
6
).
setVisible
(
False
)
self
.
N
=
N
for
i
,
p
in
pointsgiven
:
wx
,
wy
,
wz
=
self
.
dswidgets
[
i
]
x
,
y
,
z
=
p
...
...
@@ -216,10 +221,12 @@ class PointCoordinates(QtWidgets.QGridLayout):
else
:
points
[
i
,:]
=
np
.
nan
return
points
class
OpticalScan
(
QtWidgets
.
QWidget
):
imageUpdate
=
QtCore
.
pyqtSignal
(
str
,
name
=
'imageUpdate'
)
#str = 'df' (= darkfield) or 'bf' (=bright field)
boundaryUpdate
=
QtCore
.
pyqtSignal
()
backGroundSavedToPath
=
QtCore
.
pyqtSignal
(
int
,
str
)
def
__init__
(
self
,
ramanctrl
,
dataset
,
logpath
=
''
,
parent
=
None
):
super
().
__init__
(
parent
,
QtCore
.
Qt
.
Window
)
...
...
@@ -235,6 +242,22 @@ class OpticalScan(QtWidgets.QWidget):
pointgroup
.
setLayout
(
self
.
points
)
self
.
points
.
readPoint
.
connect
(
self
.
takePoint
)
bkggroup
=
QtWidgets
.
QGroupBox
(
'Manage Background Images'
)
self
.
enableBackGround
=
QtWidgets
.
QCheckBox
(
'Enable BackgroundSubtraction'
)
self
.
enableBackGround
.
setChecked
(
False
)
self
.
enableBackGround
.
stateChanged
.
connect
(
self
.
enableDisableBackground
)
self
.
backGroundManager
=
BackGroundManager
(
self
)
self
.
backGroundManager
.
managerClosed
.
connect
(
self
.
managerWasClosed
)
self
.
backGroundManager
.
readBackground
.
connect
(
self
.
readBackground
)
self
.
showBgkManagerBtn
=
QtWidgets
.
QPushButton
(
'Show Background Manager Window'
)
self
.
showBgkManagerBtn
.
setDisabled
(
True
)
self
.
showBgkManagerBtn
.
clicked
.
connect
(
self
.
showHideBackgroundWindow
)
bkglayout
=
QtWidgets
.
QVBoxLayout
()
bkglayout
.
addWidget
(
self
.
enableBackGround
)
bkglayout
.
addWidget
(
self
.
showBgkManagerBtn
)
bkggroup
.
setLayout
(
bkglayout
)
self
.
pareaselect
=
QtWidgets
.
QPushButton
(
"Area select"
,
self
)
label
=
QtWidgets
.
QLabel
(
"Size increase:"
,
self
)
self
.
radiusincreaseedit
=
QtWidgets
.
QDoubleSpinBox
(
self
)
...
...
@@ -253,7 +276,7 @@ class OpticalScan(QtWidgets.QWidget):
self
.
zmaxedit
.
setMaximumWidth
(
100
)
label3
=
QtWidgets
.
QLabel
(
"Focus steps:"
,
self
)
self
.
nzedit
=
QtWidgets
.
QSpinBox
(
self
)
self
.
nzedit
.
setRange
(
2
,
1
0
)
self
.
nzedit
.
setRange
(
2
,
2
0
)
self
.
nzedit
.
setValue
(
3
)
self
.
nzedit
.
setMaximumWidth
(
100
)
self
.
hdrcheck
=
QtWidgets
.
QCheckBox
(
"High dynamic range"
,
self
)
...
...
@@ -293,11 +316,7 @@ class OpticalScan(QtWidgets.QWidget):
micModeLayout
.
addWidget
(
self
.
df_btn
)
micModeLayout
.
addWidget
(
self
.
bf_btn
)
micModeGroup
.
setLayout
(
micModeLayout
)
self
.
halfResChecker
=
QtWidgets
.
QCheckBox
(
'Half resolution'
)
self
.
halfResChecker
.
setChecked
(
False
)
self
.
halfResChecker
.
setToolTip
(
'Enable for very high resolution images.
\n
Full resolution slows down the scan too much..'
)
self
.
deleteImgChecker
=
QtWidgets
.
QCheckBox
(
'Delete image files after run'
)
self
.
deleteImgChecker
.
setChecked
(
True
)
...
...
@@ -318,16 +337,15 @@ class OpticalScan(QtWidgets.QWidget):
furtherOptionsLayout
.
addRow
(
label3
,
self
.
nzedit
)
furtherOptionsLayout
.
addRow
(
self
.
hdrcheck
)
furtherOptionsLayout
.
addRow
(
self
.
deleteImgChecker
)
furtherOptionsLayout
.
addRow
(
self
.
halfResChecker
)
furtherOptionsGroup
.
setLayout
(
furtherOptionsLayout
)
btnLayout
=
QtWidgets
.
QHBoxLayout
()
btnLayout
.
addWidget
(
self
.
prun
)
btnLayout
.
addWidget
(
self
.
pexit
)
btnLayout
.
addStretch
()
vbox
.
addWidget
(
pointgroup
)
vbox
.
addWidget
(
bkggroup
)
vbox
.
addWidget
(
self
.
areaOptionsGroup
)
vbox
.
addWidget
(
furtherOptionsGroup
)
vbox
.
addLayout
(
btnLayout
)
...
...
@@ -335,9 +353,27 @@ class OpticalScan(QtWidgets.QWidget):
vbox
.
addWidget
(
self
.
progressbar
)