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
a6fa4f0e
Commit
a6fa4f0e
authored
Aug 23, 2019
by
JosefBrandt
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
No further ContourApproximation + Code Cleanup
Contour approximation can lead to wrong ellipse fits...
parent
c90f7b26
Changes
18
Hide whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
94 additions
and
210 deletions
+94
-210
analysis/analysisview.py
analysis/analysisview.py
+1
-13
analysis/database.py
analysis/database.py
+10
-46
analysis/excelexport.py
analysis/excelexport.py
+2
-4
analysis/particleCharacterization.py
analysis/particleCharacterization.py
+8
-12
analysis/particleClassification/colorClassification.py
analysis/particleClassification/colorClassification.py
+21
-19
analysis/particleClassification/shapeClassification.py
analysis/particleClassification/shapeClassification.py
+23
-23
analysis/particleContainer.py
analysis/particleContainer.py
+1
-1
analysis/particleEditor.py
analysis/particleEditor.py
+1
-1
analysis/particlePainter.py
analysis/particlePainter.py
+14
-11
analysis/sqlexport.py
analysis/sqlexport.py
+1
-0
dataset.py
dataset.py
+0
-1
detectionview.py
detectionview.py
+2
-29
imagestitch.py
imagestitch.py
+2
-11
legacyConvert.py
legacyConvert.py
+2
-4
sampleview.py
sampleview.py
+0
-2
scalebar.py
scalebar.py
+1
-11
segmentation.py
segmentation.py
+0
-20
viewitems.py
viewitems.py
+5
-2
No files found.
analysis/analysisview.py
View file @
a6fa4f0e
...
...
@@ -45,7 +45,6 @@ except:
class
ParticleAnalysis
(
QtWidgets
.
QMainWindow
):
def
__init__
(
self
,
dataset
,
viewparent
=
None
):
super
(
ParticleAnalysis
,
self
).
__init__
(
viewparent
)
# self.resize(1680, 1050)
self
.
setWindowTitle
(
'Results of polymer analysis'
)
self
.
layout
=
QtWidgets
.
QHBoxLayout
()
self
.
widget
=
QtWidgets
.
QWidget
()
...
...
@@ -599,15 +598,4 @@ class ParticleAnalysis(QtWidgets.QMainWindow):
window
.
close
()
self
.
viewparent
.
imparent
.
particelAnalysisAct
.
setChecked
(
False
)
event
.
accept
()
if
__name__
==
'__main__'
:
from
..dataset
import
DataSet
def
run
():
app
=
QtWidgets
.
QApplication
(
sys
.
argv
)
meas
=
ParticleAnalysis
(
DataSet
(
"dummydata"
))
meas
.
showMaximized
()
return
app
.
exec_
()
run
()
\ No newline at end of file
event
.
accept
()
\ No newline at end of file
analysis/database.py
View file @
a6fa4f0e
...
...
@@ -27,8 +27,7 @@ with permission from github user CJ Carey (perimosocordiae)
from
PyQt5
import
QtWidgets
,
QtCore
import
numpy
as
np
import
sys
import
dill
import
dill
#TODO: Make it run with pickle... Having two different methods is not so sensefull...
import
os
from
matplotlib.backends.backend_qt5agg
import
FigureCanvasQTAgg
as
FigureCanvas
from
matplotlib.backends.backend_qt5agg
import
NavigationToolbar2QT
as
NavigationToolbar
...
...
@@ -317,16 +316,14 @@ class DataBaseWindow(QtWidgets.QMainWindow):
self
.
removeSpecBtn
.
setText
(
'Remove {}'
.
format
(
self
.
activeSpectrumName
))
self
.
removeSpecBtn
.
setDisabled
(
False
)
def
save
(
self
):
def
save
(
self
,
showMessage
=
True
):
for
index
,
db
in
enumerate
(
self
.
databases
):
# pickling_on = open(db.title+'.dbpkl', 'wb')
# pickle.dump(db, pickling_on)
# pickling_on.close()
savename
=
os
.
path
.
join
(
self
.
path
,
db
.
title
+
'.db'
)
with
open
(
savename
,
'wb'
)
as
f
:
dill
.
dump
(
db
,
f
)
QtWidgets
.
QMessageBox
.
about
(
self
,
'Done.'
,
'Saved {} database(s)'
.
format
(
len
(
self
.
databases
)))
if
showMessage
:
QtWidgets
.
QMessageBox
.
about
(
self
,
'Done.'
,
'Saved {} database(s)'
.
format
(
len
(
self
.
databases
)))
def
updateDBSelectorList
(
self
):
self
.
db_selector
.
clear
()
...
...
@@ -339,7 +336,6 @@ class DataBaseWindow(QtWidgets.QMainWindow):
self
.
db_selector
.
setCurrentText
(
self
.
activeDatabase
.
title
)
def
selectDataBase
(
self
,
refreshParent
=
False
):
# if not self.noDBFound:
if
len
(
self
.
databases
)
>
0
:
self
.
activeDatabaseIndex
=
self
.
db_selector
.
currentIndex
()
self
.
activeDatabase
=
self
.
databases
[
self
.
activeDatabaseIndex
]
...
...
@@ -352,13 +348,7 @@ class DataBaseWindow(QtWidgets.QMainWindow):
self
.
parent
.
populateRefSelector
()
def
closeEvent
(
self
,
event
):
# response = QtWidgets.QMessageBox.question(self, 'Warning', 'Exit without saving?', QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No, QtWidgets.QMessageBox.No)
# if response == QtWidgets.QMessageBox.Yes:
# if self.parent is not None:
# self.parent.setDisabled(False)
# event.accept()
# else:
# event.ignore()
self
.
save
(
showMessage
=
False
)
if
self
.
parent
is
not
None
:
self
.
parent
.
setDisabled
(
False
)
...
...
@@ -426,8 +416,6 @@ class BaseLineCorrect(QtWidgets.QDialog):
for
i
in
range
(
len
(
spectra
)):
spectra
[
i
][:,
1
]
=
self
.
origspectra
[
i
][:,
1
].
copy
()
-
self
.
als_baseline
(
self
.
origspectra
[
i
][:,
1
].
copy
(),
asymmetry_param
=
self
.
asymSpinBox
.
value
(),
smoothness_param
=
self
.
smoothSpinBox
.
value
(),
max_iters
=
self
.
iterSpinBox
.
value
())
# self.newSpectra = spectra.copy()
# self.parent.drawSpectrum(spectra[self.parent.activeSpectrumIndex], self.parent.activeSpectrumName)
self
.
saveBtn
.
setDisabled
(
False
)
def
als_baseline
(
self
,
intensities
,
asymmetry_param
=
0.05
,
smoothness_param
=
1e4
,
...
...
@@ -453,27 +441,17 @@ class BaseLineCorrect(QtWidgets.QDialog):
if
conv
<
conv_thresh
:
break
w
=
new_w
#
else:
#
print( 'ALS did not converge in %d iterations' % max_iters)
else
:
print
(
'ALS did not converge in %d iterations'
%
max_iters
)
return
z
def
save
(
self
):
# self.parent.databases[self.parent.activeDatabaseIndex].spectra = self.spectra
# self.parent.activeDatabase = self.parent.databases[self.parent.activeDatabaseIndex]
# self.parent.activeSpectrum = self.parent.activeDatabase.spectra[self.parent.activeSpectrumIndex]
# self.parent.drawSpectrum(self.parent.activeSpectrum, self.parent.activeSpectrumName)
self
.
close
()
def
cancel
(
self
):
self
.
close
()
def
closeEvent
(
self
,
event
):
if
self
.
parent
is
not
None
:
self
.
parent
.
setDisabled
(
False
)
# self.parent.drawSpectrum(self.parent.activeSpectrum, self.parent.activeSpectrumName)
class
WhittakerSmoother
(
object
):
def
__init__
(
self
,
signal
,
smoothness_param
,
deriv_order
=
1
):
...
...
@@ -549,18 +527,4 @@ class CropSpectra(QtWidgets.QDialog):
def
closeEvent
(
self
,
event
):
if
self
.
parent
is
not
None
:
self
.
parent
.
setDisabled
(
False
)
event
.
accept
()
def
main
():
global
dbWin
#start Application
app
=
QtWidgets
.
QApplication
(
sys
.
argv
)
dbWin
=
DataBaseWindow
(
None
)
app
.
exec_
()
if
__name__
==
'__main__'
:
main
()
\ No newline at end of file
event
.
accept
()
\ No newline at end of file
analysis/excelexport.py
View file @
a6fa4f0e
...
...
@@ -30,14 +30,12 @@ class ExpExcelDialog(QtWidgets.QDialog):
super
(
ExpExcelDialog
,
self
).
__init__
()
self
.
setWindowTitle
(
'Export Options'
)
self
.
setGeometry
(
200
,
200
,
300
,
300
)
self
.
layout
=
QtWidgets
.
QHBoxLayout
()
self
.
setLayout
(
self
.
layout
)
self
.
dataset
=
dataset
self
.
particleContainer
=
dataset
.
particleContainer
self
.
layout
=
QtWidgets
.
QHBoxLayout
()
self
.
setLayout
(
self
.
layout
)
excelvbox
=
QtWidgets
.
QVBoxLayout
()
excelvbox
.
addWidget
(
QtWidgets
.
QLabel
(
'Select Parameters for Export'
))
excelgroup
=
QtWidgets
.
QGroupBox
(
"Export to Excel"
,
self
)
...
...
analysis/particleCharacterization.py
View file @
a6fa4f0e
...
...
@@ -45,8 +45,8 @@ def particleIsValid(particle):
return
False
return
True
def
getParticleStatsWithPixelScale
(
cnt
,
fullimage
,
dataset
):
def
getParticleStatsWithPixelScale
(
contour
,
fullimage
,
dataset
):
cnt
=
deepcopy
(
c
o
nt
our
)
pixelscale
=
dataset
.
getPixelScale
()
newStats
=
ParticleStats
()
...
...
@@ -64,7 +64,7 @@ def getParticleStatsWithPixelScale(cnt, fullimage, dataset):
newStats
.
longSize
,
newStats
.
shortSize
=
getFibreDimension
(
cnt
)
newStats
.
longSize
*=
pixelscale
newStats
.
shortSize
*=
pixelscale
partImg
=
getParticleImageFromFullimage
(
cnt
,
fullimage
)
newStats
.
color
=
getParticleColor
(
partImg
)
return
newStats
...
...
@@ -76,8 +76,6 @@ def getFibreDimension(contour):
maxThickness
=
np
.
max
(
dist
)
*
2
return
longSize
,
maxThickness
def
getParticleColor
(
imgRGB
,
colorClassifier
=
None
):
img
=
cv2
.
cvtColor
(
imgRGB
,
cv2
.
COLOR_RGB2HSV_FULL
)
meanHSV
=
cv2
.
mean
(
img
)
...
...
@@ -130,6 +128,7 @@ def getParticleImageFromFullimage(contour, fullimage):
xmin
,
xmax
,
ymin
,
ymax
=
getContourExtrema
(
contourCopy
)
img
=
fullimage
[
ymin
:
ymax
,
xmin
:
xmax
]
img
=
img
.
copy
()
mask
=
np
.
zeros
(
img
.
shape
[:
2
])
for
i
in
range
(
len
(
contourCopy
)):
...
...
@@ -164,11 +163,11 @@ def contoursToImg(contours, padding=0):
return
img
,
xmin
,
ymin
,
padding
def
imgToCnt
(
img
,
xmin
,
ymin
,
padding
=
0
):
def
getContour
(
img
,
flag
):
def
getContour
(
img
,
contourMode
):
if
cv2
.
__version__
>
'3.5'
:
contours
,
hierarchy
=
cv2
.
findContours
(
img
,
cv2
.
RETR_EXTERNAL
,
flag
)
contours
,
hierarchy
=
cv2
.
findContours
(
img
,
cv2
.
RETR_EXTERNAL
,
contourMode
)
else
:
temp
,
contours
,
hierarchy
=
cv2
.
findContours
(
img
,
cv2
.
RETR_EXTERNAL
,
flag
)
temp
,
contours
,
hierarchy
=
cv2
.
findContours
(
img
,
cv2
.
RETR_EXTERNAL
,
contourMode
)
if
len
(
contours
)
==
0
:
#i.e., no contour found
raise
InvalidParticleError
...
...
@@ -188,10 +187,7 @@ def imgToCnt(img, xmin, ymin, padding=0):
return
contours
[
maxIndex
]
img
=
closeHolesOfSubImage
(
img
)
contour
=
getContour
(
img
,
flag
=
cv2
.
CHAIN_APPROX_SIMPLE
)
if
len
(
contour
)
<
5
:
contour
=
getContour
(
img
,
flag
=
cv2
.
CHAIN_APPROX_NONE
)
contour
=
getContour
(
img
,
contourMode
=
cv2
.
CHAIN_APPROX_NONE
)
for
i
in
range
(
len
(
contour
)):
contour
[
i
][
0
][
0
]
+=
xmin
-
padding
...
...
analysis/particleClassification/colorClassification.py
View file @
a6fa4f0e
...
...
@@ -20,6 +20,26 @@ along with this program, see COPYING.
If not, see <https://www.gnu.org/licenses/>.
"""
class
ColorClassifier
(
object
):
def
__init__
(
self
):
hue_tolerance
=
50
self
.
colors
=
[
ColorRangeHSV
(
'yellow'
,
30
,
hue_tolerance
,
40
,
255
),
ColorRangeHSV
(
'blue'
,
120
,
hue_tolerance
,
40
,
255
),
ColorRangeHSV
(
'red'
,
180
,
hue_tolerance
,
40
,
255
),
ColorRangeHSV
(
'red'
,
0
,
hue_tolerance
,
40
,
255
),
ColorRangeHSV
(
'green'
,
70
,
hue_tolerance
,
40
,
255
),
ColorRangeHSV
(
'white'
,
128
,
256
,
0
,
40
)]
def
classifyColor
(
self
,
meanHSV
):
result
=
'non-determinable'
for
color
in
self
.
colors
:
if
color
.
containsHSV
(
meanHSV
):
result
=
color
.
name
break
return
result
class
ColorRangeHSV
(
object
):
def
__init__
(
self
,
name
,
hue
,
hue_tolerance
,
min_sat
,
max_sat
):
self
.
name
=
name
...
...
@@ -40,22 +60,4 @@ class ColorRangeHSV(object):
else
:
if
sat
<
128
and
hsv
[
2
]
>
70
:
return
True
class
ColorClassifier
(
object
):
def
__init__
(
self
):
hue_tolerance
=
50
self
.
colors
=
[
ColorRangeHSV
(
'yellow'
,
30
,
hue_tolerance
,
40
,
255
),
ColorRangeHSV
(
'blue'
,
120
,
hue_tolerance
,
40
,
255
),
ColorRangeHSV
(
'red'
,
180
,
hue_tolerance
,
40
,
255
),
ColorRangeHSV
(
'red'
,
0
,
hue_tolerance
,
40
,
255
),
ColorRangeHSV
(
'green'
,
70
,
hue_tolerance
,
40
,
255
),
ColorRangeHSV
(
'white'
,
128
,
256
,
0
,
40
)]
def
classifyColor
(
self
,
meanHSV
):
result
=
'non-determinable'
for
color
in
self
.
colors
:
if
color
.
containsHSV
(
meanHSV
):
result
=
color
.
name
break
return
result
\ No newline at end of file
\ No newline at end of file
analysis/particleClassification/shapeClassification.py
View file @
a6fa4f0e
...
...
@@ -22,6 +22,28 @@ If not, see <https://www.gnu.org/licenses/>.
import
cv2
from
errors
import
InvalidParticleError
class
ShapeClassifier
(
object
):
def
__init__
(
self
):
self
.
shapeClasses
=
[
Spherule
(),
Fibre
(),
Irregular
()]
def
classifyShape
(
self
,
contour
,
particleHeight
):
newShape
=
BaseShape
()
newShape
.
contour
=
contour
newShape
.
height
=
particleHeight
newShape
.
getParticleCharacteristics
()
mostFittingCriteria
=
0
bestFittingShape
=
'unknown'
for
testShape
in
self
.
shapeClasses
:
numFits
=
newShape
.
fitsOtherShapeCriteria
(
testShape
)
if
numFits
>
mostFittingCriteria
:
mostFittingCriteria
=
numFits
bestFittingShape
=
testShape
.
name
return
bestFittingShape
class
BaseShape
(
object
):
def
__init__
(
self
):
self
.
name
=
None
...
...
@@ -124,26 +146,4 @@ class Fibre(BaseShape):
self
.
name
=
'fibre'
self
.
aspectRatioRange
=
[
3
,
1000
]
self
.
solidityRange
=
[
0.0
,
0.4
]
self
.
height2AverageLengthRange
=
[
0
,
1000
]
class
ShapeClassifier
(
object
):
def
__init__
(
self
):
self
.
shapeClasses
=
[
Spherule
(),
Fibre
(),
Irregular
()]
def
classifyShape
(
self
,
contour
,
particleHeight
):
newShape
=
BaseShape
()
newShape
.
contour
=
contour
newShape
.
height
=
particleHeight
newShape
.
getParticleCharacteristics
()
mostFittingCriteria
=
0
bestFittingShape
=
'unknown'
for
testShape
in
self
.
shapeClasses
:
numFits
=
newShape
.
fitsOtherShapeCriteria
(
testShape
)
if
numFits
>
mostFittingCriteria
:
mostFittingCriteria
=
numFits
bestFittingShape
=
testShape
.
name
return
bestFittingShape
\ No newline at end of file
self
.
height2AverageLengthRange
=
[
0
,
1000
]
\ No newline at end of file
analysis/particleContainer.py
View file @
a6fa4f0e
...
...
@@ -101,7 +101,7 @@ class ParticleContainer(object):
for
index
,
particle
in
enumerate
(
self
.
particles
):
particle
.
__dict__
.
update
(
particlestats
[
index
].
__dict__
)
def
testForInconsistentParticles
(
self
):
#i.e., particles that have multiple measurements with different assignments
def
testForInconsistentParticle
Assignment
s
(
self
):
#i.e., particles that have multiple measurements with different assignments
self
.
inconsistentParticles
=
[]
for
particle
in
self
.
particles
:
if
not
particle
.
measurementsHaveSameOrigAssignment
():
...
...
analysis/particleEditor.py
View file @
a6fa4f0e
...
...
@@ -100,7 +100,7 @@ class ParticleContextMenu(QtWidgets.QMenu):
self
.
colorMenu
=
QtWidgets
.
QMenu
(
"Set Particle Color To"
)
self
.
colorActs
=
[]
for
color
in
[
'white'
,
'black'
,
'blue'
,
'brown'
,
'green'
,
'grey'
,
'non-determinable'
,
'red'
,
'transparent'
,
'yellow'
]:
for
color
in
[
'white'
,
'black'
,
'blue'
,
'brown'
,
'green'
,
'grey'
,
'non-determinable'
,
'red'
,
'transparent'
,
'yellow'
,
'violet'
]:
self
.
colorActs
.
append
(
self
.
colorMenu
.
addAction
(
color
))
self
.
shapeMenu
=
QtWidgets
.
QMenu
(
"Set Particle Shape To"
)
...
...
analysis/particlePainter.py
View file @
a6fa4f0e
...
...
@@ -99,9 +99,22 @@ class ParticlePainter(QtWidgets.QGraphicsItem):
self
.
editorParent
.
acceptPaintedResult
()
def
drawParticle
(
self
,
pixelPos
):
self
.
adjustMarginsAndPlaceImage
(
pixelPos
)
center
=
(
int
(
pixelPos
.
x
()),
int
(
pixelPos
.
y
()))
if
self
.
painting
:
cv2
.
circle
(
self
.
img
,
center
,
self
.
radius
,
255
,
-
1
)
elif
self
.
erasing
:
cv2
.
circle
(
self
.
img
,
center
,
self
.
radius
,
0
,
-
1
)
self
.
setPixmap
()
self
.
update
()
def
adjustMarginsAndPlaceImage
(
self
,
pixelPos
):
x_min
,
x_max
=
round
(
pixelPos
.
x
()
-
self
.
radius
),
round
(
pixelPos
.
x
()
+
self
.
radius
)
y_min
,
y_max
=
round
(
pixelPos
.
y
()
-
self
.
radius
),
round
(
pixelPos
.
y
()
+
self
.
radius
)
#TODO: Using cv2.warpAffine would probably be more elegant....
x_shift
=
y_shift
=
int
(
0
)
if
x_min
<
0
:
...
...
@@ -146,17 +159,7 @@ class ParticlePainter(QtWidgets.QGraphicsItem):
self
.
img
=
np
.
uint8
(
newImg
)
self
.
setBrect
()
center
=
(
int
(
pixelPos
.
x
()),
int
(
pixelPos
.
y
()))
if
self
.
painting
:
cv2
.
circle
(
self
.
img
,
center
,
self
.
radius
,
255
,
-
1
)
elif
self
.
erasing
:
cv2
.
circle
(
self
.
img
,
center
,
self
.
radius
,
0
,
-
1
)
self
.
setPixmap
()
self
.
update
()
def
paint
(
self
,
painter
,
option
,
widget
):
painter
.
setPen
(
QtCore
.
Qt
.
white
)
painter
.
drawRect
(
self
.
brect
)
...
...
analysis/sqlexport.py
View file @
a6fa4f0e
...
...
@@ -437,6 +437,7 @@ class SQLExport(QtWidgets.QDialog):
self
.
dbAssignments
.
updateAssignment
(
polymerType
,
result
,
categ_result
,
paint_remark
)
self
.
dbAssignments
.
save
()
class
LinkedLineEdit
(
QtWidgets
.
QLineEdit
):
def
__init__
(
self
,
combobox
):
...
...
dataset.py
View file @
a6fa4f0e
...
...
@@ -133,7 +133,6 @@ class DataSet(object):
'blurRadius'
:
9
,
'threshold'
:
0.2
,
'maxholebrightness'
:
0.5
,
'erodeconvexdefects'
:
0
,
'minparticlearea'
:
20
,
'minparticledistance'
:
20
,
'measurefrac'
:
1
,
...
...
detectionview.py
View file @
a6fa4f0e
...
...
@@ -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
,
MeasurementPoint
from
segmentation
import
Segmentation
from
matplotlib.backends.backend_qt5agg
import
FigureCanvasQTAgg
import
matplotlib.pyplot
as
plt
from
threading
import
Thread
...
...
@@ -164,7 +164,7 @@ class ImageView(QtWidgets.QLabel):
self
.
seeddeletepoints
=
arr
[
ind
,:].
tolist
()
def
mousePressEvent
(
self
,
event
):
if
event
.
button
()
==
QtCore
.
Qt
.
LeftButton
and
event
.
modifiers
()
&
QtCore
.
Qt
.
ControlModifier
:
if
event
.
button
()
==
QtCore
.
Qt
.
LeftButton
:
if
event
.
modifiers
()
&
QtCore
.
Qt
.
ShiftModifier
:
self
.
drag
=
"delete"
elif
event
.
modifiers
()
&
QtCore
.
Qt
.
AltModifier
:
...
...
@@ -234,7 +234,6 @@ class ImageView(QtWidgets.QLabel):
self
.
overlay
=
pix
def
paintEvent
(
self
,
event
):
painter
=
QtGui
.
QPainter
(
self
)
painter
.
drawPixmap
(
0
,
0
,
self
.
pixmap
())
painter
.
setOpacity
(
self
.
alpha
)
...
...
@@ -249,7 +248,6 @@ class ImageView(QtWidgets.QLabel):
painter
.
setBrush
(
QtCore
.
Qt
.
red
)
for
p
in
self
.
measpoints
:
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
:
...
...
@@ -666,12 +664,10 @@ class ParticleDetectionView(QtWidgets.QWidget):
self
.
dataset
.
ramanscandone
=
False
particleContainer
=
self
.
dataset
.
particleContainer
numParticles
=
len
(
contours
)
particleContainer
.
initializeParticles
(
numParticles
)
particleContainer
.
setParticleContours
(
contours
)
particleContainer
.
setParticleStats
(
particlestats
)
# particleContainer.applyPixelScaleToParticleStats(self.dataset.getPixelScale())
for
particleIndex
in
measurementPoints
.
keys
():
measPoints
=
measurementPoints
[
particleIndex
]
...
...
@@ -684,26 +680,3 @@ class ParticleDetectionView(QtWidgets.QWidget):
self
.
dataset
.
particleDetectionDone
=
True
self
.
dataset
.
mode
=
"prepareraman"
self
.
dataset
.
save
()
if
__name__
==
"__main__"
:
import
cv2
import
sys
from
helperfunctions
import
cv2imread_fix
from
dataset
import
DataSet
from
time
import
time
fname
=
r
"C:\Users\brandt\Desktop\20180723DemoTZW\fullimage.tif"
app
=
QtWidgets
.
QApplication
(
sys
.
argv
)
t2
=
time
()
img
=
cv2imread_fix
(
fname
)
t3
=
time
()
print
(
"OpenCV read:"
,
t3
-
t2
)
img
=
cv2
.
cvtColor
(
img
,
cv2
.
COLOR_BGR2RGB
)
ds
=
DataSet
(
"dummy"
)
view
=
ParticleDetectionView
(
img
,
ds
,
None
)
view
.
setDataSet
(
ds
)
view
.
show
()
app
.
exec_
()
\ No newline at end of file
imagestitch.py
View file @
a6fa4f0e
...
...
@@ -47,7 +47,7 @@ def imageStacking(colimgs):
im
=
np
.
uint8
(
im
)
return
im
,
zval
def
combineImages
(
path
,
nx
,
ny
,
nk
,
width
,
height
,
angle
):
def
combineImages
(
path
,
nx
,
ny
,
nk
,
width
,
height
,
angle
):
#TODO: Currently not used anywhere. Remove? Might be useful, still...
full
=
None
for
i
in
range
(
nx
):
for
j
in
range
(
ny
):
...
...
@@ -70,13 +70,4 @@ def combineImages(path, nx, ny, nk, width, height, angle):
else
:
full
=
cv2
.
max
(
full
,
dst
)
cv2
.
imwrite
(
"full_dunkel.png"
,
full
)
if
__name__
==
"__main__"
:
path
=
"../Bildserie-Scan/dunkelfeld/"
Nx
,
Ny
,
Nk
=
10
,
10
,
4
width
,
height
,
angle
=
463.78607177734375
,
296.0336608886719
,
-
0.04330849274992943
combineImages
(
path
,
Nx
,
Ny
,
Nk
,
width
,
height
,
angle
)
\ No newline at end of file
cv2
.
imwrite
(
"full_dunkel.png"
,
full
)
\ No newline at end of file
legacyConvert.py
View file @
a6fa4f0e
...
...
@@ -112,12 +112,10 @@ def legacyConversion(dset, recreatefullimage=False):
def
transferParticleStatsToParticleContainer
(
dset
):
dset
.
particleContainer
=
ParticleContainer
(
dset
)
dset
.
particleContainer
.
initializeParticles
(
len
(
dset
.
particlestats
))
dset
.
particleContainer
.
setParticleContours
(
dset
.
particlecontours
)
# dset.particleContainer.setParticleStats(dset.particlestats)
assert
len
(
dset
.
particleContainer
.
particles
)
==
len
(
dset
.
particlestats
)
#particlestats is list of [long, short, longellipse, shortellipse, cv2.contourArea(cnt)]
for
index
,
particle
in
enumerate
(
dset
.
particleContainer
.
particles
):
particle
.
longSize_box
=
float
(
dset
.
particlestats
[
index
][
0
])
particle
.
shortSize_box
=
float
(
dset
.
particlestats
[
index
][
1
])
...
...
@@ -152,7 +150,7 @@ def transferParticleStatsToParticleContainer(dset):
meas
.
setAssignment
(
dset
.
results
[
'polymers'
][
specIndex
])
meas
.
setHQI
(
dset
.
results
[
'hqis'
][
specIndex
])
dset
.
particleContainer
.
testForInconsistentParticles
()
dset
.
particleContainer
.
testForInconsistentParticle
Assignment
s
()
def
updateParticleStats
(
dset
):
def
markForDeletion
(
particle
):
...
...
sampleview.py
View file @
a6fa4f0e
...
...
@@ -472,13 +472,11 @@ class SampleView(QtWidgets.QGraphicsView):
data
=
cv2
.
cvtColor
(
cv2imread_fix
(
fname
),
cv2
.
COLOR_BGR2RGB
)
self
.
imgdata
=
data
if
data
is
not
None
:
height
,
width
,
channel
=
data
.
shape
bytesPerLine
=
3
*
width
pix
=
QtGui
.
QPixmap
()
pix
.
convertFromImage
(
QtGui
.
QImage
(
data
.
data
,
width
,
height
,
bytesPerLine
,
QtGui
.
QImage
.
Format_RGB888
))
self
.
item
.
setPixmap
(
pix
)
if
self
.
darkenPixmap
:
...
...
scalebar.py
View file @
a6fa4f0e
...
...
@@ -88,14 +88,4 @@ class ScaleBar(QtWidgets.QMdiSubWindow):
qp
.
drawRect
((
WX
-
self
.
wscale
)
//
2
,
y0
,
self
.
wscale
,
dy
)
qp
.
drawText
((
WX
-
self
.
wscale
)
//
2
,
5
,
self
.
wscale
,
dy
+
20
,
QtCore
.
Qt
.
AlignCenter
,
str
(
int
(
self
.
divisor
))
+
" µm"
)
qp
.
end
()
if
__name__
==
'__main__'
:
import
sys
app
=
QtWidgets
.
QApplication
(
sys
.
argv
)
meas
=
ScaleBar
(
None
)
meas
.
show
()
sys
.
exit
(
app
.
exec_
())
\ No newline at end of file
qp
.
end
()
\ No newline at end of file
segmentation.py
View file @
a6fa4f0e
...
...
@@ -225,26 +225,6 @@ class Segmentation(object):
return
edges
def
erodeConvexDefects
(
self
,
thresh
,
numiter
):
thresh
=
cv2
.
copyMakeBorder
(
thresh
,
1
,
1
,
1
,
1
,
0
)
for
iterations
in
range
(
numiter
):
if
cv2
.
__version__
>
'3.5'
:
contours
,
hierarchy
=
cv2
.
findContours
(
thresh
.
copy
(),
cv2
.
RETR_TREE
,
cv2
.
CHAIN_APPROX_SIMPLE
)
else
:
thresh2
,
contours
,
hierarchy
=
cv2
.
findContours
(
thresh
.
copy
(),
cv2
.
RETR_TREE
,
cv2
.
CHAIN_APPROX_SIMPLE
)
for
cnt
in
contours
:
hull
=
cv2
.
convexHull
(
cnt
,
returnPoints
=
False
)
defects
=
cv2
.
convexityDefects
(
cnt
,
hull
)
if
defects
is
not
None
:
sqarea
=
np
.
sqrt
(
cv2
.
contourArea
(
cnt
))
blobsize
=
int
(
sqarea
/
15
*
1
/
(
iterations
+
1
))
for
i
in
range
(
defects
.
shape
[
0
]):
s
,
e
,
f
,
d
=
defects
[
i
,
0
]
if
d
>
sqarea
*
5
:
cv2
.
circle
(
thresh
,
tuple
(
cnt
[
f
][
0
]),
blobsize
,
0
,
-
1
)
return
thresh
[
1
:
-
1
,
1
:
-
1
]
def
filterThresholdByAreas
(
self
,
thresh
,
minarea
,
maxarea
):
newthresh
=
np
.
zeros_like
(
thresh
)
n
,
labels
,
stats
,
centroids
=
cv2
.
connectedComponentsWithStats
(
thresh
,
8
,
cv2
.
CV_32S
)
...
...
viewitems.py
View file @
a6fa4f0e
...
...
@@ -79,6 +79,9 @@ class SegmentationContour(QtWidgets.QGraphicsItem):
painter
.
setBrush
(
self
.
color
)
painter
.
drawPolygon
(
self
.
polygon
)
self
.
viewparent
.
update
()
else
:
print
(
'painting not present contour'
)
def
contextMenuEvent
(
self
,
event
):
if
self
.
isSelected
:
...
...
@@ -274,10 +277,10 @@ class ParticleInfo(QtWidgets.QGraphicsItem):
self
.
entries
[
'Assignment:'
]
=
self
.
particle
.
getParticleAssignment
()
self
.
entries
[
'Long Size (µm):'
]
=
int
(
round
(
self
.
particle
.
longSize
))
self
.
entries
[
'Short Size (µm):'
]
=
int
(
round
(
self
.
particle
.
shortSize
))
self
.
entries
[
'Average Height (µm)'
]
=
int
(
round
(
self
.
particle
.
height
))
self
.
entries
[
'Average Height (µm)
:
'
]
=
int
(
round
(
self
.
particle
.
height
))
self
.
entries
[
'Color:'
]