Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
XRD
darfix
Commits
32c236d6
Commit
32c236d6
authored
Feb 28, 2020
by
Julia Garriga Ferrer
Browse files
Merge branch 'silx_backend' into 'master'
Silx backend See merge request julia.garriga/darfix!44
parents
bbda9007
2605d313
Pipeline
#22165
passed with stage
in 3 minutes and 17 seconds
Changes
4
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
darfix/core/componentsMatching.py
View file @
32c236d6
...
...
@@ -34,12 +34,15 @@ import numpy
from
enum
import
Enum
from
silx.image
import
sift
class
Method
(
Enum
):
"""
Methods available to compute the matching.
"""
feature_matching
=
"feature matching"
orb_feature_matching
=
"orb feature matching"
sift_feature_matching
=
"sift feature matching"
euclidean_distance
=
"euclidean distance"
@
staticmethod
...
...
@@ -57,24 +60,37 @@ class ComponentsMatching():
def
__init__
(
self
,
components
):
self
.
_create_descriptors
(
components
)
self
.
components
=
components
def
_create_descriptors
(
self
,
components_list
):
def
_create_descriptors
(
self
):
"""
Function that detects and computes the keypoints and descriptors for
the components.
"""
self
.
orb
=
cv2
.
ORB_create
()
self
.
components
=
[]
orb
=
cv2
.
ORB_create
()
descripted_
components
=
[]
for
array
in
components
_list
:
for
array
in
self
.
components
:
components
=
[]
for
image
in
array
:
cv2
.
normalize
(
image
,
image
,
0
,
255
,
cv2
.
NORM_MINMAX
)
image
=
image
.
astype
(
numpy
.
uint8
)
kp
,
des
=
self
.
orb
.
detectAndCompute
(
image
,
None
)
kp
,
des
=
orb
.
detectAndCompute
(
image
,
None
)
components
.
append
(
Component
(
image
,
kp
,
des
))
self
.
components
.
append
(
components
)
descripted_components
.
append
(
components
)
return
descripted_components
def
_create_sift_keypoints
(
self
):
keypoints
=
[]
for
array
in
self
.
components
:
sift_ocl
=
sift
.
SiftPlan
(
template
=
array
[
0
],
devicetype
=
"CPU"
)
components
=
[
sift_ocl
(
image
)
for
image
in
array
]
keypoints
.
append
(
components
)
return
keypoints
def
euclidean_distance
(
self
,
X
,
Y
):
"""
...
...
@@ -85,7 +101,7 @@ class ComponentsMatching():
dst
=
numpy
.
linalg
.
norm
(
X
-
Y
)
# their euclidean distances
return
dst
def
match_components
(
self
,
id1
=
None
,
id2
=
None
,
method
=
Method
.
feature_matching
):
def
match_components
(
self
,
id1
=
None
,
id2
=
None
,
method
=
Method
.
orb_
feature_matching
):
"""
Match components. Given the components x1,...,xn of dataset 1 and the
components y1,...,ym of dataset 2, this function computes the pairs
...
...
@@ -108,12 +124,14 @@ class ComponentsMatching():
matches
=
{}
final_matches
=
{}
if
method
==
Method
.
feature_matching
:
if
method
==
Method
.
orb_feature_matching
:
self
.
descriptors
=
self
.
_create_descriptors
()
bf
=
cv2
.
BFMatcher
(
cv2
.
NORM_HAMMING
,
crossCheck
=
True
)
# Match components with id1 and id2
for
i
,
component1
in
enumerate
(
self
.
component
s
[
id1
]):
for
i
,
component1
in
enumerate
(
self
.
descriptor
s
[
id1
]):
if
component1
.
descriptor
is
not
None
:
for
j
,
component2
in
enumerate
(
self
.
component
s
[
id2
]):
for
j
,
component2
in
enumerate
(
self
.
descriptor
s
[
id2
]):
if
component2
.
descriptor
is
not
None
:
# Match descriptors
matches
[(
i
,
j
)]
=
bf
.
match
(
component1
.
descriptor
,
...
...
@@ -125,10 +143,26 @@ class ComponentsMatching():
if
x
not
in
final_matches
.
keys
()
and
y
not
in
final_matches
.
values
():
final_matches
[
x
]
=
y
elif
method
==
Method
.
sift_feature_matching
:
keypoints
=
self
.
_create_sift_keypoints
()
mp
=
sift
.
MatchPlan
()
# Match components with id1 and id2
for
i
,
kp1
in
enumerate
(
keypoints
[
id1
]):
for
j
,
kp2
in
enumerate
(
keypoints
[
id2
]):
# Match descriptors
matches
[(
i
,
j
)]
=
mp
.
match
(
kp1
,
kp2
)
# Add matches sorted by number of matches found.
for
x
,
y
in
sorted
(
matches
,
key
=
lambda
match
:
matches
[
match
].
shape
[
0
],
reverse
=
True
):
# Only add match if neither x nor y are already in the list.
if
x
not
in
final_matches
.
keys
()
and
y
not
in
final_matches
.
values
():
final_matches
[
x
]
=
y
elif
method
==
Method
.
euclidean_distance
:
for
i
,
X
in
enumerate
(
self
.
components
[
id1
]):
for
j
,
Y
in
enumerate
(
self
.
components
[
id2
]):
matches
[(
i
,
j
)]
=
self
.
euclidean_distance
(
X
.
image
,
Y
.
image
)
matches
[(
i
,
j
)]
=
self
.
euclidean_distance
(
X
,
Y
)
# Add matches sorted by distance.
for
x
,
y
in
sorted
(
matches
,
key
=
lambda
match
:
matches
[
match
]):
# Only add match if neither x nor y are already in the list.
...
...
@@ -157,32 +191,32 @@ class ComponentsMatching():
id1
=
0
id2
=
1
stack
=
[]
for
i
,
component
in
enumerate
(
self
.
components
[
id1
]):
for
i
,
img1
in
enumerate
(
self
.
components
[
id1
]):
if
i
in
final_matches
:
j
=
final_matches
[
i
]
component
2
=
self
.
components
[
id2
][
j
]
img
2
=
self
.
components
[
id2
][
j
]
# Show link between features
if
displayMatches
:
# Check that all values are of type `cv2.DMatch`
assert
all
((
isinstance
(
match
,
cv2
.
DMatch
)
for
match
in
values
)
for
values
in
matches
.
values
()),
\
"Dictionary `matches` has to contain values of type `cv2.DMatch`"
img
=
cv2
.
drawMatches
(
component
.
image
,
self
.
component
s
[
id1
][
i
].
keypoints
,
component2
.
image
,
self
.
component
s
[
id2
][
j
].
keypoints
,
img
=
cv2
.
drawMatches
(
self
.
descriptors
[
id1
][
i
]
.
image
,
self
.
descriptor
s
[
id1
][
i
].
keypoints
,
self
.
descriptors
[
id2
][
j
]
.
image
,
self
.
descriptor
s
[
id2
][
j
].
keypoints
,
matches
[(
i
,
j
)],
None
,
flags
=
2
)
img
=
cv2
.
cvtColor
(
img
,
cv2
.
COLOR_BGR2GRAY
)
else
:
shape1
,
shape2
=
component
.
image
.
shape
,
component2
.
image
.
shape
shape1
,
shape2
=
img1
.
shape
,
img2
.
shape
img
=
numpy
.
zeros
((
max
(
shape1
[
0
],
shape2
[
0
]),
shape1
[
1
]
+
shape2
[
1
]))
img
[:
shape1
[
0
],
:
shape1
[
1
]]
=
component
.
image
img
[:
shape2
[
0
],
shape1
[
1
]:]
=
component2
.
image
img
[:
shape1
[
0
],
:
shape1
[
1
]]
=
img1
img
[:
shape2
[
0
],
shape1
[
1
]:]
=
img2
else
:
shape1
=
component
.
image
.
shape
shape2
=
self
.
components
[
id2
][
0
].
image
.
shape
shape1
=
img1
.
shape
shape2
=
self
.
components
[
id2
][
0
].
shape
img
=
numpy
.
zeros
((
max
(
shape1
[
0
],
shape2
[
0
]),
shape1
[
1
]
+
shape2
[
1
]))
img
[:
shape1
[
0
],
:
shape1
[
1
]]
=
component
.
image
img
[:
shape1
[
0
],
:
shape1
[
1
]]
=
img1
stack
.
append
(
img
)
return
stack
...
...
darfix/core/imageOperations.py
View file @
32c236d6
...
...
@@ -29,7 +29,7 @@ __license__ = "MIT"
__date__
=
"29/11/2019"
import
numpy
import
cv2
import
silx.math
from
enum
import
Enum
...
...
@@ -145,7 +145,7 @@ def hot_pixel_removal(data, ksize=3):
elif
frame
.
dtype
==
numpy
.
float
:
frame
=
frame
.
astype
(
numpy
.
float32
)
corrected_frame
=
numpy
.
array
(
frame
)
median
=
cv2
.
medianBlur
(
frame
,
ksize
)
median
=
silx
.
math
.
medfilt
(
frame
,
ksize
)
hot_pixels
=
numpy
.
subtract
(
frame
,
median
,
dtype
=
numpy
.
int64
)
threshold
=
numpy
.
std
(
hot_pixels
)
corrected_frame
[
hot_pixels
>
threshold
]
=
median
[
hot_pixels
>
threshold
]
...
...
darfix/core/test/test_components_matching.py
View file @
32c236d6
...
...
@@ -65,11 +65,11 @@ class TestComponentsMatching(unittest.TestCase):
def
test_match_components
(
self
):
final_matches
,
matches
=
self
.
componentsMatching
.
match_components
(
method
=
Method
.
feature_matching
)
final_matches
,
matches
=
self
.
componentsMatching
.
match_components
(
method
=
Method
.
orb_
feature_matching
)
self
.
assertEqual
(
final_matches
[
0
],
1
)
def
test_draw_matches0
(
self
):
final_matches
,
matches
=
self
.
componentsMatching
.
match_components
(
method
=
Method
.
feature_matching
)
final_matches
,
matches
=
self
.
componentsMatching
.
match_components
(
method
=
Method
.
orb_
feature_matching
)
stack
=
self
.
componentsMatching
.
draw_matches
(
final_matches
,
matches
,
displayMatches
=
True
)
self
.
assertEqual
(
stack
[
0
].
shape
,
(
512
,
1024
))
stack
=
self
.
componentsMatching
.
draw_matches
(
final_matches
,
matches
,
displayMatches
=
False
)
...
...
darfix/gui/linkComponentsWidget.py
View file @
32c236d6
...
...
@@ -172,12 +172,12 @@ class LinkComponentsWidget(qt.QWidget):
def
_comboBoxChanged
(
self
,
text
):
method
=
Method
(
text
)
if
method
==
Method
.
euclidean_distance
:
self
.
_checkbox
.
setEnabled
(
False
)
self
.
_displayMatches
=
False
else
:
if
method
==
Method
.
orb_feature_matching
:
self
.
_checkbox
.
setEnabled
(
True
)
self
.
_displayMatches
=
self
.
_checkbox
.
checkState
()
else
:
self
.
_checkbox
.
setEnabled
(
False
)
self
.
_displayMatches
=
False
def
_linkComponents
(
self
):
"""
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment