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
Josef Brandt
Subsampling
Commits
064d26eb
Commit
064d26eb
authored
Mar 09, 2020
by
Josef Brandt
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Dataset can be loaded in mainView
parent
c8650c49
Changes
9
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
561 additions
and
144 deletions
+561
-144
geometricMethods.py
geometricMethods.py
+68
-15
gui/filterView.py
gui/filterView.py
+150
-12
gui/mainView.py
gui/mainView.py
+10
-0
gui/measureModes.py
gui/measureModes.py
+10
-17
helpers.py
helpers.py
+104
-15
methods.py
methods.py
+0
-24
subsampling.py
subsampling.py
+53
-47
tests/test_geometricMethods.py
tests/test_geometricMethods.py
+47
-8
tests/test_helpers.py
tests/test_helpers.py
+119
-6
No files found.
geometricMethods.py
View file @
064d26eb
import
numpy
as
np
import
numpy
as
np
from
itertools
import
combinations
from
itertools
import
combinations
from
methods
import
BoxSelectionSubsamplingMethod
from
methods
import
SubsamplingMethod
from
helpers
import
box_contains_contour
import
sys
sys
.
path
.
append
(
"C://Users//xbrjos//Desktop//Python"
)
from
gepard
import
dataset
class
BoxSelectionSubsamplingMethod
(
SubsamplingMethod
):
def
__init__
(
self
,
*
args
):
super
(
BoxSelectionSubsamplingMethod
,
self
).
__init__
(
*
args
)
self
.
filterDiameter
:
float
=
500
self
.
offset
:
tuple
=
(
0
,
0
)
@
property
def
filterArea
(
self
)
->
float
:
return
np
.
pi
*
(
self
.
filterDiameter
/
2
)
**
2
def
apply_subsampling_method
(
self
)
->
tuple
:
subParticles
:
list
=
[]
topLefts
:
list
=
self
.
get_topLeft_of_boxes
()
boxSize
=
self
.
boxSize
for
particle
in
self
.
particleContainer
.
particles
:
for
topLeft
in
topLefts
:
if
box_overlaps_contour
(
topLeft
,
(
boxSize
,
boxSize
),
particle
.
contour
,
self
.
offset
):
subParticles
.
append
(
particle
)
return
self
.
fraction
,
subParticles
def
get_topLeft_of_boxes
(
self
)
->
list
:
raise
NotImplementedError
class
BoxSelectionCreator
(
object
):
def
__init__
(
self
,
dataset
:
dataset
.
DataSet
):
super
(
BoxSelectionCreator
,
self
).
__init__
()
self
.
dataset
:
dataset
.
DataSet
=
dataset
def
get_crossBoxSelectors_for_fraction
(
self
,
desiredFraction
:
float
)
->
list
:
"""
Creates CrossBoxSelectors that fullfil the desired fraction criterium.
:param desiredFraction:
:return:
"""
crossBoxSelectors
=
[]
offset
,
diameter
,
widthHeight
=
self
.
get_filterDimensions_from_dataset
()
# for numBoxesAcross in [3, 5]:
# newBoxSelector: CrossBoxSelector = CrossBoxSelector(self.dataset.particleContainer, desiredFraction)
# newBoxSelector.filterDiameter = diameter
# newBoxSelector.offset = offset
# newBoxSelector.numBoxesAcross = numBoxesAcross
#
# crossBoxSelectors.append(newBoxSelector)
return
crossBoxSelectors
class
CrossBoxSelector
(
BoxSelectionSubsamplingMethod
):
class
CrossBoxSelector
(
BoxSelectionSubsamplingMethod
):
...
@@ -41,7 +94,7 @@ class CrossBoxSelector(BoxSelectionSubsamplingMethod):
...
@@ -41,7 +94,7 @@ class CrossBoxSelector(BoxSelectionSubsamplingMethod):
:return float:
:return float:
"""
"""
alpha
:
float
=
np
.
deg2rad
(
135
)
alpha
:
float
=
np
.
deg2rad
(
135
)
r
:
float
=
self
.
filter
Size
/
2
r
:
float
=
self
.
filter
Diameter
/
2
d
:
float
=
(
self
.
numBoxesAcross
-
1
)
*
r
/
self
.
numBoxesAcross
# 2/3*r for numAcross = 3, 4/5*r numAcross = 5
d
:
float
=
(
self
.
numBoxesAcross
-
1
)
*
r
/
self
.
numBoxesAcross
# 2/3*r for numAcross = 3, 4/5*r numAcross = 5
delta
:
float
=
np
.
arcsin
((
np
.
sin
(
alpha
)
*
d
)
/
r
)
delta
:
float
=
np
.
arcsin
((
np
.
sin
(
alpha
)
*
d
)
/
r
)
gamma
:
float
=
np
.
pi
-
alpha
-
delta
gamma
:
float
=
np
.
pi
-
alpha
-
delta
...
@@ -69,11 +122,11 @@ class CrossBoxSelector(BoxSelectionSubsamplingMethod):
...
@@ -69,11 +122,11 @@ class CrossBoxSelector(BoxSelectionSubsamplingMethod):
return
self
.
_get_box_starts
(
boxSize
)
return
self
.
_get_box_starts
(
boxSize
)
def
_get_box_starts
(
self
,
boxSize
:
float
)
->
list
:
def
_get_box_starts
(
self
,
boxSize
:
float
)
->
list
:
maxBoxSize
:
float
=
self
.
filter
Size
/
self
.
numBoxesAcross
maxBoxSize
:
float
=
self
.
filter
Diameter
/
self
.
numBoxesAcross
assert
maxBoxSize
>=
boxSize
assert
maxBoxSize
>=
boxSize
tileStarts
:
list
=
[]
tileStarts
:
list
=
[]
for
i
in
range
(
self
.
numBoxesAcross
):
for
i
in
range
(
self
.
numBoxesAcross
):
start
:
float
=
i
*
self
.
filter
Size
/
self
.
numBoxesAcross
+
(
maxBoxSize
-
boxSize
)
/
2
start
:
float
=
i
*
self
.
filter
Diameter
/
self
.
numBoxesAcross
+
(
maxBoxSize
-
boxSize
)
/
2
tileStarts
.
append
(
start
)
tileStarts
.
append
(
start
)
return
tileStarts
return
tileStarts
...
@@ -102,7 +155,7 @@ class SpiralSelector(BoxSelectionSubsamplingMethod):
...
@@ -102,7 +155,7 @@ class SpiralSelector(BoxSelectionSubsamplingMethod):
Calculates the topLeft-points (x, y) of all measure boxes
Calculates the topLeft-points (x, y) of all measure boxes
The method uses an approximation for the spiral and is not purely accurate.
The method uses an approximation for the spiral and is not purely accurate.
:return list:"""
:return list:"""
filterCenter
:
tuple
=
self
.
filter
Size
/
2
-
self
.
boxSize
/
2
,
self
.
filter
Size
/
2
-
self
.
boxSize
/
2
filterCenter
:
tuple
=
self
.
filter
Diameter
/
2
-
self
.
boxSize
/
2
,
self
.
filter
Diameter
/
2
-
self
.
boxSize
/
2
slope
=
self
.
spiralSlope
slope
=
self
.
spiralSlope
theta
:
float
=
0
theta
:
float
=
0
boxDistance
=
self
.
boxSize
*
1.1
boxDistance
=
self
.
boxSize
*
1.1
...
@@ -123,25 +176,25 @@ class SpiralSelector(BoxSelectionSubsamplingMethod):
...
@@ -123,25 +176,25 @@ class SpiralSelector(BoxSelectionSubsamplingMethod):
This function moves and scales the topLeft-Points so that all measure boxes lie within the filter limits.
This function moves and scales the topLeft-Points so that all measure boxes lie within the filter limits.
:return list:
:return list:
"""
"""
xCoords
:
np
.
array
=
np
.
array
([
float
(
point
[
0
])
for
point
in
topLefts
])
-
self
.
filter
Size
/
2
xCoords
:
np
.
nd
array
=
np
.
array
([
float
(
point
[
0
])
for
point
in
topLefts
])
-
self
.
filter
Diameter
/
2
yCoords
:
np
.
array
=
np
.
array
([
float
(
point
[
1
])
for
point
in
topLefts
])
-
self
.
filter
Size
/
2
yCoords
:
np
.
nd
array
=
np
.
array
([
float
(
point
[
1
])
for
point
in
topLefts
])
-
self
.
filter
Diameter
/
2
xCoordsBoxMiddles
:
np
.
array
=
xCoords
+
self
.
boxSize
/
2
xCoordsBoxMiddles
:
np
.
nd
array
=
xCoords
+
self
.
boxSize
/
2
yCoordsBoxMiddles
:
np
.
array
=
yCoords
+
self
.
boxSize
/
2
yCoordsBoxMiddles
:
np
.
nd
array
=
yCoords
+
self
.
boxSize
/
2
lastBoxCenter
:
tuple
=
(
xCoordsBoxMiddles
[
-
1
],
yCoordsBoxMiddles
[
-
1
])
lastBoxCenter
:
tuple
=
(
xCoordsBoxMiddles
[
-
1
],
yCoordsBoxMiddles
[
-
1
])
distanceLastCenter
:
float
=
np
.
linalg
.
norm
(
lastBoxCenter
)
distanceLastCenter
:
float
=
np
.
linalg
.
norm
(
lastBoxCenter
)
maxDistanceInLastBox
:
float
=
self
.
_get_max_distance_of_boxCenter_to_center
(
lastBoxCenter
)
maxDistanceInLastBox
:
float
=
self
.
_get_max_distance_of_boxCenter_to_center
(
lastBoxCenter
)
halfBoxDistance
:
float
=
maxDistanceInLastBox
-
distanceLastCenter
halfBoxDistance
:
float
=
maxDistanceInLastBox
-
distanceLastCenter
desiredDistanceTotal
:
float
=
self
.
filter
Height
/
2
desiredDistanceTotal
:
float
=
self
.
filter
Diameter
/
2
desiredDistanceCenter
:
float
=
desiredDistanceTotal
-
halfBoxDistance
desiredDistanceCenter
:
float
=
desiredDistanceTotal
-
halfBoxDistance
scaleFactor
:
float
=
desiredDistanceCenter
/
distanceLastCenter
scaleFactor
:
float
=
desiredDistanceCenter
/
distanceLastCenter
xCoordsBoxMiddles
*=
scaleFactor
xCoordsBoxMiddles
*=
scaleFactor
yCoordsBoxMiddles
*=
scaleFactor
yCoordsBoxMiddles
*=
scaleFactor
xCoords
=
xCoordsBoxMiddles
+
(
self
.
filter
Size
-
self
.
boxSize
)
/
2
xCoords
=
xCoordsBoxMiddles
+
(
self
.
filter
Diameter
-
self
.
boxSize
)
/
2
yCoords
=
yCoordsBoxMiddles
+
(
self
.
filter
Size
-
self
.
boxSize
)
/
2
yCoords
=
yCoordsBoxMiddles
+
(
self
.
filter
Diameter
-
self
.
boxSize
)
/
2
newTopLefts
=
zip
(
np
.
round
(
xCoords
),
np
.
round
(
yCoords
))
newTopLefts
=
zip
(
np
.
round
(
xCoords
),
np
.
round
(
yCoords
))
return
list
(
tuple
(
newTopLefts
))
return
list
(
tuple
(
newTopLefts
))
...
@@ -155,12 +208,12 @@ class SpiralSelector(BoxSelectionSubsamplingMethod):
...
@@ -155,12 +208,12 @@ class SpiralSelector(BoxSelectionSubsamplingMethod):
"""
"""
center
=
np
.
array
(
center
)
center
=
np
.
array
(
center
)
boxSize
=
self
.
boxSize
boxSize
=
self
.
boxSize
coords
:
np
.
array
=
np
.
array
([[
boxCenter
[
0
]
-
0.5
*
boxSize
,
boxCenter
[
1
]
-
0.5
*
boxSize
],
coords
:
np
.
nd
array
=
np
.
array
([[
boxCenter
[
0
]
-
0.5
*
boxSize
,
boxCenter
[
1
]
-
0.5
*
boxSize
],
[
boxCenter
[
0
]
+
0.5
*
boxSize
,
boxCenter
[
1
]
-
0.5
*
boxSize
],
[
boxCenter
[
0
]
+
0.5
*
boxSize
,
boxCenter
[
1
]
-
0.5
*
boxSize
],
[
boxCenter
[
0
]
-
0.5
*
boxSize
,
boxCenter
[
1
]
+
0.5
*
boxSize
],
[
boxCenter
[
0
]
-
0.5
*
boxSize
,
boxCenter
[
1
]
+
0.5
*
boxSize
],
[
boxCenter
[
0
]
+
0.5
*
boxSize
,
boxCenter
[
1
]
+
0.5
*
boxSize
]])
[
boxCenter
[
0
]
+
0.5
*
boxSize
,
boxCenter
[
1
]
+
0.5
*
boxSize
]])
distances
:
np
.
array
=
np
.
linalg
.
norm
(
coords
-
center
,
axis
=
1
)
distances
:
np
.
nd
array
=
np
.
linalg
.
norm
(
coords
-
center
,
axis
=
1
)
return
np
.
max
(
distances
)
return
np
.
max
(
distances
)
def
_get_xy_at_angle
(
self
,
theta
:
float
,
centerXY
:
tuple
=
(
0
,
0
))
->
tuple
:
def
_get_xy_at_angle
(
self
,
theta
:
float
,
centerXY
:
tuple
=
(
0
,
0
))
->
tuple
:
...
...
gui/filterView.py
View file @
064d26eb
from
PyQt5
import
QtGui
,
QtWidgets
,
QtCore
from
PyQt5
import
QtGui
,
QtWidgets
,
QtCore
import
sys
sys
.
path
.
append
(
"C://Users//xbrjos//Desktop//Python"
)
import
gepard
from
gepard
import
dataset
import
helpers
class
FilterView
(
QtWidgets
.
QGraphicsView
):
class
FilterView
(
QtWidgets
.
QGraphicsView
):
...
@@ -7,6 +12,8 @@ class FilterView(QtWidgets.QGraphicsView):
...
@@ -7,6 +12,8 @@ class FilterView(QtWidgets.QGraphicsView):
super
(
FilterView
,
self
).
__init__
()
super
(
FilterView
,
self
).
__init__
()
self
.
setWindowTitle
(
'FilterView'
)
self
.
setWindowTitle
(
'FilterView'
)
self
.
dataset
:
dataset
.
DataSet
=
None
scene
=
QtWidgets
.
QGraphicsScene
(
self
)
scene
=
QtWidgets
.
QGraphicsScene
(
self
)
scene
.
setItemIndexMethod
(
QtWidgets
.
QGraphicsScene
.
NoIndex
)
scene
.
setItemIndexMethod
(
QtWidgets
.
QGraphicsScene
.
NoIndex
)
scene
.
setBackgroundBrush
(
QtCore
.
Qt
.
darkGray
)
scene
.
setBackgroundBrush
(
QtCore
.
Qt
.
darkGray
)
...
@@ -14,37 +21,124 @@ class FilterView(QtWidgets.QGraphicsView):
...
@@ -14,37 +21,124 @@ class FilterView(QtWidgets.QGraphicsView):
self
.
setCacheMode
(
QtWidgets
.
QGraphicsView
.
CacheBackground
)
self
.
setCacheMode
(
QtWidgets
.
QGraphicsView
.
CacheBackground
)
self
.
setViewportUpdateMode
(
QtWidgets
.
QGraphicsView
.
BoundingRectViewportUpdate
)
self
.
setViewportUpdateMode
(
QtWidgets
.
QGraphicsView
.
BoundingRectViewportUpdate
)
self
.
setRenderHint
(
QtGui
.
QPainter
.
Antialiasing
)
self
.
setRenderHint
(
QtGui
.
QPainter
.
Antialiasing
)
self
.
setTransformationAnchor
(
QtWidgets
.
QGraphicsView
.
AnchorUnderMouse
)
self
.
setResizeAnchor
(
QtWidgets
.
QGraphicsView
.
AnchorUnderMouse
)
self
.
drag
=
None
self
.
filter
=
FilterGraphItem
()
self
.
filter
:
FilterGraphItem
=
FilterGraphItem
()
self
.
scene
().
addItem
(
self
.
filter
)
self
.
scene
().
addItem
(
self
.
filter
)
self
.
measuringBoxes
:
list
=
[]
self
.
measuringBoxes
:
list
=
[]
self
.
contourItems
:
list
=
[]
def
update_measure_boxes
(
self
,
viewItems
:
lis
t
)
->
None
:
def
update_measure_boxes
(
self
,
topLefts
:
list
,
boxSize
:
floa
t
)
->
None
:
self
.
_remove_measure_boxes
()
self
.
_remove_measure_boxes
()
for
item
in
viewItems
:
offset
=
self
.
filter
.
circleOffset
self
.
measuringBoxes
.
append
(
item
)
for
x
,
y
in
topLefts
:
self
.
scene
().
addItem
(
item
)
newBox
:
MeasureBoxGraphItem
=
MeasureBoxGraphItem
(
x
+
offset
[
0
],
y
+
offset
[
1
],
boxSize
,
boxSize
)
self
.
measuringBoxes
.
append
(
newBox
)
self
.
scene
().
addItem
(
newBox
)
self
.
_update_measured_contours
()
def
_remove_measure_boxes
(
self
)
->
None
:
def
_remove_measure_boxes
(
self
)
->
None
:
for
item
in
self
.
measuringBoxes
:
for
item
in
self
.
measuringBoxes
:
self
.
scene
().
removeItem
(
item
)
self
.
scene
().
removeItem
(
item
)
self
.
measuringBoxes
=
[]
self
.
measuringBoxes
=
[]
def
load_and_update_from_dataset
(
self
,
fname
:
str
)
->
None
:
self
.
dataset
=
dataset
.
loadData
(
fname
)
offset
,
diameter
,
widthHeight
=
helpers
.
get_filterDimensions_from_dataset
(
self
.
dataset
)
offsetx
=
helpers
.
convert_length_to_pixels
(
self
.
dataset
,
offset
[
0
])
offsety
=
helpers
.
convert_length_to_pixels
(
self
.
dataset
,
offset
[
1
])
diameter
=
helpers
.
convert_length_to_pixels
(
self
.
dataset
,
diameter
)
width
=
helpers
.
convert_length_to_pixels
(
self
.
dataset
,
widthHeight
[
0
])
height
=
helpers
.
convert_length_to_pixels
(
self
.
dataset
,
widthHeight
[
1
])
self
.
filter
.
update_filterSize
(
width
,
height
,
diameter
,
(
offsetx
,
offsety
))
self
.
_update_particle_contours
()
self
.
_fit_to_window
()
def
_update_particle_contours
(
self
)
->
None
:
self
.
_remove_particle_contours
()
if
self
.
dataset
is
not
None
:
for
particle
in
self
.
dataset
.
particleContainer
.
particles
:
newContour
:
ParticleContour
=
ParticleContour
(
particle
.
contour
)
self
.
scene
().
addItem
(
newContour
)
self
.
contourItems
.
append
(
newContour
)
def
_remove_particle_contours
(
self
)
->
None
:
for
cntItem
in
self
.
contourItems
:
self
.
scene
().
removeItem
(
cntItem
)
self
.
contourItems
=
[]
def
_update_measured_contours
(
self
)
->
None
:
# offset = self.filter.circleOffset
# offset = (-offset[0], -offset[1])
offset
=
(
0
,
0
)
for
contourItem
in
self
.
contourItems
:
contourItem
.
isMeasured
=
False
for
measBox
in
self
.
measuringBoxes
:
topLeftXY
=
(
measBox
.
posX
,
measBox
.
posY
)
boxWidthHeight
=
(
measBox
.
width
,
measBox
.
height
)
if
helpers
.
box_overlaps_contour
(
topLeftXY
,
boxWidthHeight
,
contourItem
.
polygon
,
offset
=
offset
):
contourItem
.
isMeasured
=
True
contourItem
.
update
()
break
def
wheelEvent
(
self
,
event
:
QtGui
.
QWheelEvent
)
->
None
:
factor
:
float
=
1.01
**
(
event
.
angleDelta
().
y
()
/
8
)
newScale
:
float
=
self
.
filter
.
scale
()
*
factor
self
.
scale
(
newScale
,
newScale
)
def
mousePressEvent
(
self
,
event
):
if
event
.
button
()
==
QtCore
.
Qt
.
MiddleButton
:
self
.
drag
=
event
.
pos
()
def
mouseMoveEvent
(
self
,
event
):
if
self
.
drag
is
not
None
:
p0
=
event
.
pos
()
move
=
self
.
drag
-
p0
self
.
horizontalScrollBar
().
setValue
(
move
.
x
()
+
self
.
horizontalScrollBar
().
value
())
self
.
verticalScrollBar
().
setValue
(
move
.
y
()
+
self
.
verticalScrollBar
().
value
())
self
.
drag
=
p0
def
mouseReleaseEvent
(
self
,
event
:
QtGui
.
QMouseEvent
)
->
None
:
self
.
drag
=
None
def
_fit_to_window
(
self
)
->
None
:
brect
=
self
.
scene
().
itemsBoundingRect
()
self
.
fitInView
(
0
,
0
,
brect
.
width
(),
brect
.
height
(),
QtCore
.
Qt
.
KeepAspectRatio
)
class
FilterGraphItem
(
QtWidgets
.
QGraphicsItem
):
class
FilterGraphItem
(
QtWidgets
.
QGraphicsItem
):
"""
"""
The Graphical Representation of the actual filter
The Graphical Representation of the actual filter
"""
"""
def
__init__
(
self
,
filterWidth
:
float
=
500
,
filterHeight
:
float
=
500
):
def
__init__
(
self
,
filterWidth
:
float
=
500
,
filterHeight
:
float
=
500
,
diameter
:
float
=
500
):
super
(
FilterGraphItem
,
self
).
__init__
()
super
(
FilterGraphItem
,
self
).
__init__
()
self
.
width
=
filterWidth
self
.
width
:
float
=
filterWidth
self
.
height
=
filterHeight
self
.
height
:
float
=
filterHeight
self
.
diameter
:
float
=
diameter
self
.
circleOffset
:
tuple
=
(
0
,
0
)
self
.
setPos
(
0
,
0
)
self
.
setPos
(
0
,
0
)
self
.
rect
=
QtCore
.
QRectF
(
0
,
0
,
self
.
width
,
self
.
height
)
self
.
rect
=
QtCore
.
QRectF
(
0
,
0
,
self
.
width
,
self
.
height
)
self
.
circleRect
=
QtCore
.
QRectF
(
self
.
circleOffset
[
0
],
self
.
circleOffset
[
1
],
self
.
diameter
,
self
.
diameter
)
def
boundingRect
(
self
)
->
QtCore
.
QRectF
:
def
boundingRect
(
self
)
->
QtCore
.
QRectF
:
return
self
.
rect
return
self
.
rect
def
update_filterSize
(
self
,
width
:
float
,
height
:
float
,
diameter
:
float
,
offset
:
tuple
)
->
None
:
self
.
width
=
width
self
.
height
=
height
self
.
rect
=
QtCore
.
QRectF
(
0
,
0
,
self
.
width
,
self
.
height
)
self
.
diameter
=
diameter
self
.
circleOffset
=
offset
self
.
circleRect
=
QtCore
.
QRectF
(
self
.
circleOffset
[
0
],
self
.
circleOffset
[
1
],
self
.
diameter
,
self
.
diameter
)
def
paint
(
self
,
painter
:
QtGui
.
QPainter
,
option
,
widget
)
->
None
:
def
paint
(
self
,
painter
:
QtGui
.
QPainter
,
option
,
widget
)
->
None
:
painter
.
setPen
(
QtCore
.
Qt
.
black
)
painter
.
setPen
(
QtCore
.
Qt
.
black
)
painter
.
setBrush
(
QtCore
.
Qt
.
white
)
painter
.
setBrush
(
QtCore
.
Qt
.
white
)
...
@@ -52,15 +146,16 @@ class FilterGraphItem(QtWidgets.QGraphicsItem):
...
@@ -52,15 +146,16 @@ class FilterGraphItem(QtWidgets.QGraphicsItem):
painter
.
setPen
(
QtCore
.
Qt
.
darkGray
)
painter
.
setPen
(
QtCore
.
Qt
.
darkGray
)
painter
.
setBrush
(
QtCore
.
Qt
.
lightGray
)
painter
.
setBrush
(
QtCore
.
Qt
.
lightGray
)
painter
.
drawEllipse
(
self
.
r
ect
)
painter
.
drawEllipse
(
self
.
circleR
ect
)
class
MeasureBoxGraphItem
(
QtWidgets
.
QGraphicsItem
):
class
MeasureBoxGraphItem
(
QtWidgets
.
QGraphicsItem
):
"""
"""
Displays a box in which particles will be measured
Displays a box in which particles will be measured
"""
"""
def
__init__
(
self
,
posX
:
float
=
50
,
posY
:
float
=
50
,
width
:
float
=
50
,
height
:
float
=
50
)
->
None
:
def
__init__
(
self
,
posX
:
float
=
50
,
posY
:
float
=
50
,
width
:
float
=
50
,
height
:
float
=
50
)
->
None
:
super
(
MeasureBoxGraphItem
,
self
).
__init__
()
super
(
MeasureBoxGraphItem
,
self
).
__init__
()
self
.
setZValue
(
5
)
self
.
posX
:
float
=
posX
self
.
posX
:
float
=
posX
self
.
posY
:
float
=
posY
self
.
posY
:
float
=
posY
self
.
height
:
float
=
height
self
.
height
:
float
=
height
...
@@ -74,6 +169,49 @@ class MeasureBoxGraphItem(QtWidgets.QGraphicsItem):
...
@@ -74,6 +169,49 @@ class MeasureBoxGraphItem(QtWidgets.QGraphicsItem):
return
self
.
rect
return
self
.
rect
def
paint
(
self
,
painter
,
option
,
widget
)
->
None
:
def
paint
(
self
,
painter
,
option
,
widget
)
->
None
:
painter
.
setBrush
(
Qt
Core
.
Qt
.
green
)
painter
.
setBrush
(
Qt
Gui
.
QColor
(
0
,
255
,
0
,
180
)
)
painter
.
setPen
(
QtCore
.
Qt
.
darkGreen
)
painter
.
setPen
(
QtCore
.
Qt
.
darkGreen
)
painter
.
drawRects
(
self
.
rect
)
painter
.
drawRects
(
self
.
rect
)
class
ParticleContour
(
QtWidgets
.
QGraphicsItem
):
def
__init__
(
self
,
contourData
,
pos
=
(
0
,
0
))
->
None
:
super
(
ParticleContour
,
self
).
__init__
()
self
.
setZValue
(
1
)
self
.
setPos
(
pos
[
0
],
pos
[
1
])
self
.
brect
:
QtCore
.
QRectF
=
QtCore
.
QRectF
(
0
,
0
,
1
,
1
)
self
.
isMeasured
:
bool
=
False
# Wether the particle overlaps with a measuring box or nt
self
.
contourData
=
contourData
self
.
polygon
=
None
self
.
getBrectAndPolygon
()
def
getBrectAndPolygon
(
self
)
->
None
:
"""
Calculates the bounding rect (needed for drawing the QGraphicsView) and converts the contourdata to a polygon.
:return:
"""
self
.
polygon
=
QtGui
.
QPolygonF
()
x0
=
self
.
contourData
[:,
0
,
0
].
min
()
x1
=
self
.
contourData
[:,
0
,
0
].
max
()
y0
=
self
.
contourData
[:,
0
,
1
].
min
()
y1
=
self
.
contourData
[:,
0
,
1
].
max
()
for
point
in
self
.
contourData
:
self
.
polygon
.
append
(
QtCore
.
QPointF
(
point
[
0
,
0
],
point
[
0
,
1
]))
self
.
brect
.
setCoords
(
x0
,
y0
,
x1
,
y1
)
def
boundingRect
(
self
)
->
QtCore
.
QRectF
:
return
self
.
brect
def
paint
(
self
,
painter
,
option
,
widget
)
->
None
:
if
self
.
polygon
is
not
None
:
if
self
.
isMeasured
:
painter
.
setPen
(
QtCore
.
Qt
.
darkRed
)
painter
.
setBrush
(
QtCore
.
Qt
.
red
)
else
:
painter
.
setPen
(
QtCore
.
Qt
.
darkCyan
)
painter
.
setBrush
(
QtCore
.
Qt
.
cyan
)
painter
.
drawPolygon
(
self
.
polygon
)
gui/mainView.py
View file @
064d26eb
...
@@ -17,10 +17,14 @@ class MainView(QtWidgets.QWidget):
...
@@ -17,10 +17,14 @@ class MainView(QtWidgets.QWidget):
self
.
activeMode
:
MeasureMode
=
None
self
.
activeMode
:
MeasureMode
=
None
self
.
activeModeControl
:
QtWidgets
.
QGroupBox
=
QtWidgets
.
QGroupBox
()
self
.
activeModeControl
:
QtWidgets
.
QGroupBox
=
QtWidgets
.
QGroupBox
()
loadDsetBtn
=
QtWidgets
.
QPushButton
(
'Load Dataset'
)
loadDsetBtn
.
released
.
connect
(
self
.
_load_dataset
)
self
.
controlGroup
=
QtWidgets
.
QGroupBox
()
self
.
controlGroup
=
QtWidgets
.
QGroupBox
()
self
.
controlGroupLayout
=
QtWidgets
.
QHBoxLayout
()
self
.
controlGroupLayout
=
QtWidgets
.
QHBoxLayout
()
self
.
controlGroup
.
setLayout
(
self
.
controlGroupLayout
)
self
.
controlGroup
.
setLayout
(
self
.
controlGroupLayout
)
self
.
controlGroupLayout
.
addWidget
(
loadDsetBtn
)
self
.
controlGroupLayout
.
addWidget
(
QtWidgets
.
QLabel
(
'Select Subsampling Mode:'
))
self
.
controlGroupLayout
.
addWidget
(
QtWidgets
.
QLabel
(
'Select Subsampling Mode:'
))
self
.
controlGroupLayout
.
addWidget
(
self
.
modeSelector
)
self
.
controlGroupLayout
.
addWidget
(
self
.
modeSelector
)
self
.
controlGroupLayout
.
addWidget
(
self
.
activeModeControl
)
self
.
controlGroupLayout
.
addWidget
(
self
.
activeModeControl
)
...
@@ -57,6 +61,12 @@ class MainView(QtWidgets.QWidget):
...
@@ -57,6 +61,12 @@ class MainView(QtWidgets.QWidget):
self
.
activeMode
.
update_measure_viewItems
()
self
.
activeMode
.
update_measure_viewItems
()
def
_load_dataset
(
self
)
->
None
:
fname
=
QtWidgets
.
QFileDialog
.
getOpenFileName
(
self
,
'Select .pkl file'
,
filter
=
'pkl file (*.pkl)'
)
if
fname
[
0
]
!=
''
:
self
.
filterView
.
load_and_update_from_dataset
(
fname
[
0
])
self
.
activeMode
.
update_measure_viewItems
()
if
__name__
==
'__main__'
:
if
__name__
==
'__main__'
:
import
sys
import
sys
...
...
gui/measureModes.py
View file @
064d26eb
...
@@ -24,8 +24,7 @@ class CrossBoxMode(MeasureMode):
...
@@ -24,8 +24,7 @@ class CrossBoxMode(MeasureMode):
self
.
update_measure_viewItems
()
self
.
update_measure_viewItems
()
def
update_measure_viewItems
(
self
)
->
None
:
def
update_measure_viewItems
(
self
)
->
None
:
assert
self
.
filterView
.
filter
.
height
==
self
.
filterView
.
filter
.
width
self
.
crossBoxGenerator
.
filterDiameter
=
self
.
filterView
.
filter
.
diameter
self
.
crossBoxGenerator
.
filterSize
=
self
.
filterView
.
filter
.
height
self
.
crossBoxGenerator
.
numBoxesAcross
=
int
(
self
.
uiControls
.
numBoxesSelector
.
currentText
())
self
.
crossBoxGenerator
.
numBoxesAcross
=
int
(
self
.
uiControls
.
numBoxesSelector
.
currentText
())
desiredCoverage
:
int
=
self
.
uiControls
.
coverageSpinbox
.
value
()
desiredCoverage
:
int
=
self
.
uiControls
.
coverageSpinbox
.
value
()
...
@@ -36,14 +35,9 @@ class CrossBoxMode(MeasureMode):
...
@@ -36,14 +35,9 @@ class CrossBoxMode(MeasureMode):
self
.
crossBoxGenerator
.
fraction
=
desiredCoverage
/
100
self
.
crossBoxGenerator
.
fraction
=
desiredCoverage
/
100
viewItems
=
[]
topLefts
:
list
=
self
.
crossBoxGenerator
.
get_topLeft_of_boxes
()
topLefts
:
list
=
self
.
crossBoxGenerator
.
get_topLeft_of_boxes
()
boxSize
=
self
.
crossBoxGenerator
.
boxSize
boxSize
=
self
.
crossBoxGenerator
.
boxSize
for
(
x
,
y
)
in
topLefts
:
self
.
filterView
.
update_measure_boxes
(
topLefts
,
boxSize
)
newBox
:
MeasureBoxGraphItem
=
MeasureBoxGraphItem
(
x
,
y
,
boxSize
,
boxSize
)
viewItems
.
append
(
newBox
)
self
.
filterView
.
update_measure_boxes
(
viewItems
)
class
CrossBoxesControls
(
QtWidgets
.
QGroupBox
):
class
CrossBoxesControls
(
QtWidgets
.
QGroupBox
):
...
@@ -94,20 +88,19 @@ class SpiralBoxMode(MeasureMode):
...
@@ -94,20 +88,19 @@ class SpiralBoxMode(MeasureMode):
self
.
update_measure_viewItems
()
self
.
update_measure_viewItems
()
def
update_measure_viewItems
(
self
)
->
None
:
def
update_measure_viewItems
(
self
)
->
None
:
self
.
spiralBoxGenerator
.
filterHeight
=
self
.
filterView
.
filter
.
height
self
.
spiralBoxGenerator
.
filterDiameter
=
self
.
filterView
.
filter
.
diameter
self
.
spiralBoxGenerator
.
filterWidth
=
self
.
filterView
.
filter
.
width
self
.
spiralBoxGenerator
.
boxSize
=
self
.
uiControls
.
boxSizeSpinbox
.
value
()
self
.
spiralBoxGenerator
.
boxSize
=
self
.
uiControls
.
boxSizeSpinbox
.
value
()
# minBoxSize: float = self.spiralBoxGenerator.filterDiameter*0.1
# if self.spiralBoxGenerator.boxSize < minBoxSize:
# self.spiralBoxGenerator.boxSize = minBoxSize
# self.uiControls.boxSizeSpinbox.setValue(int(round(minBoxSize)))
self
.
spiralBoxGenerator
.
numBoxes
=
self
.
uiControls
.
numBoxesSpinbox
.
value
()
self
.
spiralBoxGenerator
.
numBoxes
=
self
.
uiControls
.
numBoxesSpinbox
.
value
()
viewItems
=
[]
topLefts
:
list
=
self
.
spiralBoxGenerator
.
get_topLeft_of_boxes
()
topLefts
:
list
=
self
.
spiralBoxGenerator
.
get_topLeft_of_boxes
()
boxSize
=
self
.
spiralBoxGenerator
.
boxSize
boxSize
=
self
.
spiralBoxGenerator
.
boxSize
for
(
x
,
y
)
in
topLefts
:
self
.
filterView
.
update_measure_boxes
(
topLefts
,
boxSize
)
newBox
:
MeasureBoxGraphItem
=
MeasureBoxGraphItem
(
x
,
y
,
boxSize
,
boxSize
)
viewItems
.
append
(
newBox
)
self
.
filterView
.
update_measure_boxes
(
viewItems
)
class
SpiralBoxControls
(
QtWidgets
.
QGroupBox
):
class
SpiralBoxControls
(
QtWidgets
.
QGroupBox
):
...
@@ -125,7 +118,7 @@ class SpiralBoxControls(QtWidgets.QGroupBox):
...
@@ -125,7 +118,7 @@ class SpiralBoxControls(QtWidgets.QGroupBox):
layout
.
addWidget
(
QtWidgets
.
QLabel
(
'Box Size:'
))
layout
.
addWidget
(
QtWidgets
.
QLabel
(
'Box Size:'
))
self
.
boxSizeSpinbox
=
QtWidgets
.
QSpinBox
()
self
.
boxSizeSpinbox
=
QtWidgets
.
QSpinBox
()
self
.
boxSizeSpinbox
.
setValue
(
50
)
self
.
boxSizeSpinbox
.
setValue
(
50
)
self
.
boxSizeSpinbox
.
setMaximum
(
1000
)
self
.
boxSizeSpinbox
.
setMaximum
(
1000
0
)
self
.
boxSizeSpinbox
.
valueChanged
.
connect
(
self
.
_config_changed
)
self
.
boxSizeSpinbox
.
valueChanged
.
connect
(
self
.
_config_changed
)
layout
.
addWidget
(
self
.
boxSizeSpinbox
)
layout
.
addWidget
(
self
.
boxSizeSpinbox
)
...
...
helpers.py
View file @
064d26eb
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Tue Jan 28 19:32:50 2020
@author: luna
"""
from
PyQt5
import
QtCore
,
QtGui
from
PyQt5
import
QtCore
,
QtGui
import
numpy
as
np
import
numpy
as
np
import
sys
sys
.
path
.
append
(
"C://Users//xbrjos//Desktop//Python"
)
from
gepard
import
dataset
class
ParticleBinSorter
(
object
):
class
ParticleBinSorter
(
object
):
...
@@ -36,15 +32,108 @@ class ParticleBinSorter(object):
...
@@ -36,15 +32,108 @@ class ParticleBinSorter(object):
return
binIndex
return
binIndex