Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
G
GEPARD
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Operations
Operations
Incidents
Packages & Registries
Packages & Registries
Package Registry
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
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
(
contour
)
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:'
]
=
self
.
particle
.
color
self
.
entries
[
'Shape:'
]
=
self
.
particle
.
shape