Adicionando opcao Ground Truth

parent 31f30bd4
......@@ -38,7 +38,7 @@ class Menu(object):
self._items_menu = []
def add_command(self, label, action, shortcut):
def add_command(self, label, action, shortcut = None):
"""Add a new option to menu.
Parameters
......@@ -66,7 +66,7 @@ class Menu(object):
"""
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.
Parameters
......@@ -77,8 +77,10 @@ class Menu(object):
Callback to be executed on check button click.
shortcut : string, optional, default = None
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):
"""Render the menu in GUI.
......
......@@ -87,7 +87,7 @@ class TkInterface(Interface):
"""
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.
Parameters
......@@ -96,10 +96,12 @@ class TkInterface(Interface):
Check button option label.
action : function
Callback to be executed on check button click.
shortcut : string
shortcut : string, optional, default = None
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):
"""Add to window GUI the last menu added.
......
......@@ -6,7 +6,7 @@
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
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.
......@@ -63,7 +63,7 @@ if __name__ == "__main__":
tk.add_command("Add new class", act.add_class, 'A')
tk.add_command("Set dataset path", act.set_dataset_path, 'd')
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_command("Choose segmenter", act.select_segmenter)
......@@ -80,6 +80,8 @@ if __name__ == "__main__":
tk.add_command("Choose classifier", act.select_classifier)
tk.add_command("Configure", act.configure_classifier)
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("Experimenter All", act.experimenter_all, 'p')
tk.add_separator()
......
......@@ -9,6 +9,7 @@
"""
from collections import OrderedDict
import numpy as np
import interface
from interface.interface import InterfaceException as IException
......@@ -17,6 +18,7 @@ import segmentation
import extraction
from extraction import FeatureExtractor
import classification
from classification import Classifier
import util
from util.config import Config
......@@ -58,6 +60,8 @@ class Act(object):
self._init_classes(args["classes"], args["colors"])
self._dataset_generator = True
self._ground_truth = False
self._gt_segments = None
def _init_dataset(self, directory):
......@@ -125,9 +129,13 @@ class Act(object):
self.tk.append_log("Painting segment: %0.3f seconds", run_time)
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 filepath:
self.tk.append_log("\nSegment saved in %s", filepath)
if self._ground_truth == True:
self._gt_segments[idx_segment] = self.classes[self._current_class]["name"].value
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("\nSegment saved in %s", filepath)
if imagename is None:
imagename = self.tk.utils.ask_image_name()
......@@ -141,6 +149,7 @@ class Act(object):
self._const_image = self._image
self.segmenter.reset()
self._gt_segments = None
def restore_image(self):
......@@ -151,6 +160,7 @@ class Act(object):
self.tk.refresh_image(self._const_image)
self.segmenter.reset()
self._gt_segments = None
def close_image(self):
"""Close the image.
......@@ -354,6 +364,8 @@ class Act(object):
self._image, run_time = self.segmenter.run(self._const_image)
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)
......@@ -488,6 +500,7 @@ class Act(object):
self._image, _ = self.segmenter.run(self._const_image)
self.tk.refresh_image(self._image)
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 ).
if self.classifier.must_train():
......@@ -530,6 +543,9 @@ class Act(object):
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.
popup_info = "%s\n" % str(self.classifier.get_summary_config())
......@@ -554,8 +570,60 @@ class Act(object):
self.tk.append_log("\nClassification finished")
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("\nClassification 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):
"""Run a cross validation on all generated segments in image dataset.
......
......@@ -157,7 +157,7 @@ class SkimageSegmenter(object):
idx_segment = [self._segments[py, px]]
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 segments and white the pixels inside
mask_segment = np.zeros(self._original_image.shape[:2], dtype="uint8")
for idx in idx_segment:
mask_segment[self._segments == idx] = 255
......@@ -172,7 +172,7 @@ class SkimageSegmenter(object):
colored_image = cv2.addWeighted(image, 0.7, class_color, 0.3, 0)
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 segments
new_image = image if clear == False else self._original_image
new_image = cv2.bitwise_and(new_image, new_image, mask=mask_inv)
mask_segment[:] = 255
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment