torchsight.evaluators.flickr32.fl_plot_classification_results
module
Plots some charts for a given object recognition result.
Tools for the FlickrLogos-32 dataset. See http://www.multimedia-computing.de/flickrlogos/ for details.
Please cite the following paper in your work: Scalable Logo Recognition in Real-World Images Stefan Romberg, Lluis Garcia Pueyo, Rainer Lienhart, Roelof van Zwol ACM International Conference on Multimedia Retrieval 2011 (ICMR11), Trento, April 2011.
Author
:Stefan
Romberg
,stefan.romberg
@informatik.uni
-augsburg.de
Notes: - Script was developed/tested on Windows with Python 2.7
$Date: 2013-11-18 11:15:33 +0100 (Mo, 18 Nov 2013) $ $Rev: 7621 $$Date: 2013-11-18 11:15:33 +0100 (Mo, 18 Nov 2013) $ $HeadURL: https://137.250.173.47:8443/svn/romberg/trunk/romberg/research/FlickrLogos-32_SDK/FlickrLogos-32_SDK-1.0.4/scripts/fl_plot_classification_results.py $ $Id: fl_plot_classification_results.py 7621 2013-11-18 10:15:33Z romberg $
Source code
# -*- coding: utf-8 -*-
"""
Plots some charts for a given object recognition result.
Tools for the FlickrLogos-32 dataset.
See http://www.multimedia-computing.de/flickrlogos/ for details.
Please cite the following paper in your work:
Scalable Logo Recognition in Real-World Images
Stefan Romberg, Lluis Garcia Pueyo, Rainer Lienhart, Roelof van Zwol
ACM International Conference on Multimedia Retrieval 2011 (ICMR11), Trento, April 2011.
Author: Stefan Romberg, stefan.romberg@informatik.uni-augsburg.de
Notes:
- Script was developed/tested on Windows with Python 2.7
$Date: 2013-11-18 11:15:33 +0100 (Mo, 18 Nov 2013) $
$Rev: 7621 $$Date: 2013-11-18 11:15:33 +0100 (Mo, 18 Nov 2013) $
$HeadURL: https://137.250.173.47:8443/svn/romberg/trunk/romberg/research/FlickrLogos-32_SDK/FlickrLogos-32_SDK-1.0.4/scripts/fl_plot_classification_results.py $
$Id: fl_plot_classification_results.py 7621 2013-11-18 10:15:33Z romberg $
"""
__version__ = "$Id: fl_plot_classification_results.py 7621 2013-11-18 10:15:33Z romberg $"
__author__ = "Stefan Romberg, stefan.romberg@informatik.uni-augsburg.de"
import sys, os.path
from os.path import exists, basename
from collections import defaultdict
import matplotlib.pyplot as plt
from .flickrlogos import fl_read_groundtruth, fl_read_csv
from .flickrlogos.ConfusionMatrix import ConfusionMatrix
#==============================================================================
#
#==============================================================================
def plot_bar_chart(x_names, y_values, title="", xlabel="", ylabel="", y_perc=None, figsize=None):
"""Plots bar char."""
assert isinstance(x_names, list)
assert isinstance(y_values, list)
fig = plt.figure(figsize=figsize)
ax = fig.add_subplot(111)
x = range(0, len(x_names))
x = [ xx + 0.5 for xx in x ]
ax.bar(x, y_values)
ax.grid(True)
ax.set_autoscale_on(True)
ax.set_title(title)
ax.set_xlabel(xlabel)
ax.set_ylabel(ylabel)
ax.set_xlim(0, max(x)+1.25 )
ax.set_ylim(0, max(y_values)+0.25 )
plt.xticks( [xx + 0.5 for xx in x], x_names, rotation=50, horizontalalignment='right')
for i,y_val in enumerate(y_values):
plt.text(0.65+i*1.000, 0.5, str(y_val).rjust(2), color="white", fontsize="small")
if y_perc is not None:
for i,y_val in enumerate(y_perc):
s = str(int(round(y_val)))
plt.text(0.60+i*1.000, 2.0, s.rjust(3), color="white", fontsize="x-small")
plt.text(0.60+i*1.000, 2.8, " %", color="white", fontsize="x-small")
plt.subplots_adjust(top=0.93,
bottom=0.18,
left=0.08,
right=0.97)
plt.tight_layout(pad=1.0)
return plt
#==============================================================================
# main()
#==============================================================================
def main(flickrlogos_dir, result_file, output_prefix,
output_formats="_.png,.pdf,.eps,.svg", # PNG files end on '_.png', this makes latex ignore them
show_plots=False):
"""main()"""
graphic_formats = []
if output_formats is not None and output_formats != None:
graphic_formats = output_formats.split(",")
if not exists(flickrlogos_dir):
print("ERROR: main(): Directory does not exist: '"+str(flickrlogos_dir)+"'")
exit(1)
if not flickrlogos_dir.endswith('/') and not flickrlogos_dir.endswith('\\'):
flickrlogos_dir += '/'
gt_all = flickrlogos_dir + "all.txt"
if not exists(gt_all):
print("ERROR: File does not exist: '"+str(gt_all)+"'")
exit(1)
if not exists(result_file):
print("ERROR: File does not exist: '"+str(result_file)+"'")
exit(1)
#==========================================================================
# load data
#==========================================================================
groundtruth, class_names = fl_read_groundtruth(gt_all)
actual_data = fl_read_csv(result_file)
actual_data = [ (image_id, classification.lower(), confidence) for image_id, classification, confidence in actual_data ]
for image_id, classification, confidence in actual_data:
assert classification in class_names, (classification, class_names)
#==========================================================================
# Process data, count TPs for each class
#==========================================================================
tp_per_class = defaultdict(int)
for image_id, classification, confidence in actual_data:
im = image_id + ".jpg"
if not im in groundtruth:
continue
if groundtruth[im] == classification:
tp_per_class[classification] += 1
# remove no-logo class from bar chart
class_names_logosonly = [ c for c in class_names if c != "no-logo" ]
# fetch TP counts
tp_values = [ tp_per_class[c] for c in class_names_logosonly ]
tp_perc = [ (float(tp_per_class[c])/30.0)*100.0 for c in class_names_logosonly ]
# prepare class names for visualization with proper capitalization and abbreviations
class_names_logosonly = [ c.capitalize() if len(c) > 3 else c.upper() for c in class_names_logosonly ]
#==========================================================================
# plot
#==========================================================================
p = plot_bar_chart(x_names=class_names_logosonly,
y_values=tp_values,
y_perc=tp_perc,
title="True Positives per Class",
xlabel="Class",
ylabel="True Positives",
figsize=(10, 6))
filename = output_prefix + "results-tp-per-class"
for format_ext in graphic_formats:
p.savefig(filename+format_ext, dpi=300, transparent=True)
if show_plots:
p.show()
#==========================================================================
# plot confusion matrix
#==========================================================================
cm = ConfusionMatrix()
for image_id, classification, confidence in actual_data:
im = image_id + ".jpg"
if not im in groundtruth:
continue
cm.add_result(groundtruth[im], classification)
p = cm.plot()
filename = output_prefix + "results-conf-mat"
for format_ext in graphic_formats:
p.savefig(filename+format_ext, dpi=300, transparent=True)
if show_plots:
p.show()
#==============================================================================
if __name__ == '__main__': # MAIN
#==============================================================================
print("fl_plot_classification_results.py\n"+__version__)
# ----------------------------------------------------------------
from optparse import OptionParser
usage = "Usage: %prog --flickrlogos=<dataset root dir> --classification=<classification file> "
parser = OptionParser(usage=usage)
parser.add_option("--flickrlogos", dest="flickrlogos", type=str, default="",
help="Base (root) directory of the FlickrLogos-32 dataset\n")
parser.add_option("--classification", dest="classification", type=str, default="",
help="""File containing images and the corresponding detected classes " +
"in the following format: <image id>, <detected class name>, "+
"<confidence value or 1 if class was detected, 0 otherwise> \n""")
parser.add_option("--output-prefix", dest="output_prefix", type=str, default="",
help="""Output directory for generated plots.""")
parser.add_option("--output-formats", dest="output_formats", type=str, default="_.png,.pdf,.eps,.svg",
help="""Desired output formats for plots\nDefault: '_.png,.pdf,.eps,.svg'.\n""")
parser.add_option("--show-images", dest="show_images", default="yes",
help="""Show plots to user.\n""")
(options, args) = parser.parse_args()
if len(sys.argv) < 3:
parser.print_help()
exit(1)
if options.show_images.lower() == "false" or options.show_images.lower() == "no":
options.show_images = False
#==========================================================================
# show passed args
#==========================================================================
print("-"*79)
print(" --flickrlogos base dir: '"+str(options.flickrlogos)+"'")
print(" --classification: '"+str(options.classification)+"'")
print(" --output-prefix: '"+str(options.output_prefix)+"'")
print(" --output-formats: '"+str(options.output_formats)+"'")
print(" --show-images: '"+str(options.show_images)+"'")
print("-"*79)
print("")
if not exists(options.flickrlogos):
print("ERROR: Invalid argument --flickrlogos: Directory does not exist: '"+str(options.flickrlogos)+"'")
exit(1)
if not exists(options.classification):
print("ERROR: Invalid argument --classification: File does not exist: '"+str(options.classification)+"'")
exit(1)
#==========================================================================
#
#==========================================================================
main(options.flickrlogos,
options.classification,
options.output_prefix,
options.output_formats,
options.show_images)
print("Done")
Functions
def main(flickrlogos_dir, result_file, output_prefix, output_formats='_.png,.pdf,.eps,.svg', show_plots=False)
-
main()
Source code
def main(flickrlogos_dir, result_file, output_prefix, output_formats="_.png,.pdf,.eps,.svg", # PNG files end on '_.png', this makes latex ignore them show_plots=False): """main()""" graphic_formats = [] if output_formats is not None and output_formats != None: graphic_formats = output_formats.split(",") if not exists(flickrlogos_dir): print("ERROR: main(): Directory does not exist: '"+str(flickrlogos_dir)+"'") exit(1) if not flickrlogos_dir.endswith('/') and not flickrlogos_dir.endswith('\\'): flickrlogos_dir += '/' gt_all = flickrlogos_dir + "all.txt" if not exists(gt_all): print("ERROR: File does not exist: '"+str(gt_all)+"'") exit(1) if not exists(result_file): print("ERROR: File does not exist: '"+str(result_file)+"'") exit(1) #========================================================================== # load data #========================================================================== groundtruth, class_names = fl_read_groundtruth(gt_all) actual_data = fl_read_csv(result_file) actual_data = [ (image_id, classification.lower(), confidence) for image_id, classification, confidence in actual_data ] for image_id, classification, confidence in actual_data: assert classification in class_names, (classification, class_names) #========================================================================== # Process data, count TPs for each class #========================================================================== tp_per_class = defaultdict(int) for image_id, classification, confidence in actual_data: im = image_id + ".jpg" if not im in groundtruth: continue if groundtruth[im] == classification: tp_per_class[classification] += 1 # remove no-logo class from bar chart class_names_logosonly = [ c for c in class_names if c != "no-logo" ] # fetch TP counts tp_values = [ tp_per_class[c] for c in class_names_logosonly ] tp_perc = [ (float(tp_per_class[c])/30.0)*100.0 for c in class_names_logosonly ] # prepare class names for visualization with proper capitalization and abbreviations class_names_logosonly = [ c.capitalize() if len(c) > 3 else c.upper() for c in class_names_logosonly ] #========================================================================== # plot #========================================================================== p = plot_bar_chart(x_names=class_names_logosonly, y_values=tp_values, y_perc=tp_perc, title="True Positives per Class", xlabel="Class", ylabel="True Positives", figsize=(10, 6)) filename = output_prefix + "results-tp-per-class" for format_ext in graphic_formats: p.savefig(filename+format_ext, dpi=300, transparent=True) if show_plots: p.show() #========================================================================== # plot confusion matrix #========================================================================== cm = ConfusionMatrix() for image_id, classification, confidence in actual_data: im = image_id + ".jpg" if not im in groundtruth: continue cm.add_result(groundtruth[im], classification) p = cm.plot() filename = output_prefix + "results-conf-mat" for format_ext in graphic_formats: p.savefig(filename+format_ext, dpi=300, transparent=True) if show_plots: p.show()
def plot_bar_chart(x_names, y_values, title='', xlabel='', ylabel='', y_perc=None, figsize=None)
-
Plots bar char.
Source code
def plot_bar_chart(x_names, y_values, title="", xlabel="", ylabel="", y_perc=None, figsize=None): """Plots bar char.""" assert isinstance(x_names, list) assert isinstance(y_values, list) fig = plt.figure(figsize=figsize) ax = fig.add_subplot(111) x = range(0, len(x_names)) x = [ xx + 0.5 for xx in x ] ax.bar(x, y_values) ax.grid(True) ax.set_autoscale_on(True) ax.set_title(title) ax.set_xlabel(xlabel) ax.set_ylabel(ylabel) ax.set_xlim(0, max(x)+1.25 ) ax.set_ylim(0, max(y_values)+0.25 ) plt.xticks( [xx + 0.5 for xx in x], x_names, rotation=50, horizontalalignment='right') for i,y_val in enumerate(y_values): plt.text(0.65+i*1.000, 0.5, str(y_val).rjust(2), color="white", fontsize="small") if y_perc is not None: for i,y_val in enumerate(y_perc): s = str(int(round(y_val))) plt.text(0.60+i*1.000, 2.0, s.rjust(3), color="white", fontsize="x-small") plt.text(0.60+i*1.000, 2.8, " %", color="white", fontsize="x-small") plt.subplots_adjust(top=0.93, bottom=0.18, left=0.08, right=0.97) plt.tight_layout(pad=1.0) return plt