Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
inovisao
pynovisao
Commits
2f27cdb9
Commit
2f27cdb9
authored
Jan 28, 2017
by
Alessandro dos Santos Ferreira
Browse files
Adicionando opcao Ground Truth
parent
31f30bd4
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
87 additions
and
13 deletions
+87
-13
src/interface/tk/tk_menu.py
src/interface/tk/tk_menu.py
+5
-3
src/interface/tk_interface.py
src/interface/tk_interface.py
+5
-3
src/main.py
src/main.py
+4
-2
src/pynovisao.py
src/pynovisao.py
+71
-3
src/segmentation/skimage_segmenter.py
src/segmentation/skimage_segmenter.py
+2
-2
No files found.
src/interface/tk/tk_menu.py
View file @
2f27cdb9
...
@@ -38,7 +38,7 @@ class Menu(object):
...
@@ -38,7 +38,7 @@ class Menu(object):
self
.
_items_menu
=
[]
self
.
_items_menu
=
[]
def
add_command
(
self
,
label
,
action
,
shortcut
):
def
add_command
(
self
,
label
,
action
,
shortcut
=
None
):
"""Add a new option to menu.
"""Add a new option to menu.
Parameters
Parameters
...
@@ -66,7 +66,7 @@ class Menu(object):
...
@@ -66,7 +66,7 @@ class Menu(object):
"""
"""
self
.
_items_menu
.
append
(
Separator
(
self
)
)
self
.
_items_menu
.
append
(
Separator
(
self
)
)
def
add_check_button
(
self
,
label
,
action
,
shortcut
):
def
add_check_button
(
self
,
label
,
action
,
shortcut
=
None
,
default_state
=
True
):
"""Add a new check button to menu.
"""Add a new check button to menu.
Parameters
Parameters
...
@@ -77,8 +77,10 @@ class Menu(object):
...
@@ -77,8 +77,10 @@ class Menu(object):
Callback to be executed on check button click.
Callback to be executed on check button click.
shortcut : string, optional, default = None
shortcut : string, optional, default = None
Check button shortcut number ou letter. Not case sensitive.
Check button shortcut number ou letter. Not case sensitive.
default_state : boolean, optional, default = True
Initial state of check button. If true set to on.
"""
"""
self
.
_items_menu
.
append
(
CheckButton
(
self
,
label
,
action
,
shortcut
)
)
self
.
_items_menu
.
append
(
CheckButton
(
self
,
label
,
action
,
shortcut
,
default_state
)
)
def
render
(
self
,
menubar
):
def
render
(
self
,
menubar
):
"""Render the menu in GUI.
"""Render the menu in GUI.
...
...
src/interface/tk_interface.py
View file @
2f27cdb9
...
@@ -87,7 +87,7 @@ class TkInterface(Interface):
...
@@ -87,7 +87,7 @@ class TkInterface(Interface):
"""
"""
self
.
_menus
[
-
1
].
add_separator
(
)
self
.
_menus
[
-
1
].
add_separator
(
)
def
add_check_button
(
self
,
label
,
action
,
shortcut
=
None
):
def
add_check_button
(
self
,
label
,
action
,
shortcut
=
None
,
default_state
=
True
):
"""Add a check button to last menu added.
"""Add a check button to last menu added.
Parameters
Parameters
...
@@ -96,10 +96,12 @@ class TkInterface(Interface):
...
@@ -96,10 +96,12 @@ class TkInterface(Interface):
Check button option label.
Check button option label.
action : function
action : function
Callback to be executed on check button click.
Callback to be executed on check button click.
shortcut : string
shortcut : string
, optional, default = None
Check button shortcut number ou letter. Not case sensitive.
Check button shortcut number ou letter. Not case sensitive.
default_state : boolean, optional, default = True
Initial state of check button. If true set to on.
"""
"""
self
.
_menus
[
-
1
].
add_check_button
(
label
=
label
,
action
=
lambda
*
_
:
self
.
_apply
(
action
),
shortcut
=
shortcut
)
self
.
_menus
[
-
1
].
add_check_button
(
label
=
label
,
action
=
lambda
*
_
:
self
.
_apply
(
action
),
shortcut
=
shortcut
,
default_state
=
default_state
)
def
render_menu
(
self
):
def
render_menu
(
self
):
"""Add to window GUI the last menu added.
"""Add to window GUI the last menu added.
...
...
src/main.py
View file @
2f27cdb9
...
@@ -6,7 +6,7 @@
...
@@ -6,7 +6,7 @@
This file is the main code of Pynovisao.
This file is the main code of Pynovisao.
To add a new action ( functionality ) to this software, you must implement the method body of action in file pynovisao.py
To add a new action ( functionality ) to this software, you must implement the method body of action in file pynovisao.py
and bind the method to menu, using the call tk.add_command.
and bind the method to menu, using the call tk.add_command
or tk.add_check_button
.
To add a new Feature Extractor, Segmenter or Classifier, place it in correct directory and extend its abstract class.
To add a new Feature Extractor, Segmenter or Classifier, place it in correct directory and extend its abstract class.
...
@@ -63,7 +63,7 @@ if __name__ == "__main__":
...
@@ -63,7 +63,7 @@ if __name__ == "__main__":
tk
.
add_command
(
"Add new class"
,
act
.
add_class
,
'A'
)
tk
.
add_command
(
"Add new class"
,
act
.
add_class
,
'A'
)
tk
.
add_command
(
"Set dataset path"
,
act
.
set_dataset_path
,
'd'
)
tk
.
add_command
(
"Set dataset path"
,
act
.
set_dataset_path
,
'd'
)
tk
.
add_separator
()
tk
.
add_separator
()
tk
.
add_check_button
(
"Dataset generator"
,
act
.
toggle_dataset_generator
,
't'
)
tk
.
add_check_button
(
"Dataset generator"
,
act
.
toggle_dataset_generator
)
tk
.
add_menu
(
"Segmentation"
)
tk
.
add_menu
(
"Segmentation"
)
tk
.
add_command
(
"Choose segmenter"
,
act
.
select_segmenter
)
tk
.
add_command
(
"Choose segmenter"
,
act
.
select_segmenter
)
...
@@ -80,6 +80,8 @@ if __name__ == "__main__":
...
@@ -80,6 +80,8 @@ if __name__ == "__main__":
tk
.
add_command
(
"Choose classifier"
,
act
.
select_classifier
)
tk
.
add_command
(
"Choose classifier"
,
act
.
select_classifier
)
tk
.
add_command
(
"Configure"
,
act
.
configure_classifier
)
tk
.
add_command
(
"Configure"
,
act
.
configure_classifier
)
tk
.
add_separator
()
tk
.
add_separator
()
tk
.
add_check_button
(
"Ground Truth"
,
act
.
toggle_ground_truth
,
default_state
=
False
)
tk
.
add_separator
()
tk
.
add_command
(
"Cross Validation"
,
act
.
cross_validation
,
'X'
)
tk
.
add_command
(
"Cross Validation"
,
act
.
cross_validation
,
'X'
)
tk
.
add_command
(
"Experimenter All"
,
act
.
experimenter_all
,
'p'
)
tk
.
add_command
(
"Experimenter All"
,
act
.
experimenter_all
,
'p'
)
tk
.
add_separator
()
tk
.
add_separator
()
...
...
src/pynovisao.py
View file @
2f27cdb9
...
@@ -9,6 +9,7 @@
...
@@ -9,6 +9,7 @@
"""
"""
from
collections
import
OrderedDict
from
collections
import
OrderedDict
import
numpy
as
np
import
interface
import
interface
from
interface.interface
import
InterfaceException
as
IException
from
interface.interface
import
InterfaceException
as
IException
...
@@ -17,6 +18,7 @@ import segmentation
...
@@ -17,6 +18,7 @@ import segmentation
import
extraction
import
extraction
from
extraction
import
FeatureExtractor
from
extraction
import
FeatureExtractor
import
classification
import
classification
from
classification
import
Classifier
import
util
import
util
from
util.config
import
Config
from
util.config
import
Config
...
@@ -58,6 +60,8 @@ class Act(object):
...
@@ -58,6 +60,8 @@ class Act(object):
self
.
_init_classes
(
args
[
"classes"
],
args
[
"colors"
])
self
.
_init_classes
(
args
[
"classes"
],
args
[
"colors"
])
self
.
_dataset_generator
=
True
self
.
_dataset_generator
=
True
self
.
_ground_truth
=
False
self
.
_gt_segments
=
None
def
_init_dataset
(
self
,
directory
):
def
_init_dataset
(
self
,
directory
):
...
@@ -125,9 +129,13 @@ class Act(object):
...
@@ -125,9 +129,13 @@ class Act(object):
self
.
tk
.
append_log
(
"Painting segment: %0.3f seconds"
,
run_time
)
self
.
tk
.
append_log
(
"Painting segment: %0.3f seconds"
,
run_time
)
self
.
tk
.
refresh_image
(
self
.
_image
)
self
.
tk
.
refresh_image
(
self
.
_image
)
filepath
=
f
.
save_class_image
(
segment
,
self
.
dataset
,
self
.
classes
[
self
.
_current_class
][
"name"
].
value
,
self
.
_image_name
,
idx_segment
)
if
self
.
_ground_truth
==
True
:
if
filepath
:
self
.
_gt_segments
[
idx_segment
]
=
self
.
classes
[
self
.
_current_class
][
"name"
].
value
self
.
tk
.
append_log
(
"
\n
Segment saved in %s"
,
filepath
)
elif
self
.
_dataset_generator
==
True
:
filepath
=
f
.
save_class_image
(
segment
,
self
.
dataset
,
self
.
classes
[
self
.
_current_class
][
"name"
].
value
,
self
.
_image_name
,
idx_segment
)
if
filepath
:
self
.
tk
.
append_log
(
"
\n
Segment saved in %s"
,
filepath
)
if
imagename
is
None
:
if
imagename
is
None
:
imagename
=
self
.
tk
.
utils
.
ask_image_name
()
imagename
=
self
.
tk
.
utils
.
ask_image_name
()
...
@@ -141,6 +149,7 @@ class Act(object):
...
@@ -141,6 +149,7 @@ class Act(object):
self
.
_const_image
=
self
.
_image
self
.
_const_image
=
self
.
_image
self
.
segmenter
.
reset
()
self
.
segmenter
.
reset
()
self
.
_gt_segments
=
None
def
restore_image
(
self
):
def
restore_image
(
self
):
...
@@ -151,6 +160,7 @@ class Act(object):
...
@@ -151,6 +160,7 @@ class Act(object):
self
.
tk
.
refresh_image
(
self
.
_const_image
)
self
.
tk
.
refresh_image
(
self
.
_const_image
)
self
.
segmenter
.
reset
()
self
.
segmenter
.
reset
()
self
.
_gt_segments
=
None
def
close_image
(
self
):
def
close_image
(
self
):
"""Close the image.
"""Close the image.
...
@@ -354,6 +364,8 @@ class Act(object):
...
@@ -354,6 +364,8 @@ class Act(object):
self
.
_image
,
run_time
=
self
.
segmenter
.
run
(
self
.
_const_image
)
self
.
_image
,
run_time
=
self
.
segmenter
.
run
(
self
.
_const_image
)
self
.
tk
.
append_log
(
"Time elapsed: %0.3f seconds"
,
run_time
)
self
.
tk
.
append_log
(
"Time elapsed: %0.3f seconds"
,
run_time
)
self
.
_gt_segments
=
[
None
]
*
(
max
(
self
.
segmenter
.
get_list_segments
())
+
1
)
self
.
tk
.
refresh_image
(
self
.
_image
)
self
.
tk
.
refresh_image
(
self
.
_image
)
...
@@ -488,6 +500,7 @@ class Act(object):
...
@@ -488,6 +500,7 @@ class Act(object):
self
.
_image
,
_
=
self
.
segmenter
.
run
(
self
.
_const_image
)
self
.
_image
,
_
=
self
.
segmenter
.
run
(
self
.
_const_image
)
self
.
tk
.
refresh_image
(
self
.
_image
)
self
.
tk
.
refresh_image
(
self
.
_image
)
list_segments
=
self
.
segmenter
.
get_list_segments
()
list_segments
=
self
.
segmenter
.
get_list_segments
()
self
.
_gt_segments
=
[
None
]
*
(
max
(
list_segments
)
+
1
)
# Train the classifier ( this program does not perform the training of ConvNets ).
# Train the classifier ( this program does not perform the training of ConvNets ).
if
self
.
classifier
.
must_train
():
if
self
.
classifier
.
must_train
():
...
@@ -530,6 +543,9 @@ class Act(object):
...
@@ -530,6 +543,9 @@ class Act(object):
self
.
tk
.
append_log
(
"Painting segments... (%0.3f seconds)"
,
(
TimeUtils
.
get_time
()
-
start_time
))
self
.
tk
.
append_log
(
"Painting segments... (%0.3f seconds)"
,
(
TimeUtils
.
get_time
()
-
start_time
))
# If ground truth mode, show alternative results
if
self
.
_ground_truth
==
True
:
return
self
.
_show_ground_truth
(
list_segments
,
len_segments
,
labels
,
start_time
)
# Create a popup with results of classification.
# Create a popup with results of classification.
popup_info
=
"%s
\n
"
%
str
(
self
.
classifier
.
get_summary_config
())
popup_info
=
"%s
\n
"
%
str
(
self
.
classifier
.
get_summary_config
())
...
@@ -554,8 +570,60 @@ class Act(object):
...
@@ -554,8 +570,60 @@ class Act(object):
self
.
tk
.
append_log
(
"
\n
Classification finished"
)
self
.
tk
.
append_log
(
"
\n
Classification finished"
)
self
.
tk
.
append_log
(
"Time elapsed: %0.3f seconds"
,
(
end_time
-
start_time
))
self
.
tk
.
append_log
(
"Time elapsed: %0.3f seconds"
,
(
end_time
-
start_time
))
def
_show_ground_truth
(
self
,
list_segments
,
len_segments
,
labels
,
start_time
):
"""Paint only wrong classified segments and show ground truth confusion matrix.
Parameters
----------
list_segments : list of integer
List of index segments.
len_segments : list of integer
List of segments sizes.
labels : list of string
List of predicted class name for each segment.
start_time : floating point
Start time of classification.
"""
classes
=
list
(
set
(
labels
))
classes
.
sort
()
n_segments
=
len
(
labels
)
spx_matrix
=
np
.
zeros
((
len
(
classes
),
len
(
classes
)),
np
.
int
)
px_matrix
=
np
.
zeros
((
len
(
classes
),
len
(
classes
)),
np
.
int
)
# Create the confusion matrix and paint wrong classified segments individually.
for
idx_segment
in
list_segments
:
if
self
.
_gt_segments
[
idx_segment
]
is
not
None
:
gt_class
=
classes
.
index
(
self
.
_gt_segments
[
idx_segment
])
predicted_class
=
classes
.
index
(
labels
[
idx_segment
])
spx_matrix
[
gt_class
][
predicted_class
]
+=
1
px_matrix
[
gt_class
][
predicted_class
]
+=
len_segments
[
idx_segment
]
if
gt_class
!=
predicted_class
:
self
.
_image
,
_
=
self
.
segmenter
.
paint_segment
(
self
.
_image
,
self
.
get_class_by_name
(
labels
[
idx_segment
])[
"color"
].
value
,
idx_segment
=
[
idx_segment
],
border
=
False
)
# Create a popup with results of classification.
popup_info
=
"%s
\n
"
%
str
(
self
.
classifier
.
get_summary_config
())
popup_info
+=
Classifier
.
confusion_matrix
(
classes
,
spx_matrix
,
"Superpixels"
)
popup_info
+=
Classifier
.
confusion_matrix
(
classes
,
px_matrix
,
"PixelSum"
)
self
.
tk
.
refresh_image
(
self
.
_image
)
self
.
tk
.
popup
(
popup_info
)
end_time
=
TimeUtils
.
get_time
()
self
.
tk
.
append_log
(
"
\n
Classification finished"
)
self
.
tk
.
append_log
(
"Time elapsed: %0.3f seconds"
,
(
end_time
-
start_time
))
def
toggle_ground_truth
(
self
):
"""Enable/disable ground truth mode.
"""
self
.
_ground_truth
=
not
self
.
_ground_truth
def
cross_validation
(
self
):
def
cross_validation
(
self
):
"""Run a cross validation on all generated segments in image dataset.
"""Run a cross validation on all generated segments in image dataset.
...
...
src/segmentation/skimage_segmenter.py
View file @
2f27cdb9
...
@@ -157,7 +157,7 @@ class SkimageSegmenter(object):
...
@@ -157,7 +157,7 @@ class SkimageSegmenter(object):
idx_segment
=
[
self
.
_segments
[
py
,
px
]]
idx_segment
=
[
self
.
_segments
[
py
,
px
]]
height
,
width
,
channels
=
self
.
_original_image
.
shape
height
,
width
,
channels
=
self
.
_original_image
.
shape
# Create a mask, painting black all pixels outside of segment and white the pixels inside
# Create a mask, painting black all pixels outside of segment
s
and white the pixels inside
mask_segment
=
np
.
zeros
(
self
.
_original_image
.
shape
[:
2
],
dtype
=
"uint8"
)
mask_segment
=
np
.
zeros
(
self
.
_original_image
.
shape
[:
2
],
dtype
=
"uint8"
)
for
idx
in
idx_segment
:
for
idx
in
idx_segment
:
mask_segment
[
self
.
_segments
==
idx
]
=
255
mask_segment
[
self
.
_segments
==
idx
]
=
255
...
@@ -172,7 +172,7 @@ class SkimageSegmenter(object):
...
@@ -172,7 +172,7 @@ class SkimageSegmenter(object):
colored_image
=
cv2
.
addWeighted
(
image
,
0.7
,
class_color
,
0.3
,
0
)
colored_image
=
cv2
.
addWeighted
(
image
,
0.7
,
class_color
,
0.3
,
0
)
colored_image
=
cv2
.
bitwise_and
(
colored_image
,
colored_image
,
mask
=
mask_segment
)
colored_image
=
cv2
.
bitwise_and
(
colored_image
,
colored_image
,
mask
=
mask_segment
)
# Create a new image keeping the painting only in pixels inside of segment
# Create a new image keeping the painting only in pixels inside of segment
s
new_image
=
image
if
clear
==
False
else
self
.
_original_image
new_image
=
image
if
clear
==
False
else
self
.
_original_image
new_image
=
cv2
.
bitwise_and
(
new_image
,
new_image
,
mask
=
mask_inv
)
new_image
=
cv2
.
bitwise_and
(
new_image
,
new_image
,
mask
=
mask_inv
)
mask_segment
[:]
=
255
mask_segment
[:]
=
255
...
...
Write
Preview
Markdown
is supported
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