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
893884dd
Commit
893884dd
authored
Aug 27, 2020
by
Josef Brandt
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'ThermoFTIR' into MergingIntoTiling2Develop
parents
2e71208e
b2e6bcbc
Changes
35
Hide whitespace changes
Inline
Side-by-side
Showing
35 changed files
with
1878 additions
and
132 deletions
+1878
-132
.gitignore
.gitignore
+4
-0
__main__.py
__main__.py
+1
-6
analysis/advancedWITec.py
analysis/advancedWITec.py
+0
-0
analysis/ftirAperture.py
analysis/ftirAperture.py
+142
-0
analysis/particleAndMeasurement.py
analysis/particleAndMeasurement.py
+3
-1
analysis/particleCharacterization.py
analysis/particleCharacterization.py
+72
-12
analysis/particleContainer.py
analysis/particleContainer.py
+21
-6
cythonModules/getMaxRect.pyx
cythonModules/getMaxRect.pyx
+73
-0
cythonModules/setup_getMaxRect.py
cythonModules/setup_getMaxRect.py
+48
-0
cythonModules/setuptsp.py
cythonModules/setuptsp.py
+0
-0
cythonModules/tsp.pyx
cythonModules/tsp.pyx
+0
-0
dataset.py
dataset.py
+5
-5
detectionview.py
detectionview.py
+18
-4
gepard_ConfigTemplate.cfg
gepard_ConfigTemplate.cfg
+23
-0
legacyConvert.py
legacyConvert.py
+1
-1
opticalscan.py
opticalscan.py
+4
-3
ramancom/WITecCOM.py
ramancom/WITecCOM.py
+15
-14
ramancom/comErrorWrapper.py
ramancom/comErrorWrapper.py
+80
-0
ramancom/configRaman.py
ramancom/configRaman.py
+1
-0
ramancom/ramanbase.py
ramancom/ramanbase.py
+16
-6
ramancom/ramancontrol.py
ramancom/ramancontrol.py
+5
-0
ramancom/simulated/imageGenerator.py
ramancom/simulated/imageGenerator.py
+0
-4
ramancom/simulated/simulatedStage.py
ramancom/simulated/simulatedStage.py
+1
-1
ramancom/specHandler.py
ramancom/specHandler.py
+311
-0
ramancom/thermoFTIR/ddeclient.py
ramancom/thermoFTIR/ddeclient.py
+452
-0
ramancom/thermoFTIR/processScreenshot.py
ramancom/thermoFTIR/processScreenshot.py
+211
-0
ramancom/thermoFTIRtesting.py
ramancom/thermoFTIRtesting.py
+73
-0
ramanscanui.py
ramanscanui.py
+95
-36
requirements.txt
requirements.txt
+12
-0
sampleview.py
sampleview.py
+19
-21
segmentation.py
segmentation.py
+2
-1
uielements.py
uielements.py
+3
-2
unittests/test_FTIRCom.py
unittests/test_FTIRCom.py
+47
-0
unittests/test_specHandler.py
unittests/test_specHandler.py
+75
-0
viewitems.py
viewitems.py
+45
-9
No files found.
.gitignore
View file @
893884dd
...
...
@@ -24,3 +24,7 @@ ramancom/renishawtesting.py
*.lib
*.obj
*.pyc
*.jdx
__main__.py
View file @
893884dd
...
...
@@ -204,10 +204,6 @@ class GEPARDMainWindow(QtWidgets.QMainWindow):
if
self
.
view
.
simulatedRaman
:
self
.
configRamanCtrlAct
.
setDisabled
(
True
)
self
.
recalculateCoordAct
=
QtWidgets
.
QAction
(
"&Recalculate Coordinate System"
)
self
.
recalculateCoordAct
.
setDisabled
(
True
)
self
.
recalculateCoordAct
.
triggered
.
connect
(
self
.
view
.
recalculateCoordinateSystem
)
self
.
noOverlayAct
=
QtWidgets
.
QAction
(
"&No Overlay"
,
self
)
self
.
noOverlayAct
.
setShortcut
(
"1"
)
self
.
selOverlayAct
=
QtWidgets
.
QAction
(
"&Selected Overlay"
,
self
)
...
...
@@ -296,7 +292,6 @@ class GEPARDMainWindow(QtWidgets.QMainWindow):
self
.
toolsMenu
=
QtWidgets
.
QMenu
(
"&Tools"
)
self
.
toolsMenu
.
addAction
(
self
.
snapshotAct
)
self
.
toolsMenu
.
addAction
(
self
.
configRamanCtrlAct
)
self
.
toolsMenu
.
addAction
(
self
.
recalculateCoordAct
)
self
.
dispMenu
=
QtWidgets
.
QMenu
(
"&Display"
,
self
)
self
.
overlayActGroup
=
QtWidgets
.
QActionGroup
(
self
.
dispMenu
)
...
...
@@ -389,7 +384,7 @@ if __name__ == '__main__':
logging
.
handlers
.
RotatingFileHandler
(
logname
,
maxBytes
=
5
*
(
1
<<
20
),
backupCount
=
10
)
)
logger
.
setLevel
(
logging
.
DEBUG
)
setDefaultLoggingConfig
(
logger
)
logger
.
info
(
"starting GEPARD at: "
+
strftime
(
"%d %b %Y %H:%M:%S"
,
localtime
()))
...
...
ramancom
/advancedWITec.py
→
analysis
/advancedWITec.py
View file @
893884dd
File moved
analysis/ftirAperture.py
0 → 100644
View file @
893884dd
# -*- 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/>.
"""
import
numpy
as
np
from
scipy
import
optimize
import
cv2
from
..cythonModules.getMaxRect
import
findMaxRect
####################################################
'''Code taken from https://github.com/pogam/ExtractRect/blob/master/extractRect.py and modified for our use'''
####################################################
def
residual
(
angle
,
img
):
img_rot
,
rotationMatrix
=
rotateImageAroundAngle
(
img
,
angle
)
point1
,
point2
,
width
,
height
,
max_area
=
findMaxRect
(
img_rot
)
return
1
/
max_area
def
getFinalRectangle
(
angle
,
img
,
shiftScaleParam
):
ny
=
img
.
shape
[
1
]
img_rot
,
rotationMatrix
=
rotateImageAroundAngle
(
img
,
angle
)
point1
,
point2
,
width
,
height
,
max_area
=
findMaxRect
(
img_rot
)
width
*=
shiftScaleParam
.
scale_factor
height
*=
shiftScaleParam
.
scale_factor
#invert rectangle
M_invert
=
cv2
.
invertAffineTransform
(
rotationMatrix
)
rect_coord
=
[
point1
,
[
point1
[
0
],
point2
[
1
]]
,
point2
,
[
point2
[
0
],
point1
[
1
]]
]
rect_coord_ori
=
[]
for
coord
in
rect_coord
:
rect_coord_ori
.
append
(
np
.
dot
(
M_invert
,[
coord
[
0
],(
ny
-
1
)
-
coord
[
1
],
1
]))
#transform to numpy coord of input image
coord_out
=
[]
for
coord
in
rect_coord_ori
:
coord_out
.
append
([
shiftScaleParam
.
scale_factor
*
round
(
coord
[
0
],
0
)
-
shiftScaleParam
.
shift_x
,
\
shiftScaleParam
.
scale_factor
*
round
((
ny
-
1
)
-
coord
[
1
],
0
)
-
shiftScaleParam
.
shift_y
])
#transpose back the original coords:
coord_out
=
transposeRectCoords
(
coord_out
)
return
coord_out
,
round
(
width
),
round
(
height
)
def
transposeRectCoords
(
rectCoords
):
#mirror x and y:
newCoords
=
[]
for
i
in
range
(
len
(
rectCoords
)):
newCoords
.
append
([
rectCoords
[
i
][
1
],
rectCoords
[
i
][
0
]])
return
newCoords
def
addBorderToMakeImageSquare
(
img
):
nx
,
ny
=
img
.
shape
if
nx
!=
ny
:
n
=
max
([
nx
,
ny
])
img_square
=
np
.
ones
([
n
,
n
])
xshift
=
(
n
-
nx
)
/
2
yshift
=
(
n
-
ny
)
/
2
if
yshift
==
0
:
img_square
[
int
(
xshift
):
int
(
xshift
+
nx
),:]
=
img
else
:
img_square
[:,
int
(
yshift
):
int
(
yshift
+
ny
)]
=
img
else
:
xshift
=
0
yshift
=
0
img_square
=
img
return
img_square
,
xshift
,
yshift
def
limitImageSize
(
img
,
limitSize
):
if
img
.
shape
[
0
]
>
limitSize
:
img_small
=
cv2
.
resize
(
img
,(
limitSize
,
limitSize
),
interpolation
=
0
)
scale_factor
=
1.
*
img
.
shape
[
0
]
/
img_small
.
shape
[
0
]
else
:
img_small
=
img
scale_factor
=
1
return
img_small
,
scale_factor
def
makeImageOddSized
(
img
):
# set the input data with an odd number of point in each dimension to make rotation easier
nx
,
ny
=
img
.
shape
nx_extra
=
-
nx
ny_extra
=
-
ny
if
nx
%
2
==
0
:
nx
+=
1
nx_extra
=
1
if
ny
%
2
==
0
:
ny
+=
1
ny_extra
=
1
img_odd
=
np
.
ones
([
img
.
shape
[
0
]
+
max
([
0
,
nx_extra
]),
img
.
shape
[
1
]
+
max
([
0
,
ny_extra
])],
dtype
=
np
.
uint8
)
img_odd
[:
-
nx_extra
,
:
-
ny_extra
]
=
img
return
img_odd
def
rotateImageAroundAngle
(
img
,
angle
):
nx
,
ny
=
img
.
shape
rotationMatrix
=
cv2
.
getRotationMatrix2D
(((
nx
-
1
)
/
2
,(
ny
-
1
)
/
2
),
angle
,
1
)
img_rot
=
np
.
array
(
cv2
.
warpAffine
(
img
,
rotationMatrix
,
img
.
shape
,
flags
=
cv2
.
INTER_NEAREST
,
borderValue
=
1
))
img_rot
=
img_rot
.
astype
(
np
.
uint8
)
return
img_rot
,
rotationMatrix
def
findRotatedMaximalRectangle
(
img
,
nbre_angle
=
4
,
limit_image_size
=
300
):
img_square
,
shift_x
,
shift_y
=
addBorderToMakeImageSquare
(
img
)
img_small
,
scale_factor
=
limitImageSize
(
img_square
,
limit_image_size
)
img_odd
=
makeImageOddSized
(
img_small
)
nx
,
ny
=
nx_odd
,
ny_odd
=
img_odd
.
shape
shiftScaleParam
=
ShiftAndScaleParam
(
shift_x
,
shift_y
,
scale_factor
)
# angle_range = ([(90.,180.),])
angle_range
=
([(
0.
,
90.
),
])
coeff1
=
optimize
.
brute
(
residual
,
angle_range
,
args
=
(
img_odd
,),
Ns
=
nbre_angle
,
finish
=
None
)
popt
=
optimize
.
fmin
(
residual
,
coeff1
,
args
=
(
img_odd
,),
xtol
=
5
,
ftol
=
1.e-5
,
disp
=
False
)
opt_angle
=
popt
[
0
]
rectangleCoords
,
width
,
height
=
getFinalRectangle
(
opt_angle
,
img_odd
,
shiftScaleParam
)
return
rectangleCoords
,
opt_angle
,
width
,
height
class
ShiftAndScaleParam
(
object
):
def
__init__
(
self
,
shift_x
=
0
,
shift_y
=
0
,
scale_factor
=
1
):
self
.
shift_x
=
shift_x
self
.
shift_y
=
shift_y
self
.
scale_factor
=
scale_factor
\ No newline at end of file
analysis/particleAndMeasurement.py
View file @
893884dd
...
...
@@ -29,6 +29,7 @@ class Particle(object):
self
.
height
=
None
self
.
area
=
None
self
.
contour
=
None
self
.
aperture
=
None
self
.
measurements
=
[]
self
.
color
=
None
self
.
shape
=
None
...
...
@@ -127,7 +128,8 @@ class Measurement(object):
self
.
assignment_orig
=
'Not Evaluated'
self
.
assignment_afterHQI
=
None
self
.
hqi
=
0
self
.
measurementResults
:
dict
=
{}
self
.
assignedParticle
=
None
def
setAssignment
(
self
,
assignment
):
...
...
analysis/particleCharacterization.py
View file @
893884dd
...
...
@@ -26,17 +26,34 @@ from copy import deepcopy
from
.particleClassification.colorClassification
import
ColorClassifier
from
.particleClassification.shapeClassification
import
ShapeClassifier
from
.ftirAperture
import
findRotatedMaximalRectangle
from
..segmentation
import
closeHolesOfSubImage
from
..errors
import
InvalidParticleError
from
..helperfunctions
import
cv2imread_fix
class
FTIRAperture
(
object
):
"""
Configuration for an FTIR aperture. CenterCoords, width and height in Pixels
"""
centerX
:
float
=
None
centerY
:
float
=
None
centerZ
:
float
=
None
width
:
float
=
None
height
:
float
=
None
angle
:
float
=
None
rectCoords
:
list
=
None
class
ParticleStats
(
object
):
longSize
=
None
shortSize
=
None
height
=
None
area
=
None
shape
=
None
color
=
None
longSize
:
float
=
None
shortSize
:
float
=
None
height
:
float
=
None
area
:
float
=
None
shape
:
str
=
None
color
:
str
=
None
aperture
:
FTIRAperture
=
None
def
particleIsValid
(
particle
):
if
particle
.
longSize
==
0
or
particle
.
shortSize
==
0
:
...
...
@@ -45,7 +62,8 @@ def particleIsValid(particle):
if
cv2
.
contourArea
(
particle
.
contour
)
==
0
:
return
False
return
True
def
updateStatsOfParticlesIfNotManuallyEdited
(
particleContainer
):
dataset
=
particleContainer
.
datasetParent
fullimage
=
loadFullimageFromDataset
(
dataset
)
...
...
@@ -59,6 +77,23 @@ def updateStatsOfParticlesIfNotManuallyEdited(particleContainer):
newStats
=
getParticleStatsWithPixelScale
(
particle
.
contour
,
dataset
,
fullimage
,
zimg
)
particle
.
__dict__
.
update
(
newStats
.
__dict__
)
def
getFTIRAperture
(
partImg
:
np
.
ndarray
)
->
FTIRAperture
:
rectPoints
,
angle
,
width
,
heigth
=
findRotatedMaximalRectangle
(
partImg
,
nbre_angle
=
4
,
limit_image_size
=
300
)
xvalues
:
list
=
[
i
[
0
]
for
i
in
rectPoints
]
yvalues
:
list
=
[
i
[
1
]
for
i
in
rectPoints
]
aperture
=
FTIRAperture
()
aperture
.
height
=
heigth
aperture
.
width
=
width
aperture
.
angle
=
angle
aperture
.
centerX
=
int
(
round
(
min
(
xvalues
)
+
(
max
(
xvalues
)
-
min
(
xvalues
))
/
2
))
aperture
.
centerY
=
int
(
round
(
min
(
yvalues
)
+
(
max
(
yvalues
)
-
min
(
yvalues
))
/
2
))
aperture
.
rectCoords
=
rectPoints
return
aperture
def
getParticleStatsWithPixelScale
(
contour
,
dataset
,
fullimage
=
None
,
zimg
=
None
):
if
fullimage
is
None
:
fullimage
=
loadFullimageFromDataset
(
dataset
)
...
...
@@ -84,17 +119,31 @@ def getParticleStatsWithPixelScale(contour, dataset, fullimage=None, zimg=None):
newStats
.
longSize
*=
pixelscale
newStats
.
shortSize
*=
pixelscale
partImg
=
getParticleImageFromFullimage
(
cnt
,
fullimage
)
partImg
,
extrema
=
getParticleImageFromFullimage
(
cnt
,
fullimage
)
newStats
.
color
=
getParticleColor
(
partImg
)
padding
:
int
=
int
(
2
)
imgforAperture
=
np
.
zeros
((
partImg
.
shape
[
0
]
+
2
*
padding
,
partImg
.
shape
[
1
]
+
2
*
padding
))
imgforAperture
[
padding
:
partImg
.
shape
[
0
]
+
padding
,
padding
:
partImg
.
shape
[
1
]
+
padding
]
=
np
.
mean
(
partImg
,
axis
=
2
)
imgforAperture
[
imgforAperture
>
0
]
=
1
# convert to binary image
imgforAperture
=
np
.
uint8
(
1
-
imgforAperture
)
# background has to be 1, particle has to be 0
aperture
:
FTIRAperture
=
getFTIRAperture
(
imgforAperture
)
aperture
.
centerX
=
aperture
.
centerX
+
extrema
[
0
]
-
padding
aperture
.
centerY
=
aperture
.
centerY
+
extrema
[
2
]
-
padding
aperture
.
centerZ
=
newStats
.
height
newStats
.
aperture
=
aperture
return
newStats
def
getFibreDimension
(
contour
):
longSize
=
cv2
.
arcLength
(
contour
,
True
)
/
2
img
=
contoursToImg
([
contour
])[
0
]
dist
=
cv2
.
distanceTransform
(
img
,
cv2
.
DIST_L2
,
3
)
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
)
...
...
@@ -103,14 +152,16 @@ def getParticleColor(imgRGB, colorClassifier=None):
color
=
colorClassifier
.
classifyColor
(
meanHSV
)
return
color
def
getParticleShape
(
contour
,
particleHeight
,
shapeClassifier
=
None
):
if
shapeClassifier
is
None
:
shapeClassifier
=
ShapeClassifier
()
shape
=
shapeClassifier
.
classifyShape
(
contour
,
particleHeight
)
return
shape
def
getParticleHeight
(
contour
,
fullZimg
,
dataset
):
zimg
=
getParticleImageFromFullimage
(
contour
,
fullZimg
)
zimg
,
_extrema
=
getParticleImageFromFullimage
(
contour
,
fullZimg
)
if
zimg
.
shape
[
0
]
==
0
or
zimg
.
shape
[
1
]
==
0
:
raise
InvalidParticleError
...
...
@@ -122,6 +173,7 @@ def getParticleHeight(contour, fullZimg, dataset):
height
=
avg_ZValue
/
255.
*
(
z1
-
z0
)
+
z0
return
height
def
getContourStats
(
cnt
):
##characterize particle
if
cnt
.
shape
[
0
]
>=
5
:
##at least 5 points required for ellipse fitting...
...
...
@@ -138,10 +190,12 @@ def getContourStats(cnt):
return
long
,
short
,
area
def
mergeContours
(
contours
):
img
,
xmin
,
ymin
,
padding
=
contoursToImg
(
contours
)
return
imgToCnt
(
img
,
xmin
,
ymin
,
padding
)
def
getParticleImageFromFullimage
(
contour
,
fullimage
):
contourCopy
=
deepcopy
(
contour
)
xmin
,
xmax
,
ymin
,
ymax
=
getContourExtrema
(
contourCopy
)
...
...
@@ -159,8 +213,9 @@ def getParticleImageFromFullimage(contour, fullimage):
img
[
mask
==
0
]
=
0
img
=
np
.
array
(
img
,
dtype
=
np
.
uint8
)
return
img
return
img
,
(
xmin
,
xmax
,
ymin
,
ymax
)
def
contoursToImg
(
contours
,
padding
=
0
):
contourCopy
=
deepcopy
(
contours
)
xmin
,
xmax
,
ymin
,
ymax
=
getContourExtrema
(
contourCopy
)
...
...
@@ -181,6 +236,7 @@ def contoursToImg(contours, padding=0):
img
=
np
.
uint8
(
cv2
.
morphologyEx
(
img
,
cv2
.
MORPH_CLOSE
,
np
.
ones
((
3
,
3
))))
return
img
,
xmin
,
ymin
,
padding
def
imgToCnt
(
img
,
xmin
,
ymin
,
padding
=
0
):
def
getContour
(
img
,
contourMode
):
if
cv2
.
__version__
>
'3.5'
:
...
...
@@ -214,6 +270,7 @@ def imgToCnt(img, xmin, ymin, padding=0):
return
contour
def
getContourExtrema
(
contours
):
try
:
cnt
=
np
.
vstack
(
tuple
(
contours
))
...
...
@@ -228,6 +285,7 @@ def getContourExtrema(contours):
return
xmin
,
xmax
,
ymin
,
ymax
def
getParticleCenterPoint
(
contour
):
img
,
xmin
,
ymin
,
padding
=
contoursToImg
(
contour
)
dist
=
cv2
.
distanceTransform
(
img
,
cv2
.
DIST_L2
,
3
)
...
...
@@ -238,8 +296,10 @@ def getParticleCenterPoint(contour):
y
+=
ymin
return
x
,
y
def
loadFullimageFromDataset
(
dataset
):
return
cv2imread_fix
(
dataset
.
getImageName
())
def
loadZValImageFromDataset
(
dataset
):
return
cv2imread_fix
(
dataset
.
getZvalImageName
(),
cv2
.
IMREAD_GRAYSCALE
)
\ No newline at end of file
analysis/particleContainer.py
View file @
893884dd
...
...
@@ -34,15 +34,15 @@ class ParticleContainer(object):
self
.
measurements
=
[]
self
.
inconsistentParticles
=
[]
def
addEmptyMeasurement
(
self
):
def
addEmptyMeasurement
(
self
)
->
int
:
newMeas
=
Measurement
()
self
.
measurements
.
append
(
newMeas
)
return
self
.
measurements
.
index
(
newMeas
)
def
clearParticles
(
self
):
def
clearParticles
(
self
)
->
None
:
self
.
particles
=
[]
def
clearMeasurements
(
self
):
def
clearMeasurements
(
self
)
->
None
:
self
.
measurements
=
[]
for
particle
in
self
.
particles
:
particle
.
measurements
=
[]
...
...
@@ -132,6 +132,13 @@ class ParticleContainer(object):
for
meas
in
self
.
measurements
:
scanIndex
=
meas
.
getScanIndex
()
meas
.
setAssignment
(
assignmentList
[
scanIndex
])
def
applyDatabaseResultsToParticleMeasurements
(
self
,
resultDictList
:
list
)
->
None
:
"""
The resultDictList has a dict for each measurement, containing multiple database results.
Key: HQI, Val: Resultname
"""
pass
def
applyHQIListToParticleMeasurements
(
self
,
hqiList
):
'''HQI-List is list of spectra hqis in order of spectra indices'''
...
...
@@ -185,12 +192,20 @@ class ParticleContainer(object):
particle
=
self
.
getParticleOfIndex
(
partIndex
)
return
particle
.
getParticleAssignment
()
def
getMeasurementPixelCoords
(
self
):
coords
=
[]
def
getMeasurementPixelCoords
(
self
)
->
list
:
coords
:
list
=
[]
for
meas
in
self
.
measurements
:
coords
.
append
([
meas
.
pixelcoord_x
,
meas
.
pixelcoord_y
])
return
coords
def
getApertureCenterCoords
(
self
)
->
list
:
coords
:
list
=
[]
for
particle
in
self
.
particles
:
assert
particle
.
aperture
is
not
None
,
'Aperture for particle was not set!'
coords
.
append
([
particle
.
aperture
.
centerX
,
particle
.
aperture
.
centerY
])
return
coords
def
getNumberOfParticlesOfAssignment
(
self
,
assignment
):
num
=
0
for
particle
in
self
.
particles
:
...
...
cythonModules/getMaxRect.pyx
0 → 100644
View file @
893884dd
#!/usr/bin/env python3
# -*- 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/>.
"""
import
numpy
as
np
cimport
numpy
as
np
cimport
cython
NP_INT32
=
np
.
int32
ctypedef
np
.
int32_t
INT32_t
@
cython
.
boundscheck
(
False
)
# assume: no index larger than N-1
@
cython
.
wraparound
(
False
)
# assume: no neg. index
def
findMaxRect
(
np
.
ndarray
[
np
.
uint8_t
,
ndim
=
2
]
img
):
'''http://stackoverflow.com/a/30418912/5008845'''
cdef
int
nrows
,
ncols
,
row
,
col
,
dh
,
height
,
width
,
minw
,
area
,
max_area
cdef
np
.
ndarray
[
INT32_t
,
ndim
=
2
]
w
,
h
cdef
np
.
ndarray
[
INT32_t
,
ndim
=
1
]
rectangle
rectangle
=
np
.
zeros
(
6
,
dtype
=
NP_INT32
)
nrows
,
ncols
=
img
.
shape
[
0
],
img
.
shape
[
1
]
w
=
np
.
zeros
((
nrows
,
ncols
),
dtype
=
NP_INT32
)
h
=
np
.
zeros
((
nrows
,
ncols
),
dtype
=
NP_INT32
)
max_area
=
0
for
row
in
range
(
nrows
):
for
col
in
range
(
ncols
):
if
img
[
row
,
col
]
==
1
:
continue
if
row
==
0
:
h
[
row
,
col
]
=
1
else
:
h
[
row
,
col
]
=
h
[
row
-
1
,
col
]
+
1
if
col
==
0
:
w
[
row
,
col
]
=
1
else
:
w
[
row
,
col
]
=
w
[
row
,
col
-
1
]
+
1
minw
=
w
[
row
,
col
]
for
dh
in
range
(
h
[
row
,
col
]):
minw
=
min
(
minw
,
w
[
row
-
dh
,
col
])
area
=
(
dh
+
1
)
*
minw
if
area
>
max_area
:
max_area
=
area
rectangle
[
0
],
rectangle
[
1
]
=
row
-
dh
,
col
-
minw
+
1
rectangle
[
2
],
rectangle
[
3
]
=
row
,
col
rectangle
[
4
],
rectangle
[
5
]
=
dh
+
1
,
minw
point1
=
rectangle
[
0
],
rectangle
[
1
]
point2
=
rectangle
[
2
],
rectangle
[
3
]
height
,
width
=
rectangle
[
4
],
rectangle
[
5
]
return
point1
,
point2
,
width
,
height
,
max_area
\ No newline at end of file
cythonModules/setup_getMaxRect.py
0 → 100644
View file @
893884dd
#!/usr/bin/env python3
# -*- 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/>.
"""
try
:
from
setuptools
import
setup
from
setuptools
import
Extension
except
ImportError
:
from
distutils.core
import
setup
from
distutils.extension
import
Extension
from
Cython.Build
import
cythonize
import
numpy
as
np
import
sys
,
os
if
os
.
path
.
exists
(
'getMaxRect.c'
):
print
(
'removing c file'
)
os
.
remove
(
'getMaxRect.c'
)
if
len
(
sys
.
argv
)
==
1
:
sys
.
argv
.
append
(
"build_ext"
)
sys
.
argv
.
append
(
"--inplace"
)
ext
=
Extension
(
"getMaxRect"
,
[
"getMaxRect.pyx"
],
extra_compile_args
=
[
'-O3'
],)
setup
(
name
=
"optimized find max rect-module"
,
ext_modules
=
cythonize
([
ext
]),
include_dirs
=
[
np
.
get_include
()]
)
external
/setuptsp.py
→
cythonModules
/setuptsp.py
View file @
893884dd
File moved
external
/tsp.pyx
→
cythonModules
/tsp.pyx
View file @
893884dd
File moved
dataset.py
View file @
893884dd
...
...
@@ -24,7 +24,6 @@ import numpy as np
import
sys
import
cv2
from
copy
import
copy
from
typing
import
List
from
.analysis.particleContainer
import
ParticleContainer
from
.legacyConvert
import
legacyConversion
,
currentVersion
from
.helperfunctions
import
cv2imwrite_fix
,
cv2imread_fix
...
...
@@ -32,7 +31,6 @@ from .helperfunctions import cv2imwrite_fix, cv2imread_fix
# (no relative import)
from
.
import
dataset
from
.
import
analysis
from
.coordinatetransform
import
TrayMarker
,
ImageMarker
sys
.
modules
[
'dataset'
]
=
dataset
sys
.
modules
[
'analysis'
]
=
analysis
...
...
@@ -136,8 +134,6 @@ class DataSet(object):
self
.
heightmap
=
None
self
.
zvalimg
=
None
self
.
coordinatetransform
=
None
# if imported form extern source coordinate system may be rotated
self
.
trayMarkers
:
List
[
TrayMarker
]
=
[]
# list of markers on the sample tray
self
.
imageMarkers
:
List
[
ImageMarker
]
=
[]
# list of coordinate markers within the image
self
.
signx
=
1.
self
.
signy
=
-
1.
...
...
@@ -173,7 +169,11 @@ class DataSet(object):
if
newProject
:
self
.
fname
=
self
.
newProject
(
fname
)
self
.
updatePath
()