Commit 9ff935dd authored by Niels-Oliver Walkowski's avatar Niels-Oliver Walkowski
Browse files

add describe method for creating complete movie descriptions

parent 7c78c442
......@@ -4,6 +4,12 @@ Itten
Itten is a python library to analyse and visualize color dynamics within moving
image files or frames that were extracted from moving image files.
Optimization
============
Eventuell kann ich einen ganzen Film oder zumindest die Kontrastwerte eines
ganzen Films speichern, wenn ich nur die Histogramme speicher (256 * frames)
ToDo
====
......
......@@ -4,8 +4,10 @@
from pathlib import Path # TODO wie kann ich third-party module nach außen verstecken
# TODO Ist der import aus dem selben Pakte so korrekt?
from . import helpers
from . import views
from . import visuals
import numpy as np
# zum Problem mit privaten und öffentlichen Eigenschaften http://www.python-course.eu/python3_properties.php und 'Fluent Python' relativ weit vorne
# numpy gibt beim Versuch zB. size zu schreiben auch ein AttributeError() aus.
......@@ -15,14 +17,122 @@ class Movie(object):
self._frames = Frames(folder, prefix)
self.fsize = self._frames.frm_cnt
# TODO Warum ist die hier?
def light_dark(self):
"""compute the light/dark contrast of the movie """
light_dark_ctrst = views.LightDark(self._frames)
return light_dark_ctrst.hist_vstack()
def describe(self, desc=False, start=1, end=0, stp=5):
"""Calculates each feature provided by Itten for the movie instance
Summary values will be returned in a python dictionary. Contrast
sequences will not be returned due to save memory. The method which
will be used to compute each contrast is the contrast class' default
method. Instead the will be plotted using Itten Sequence Plots. More
precisely MultivariatePlot and UnivariatePlot will be stored on disk
for each contrast type. The filename follows the Pattern prefix +
contrast.
Parameters
----------
start: Int which defines the start frame for the description
end: Int which defines the end frame for the description (0 defines
the unknown end frame)
Returns
-------
Dictionary: Dictionary which contains summarizing statistics The
Dictionary keys carry the names of the type of
summarization. For each contrast it contains: min, max,
mean, median, 25, 75, standard deviation, variance. And for
each of this values the same set of values are computed.
ToDo
----
- outsource summary/feature loop to function which can be accessed
by the view class
- pickle view data
"""
# set properties of the current function call
self._frames.start = start
self._frames.end = end
prefix = self._frames.prefix
if not(desc):
desc = 'Frame ' + str(start) + ' bis ' + str(end)
# Summary Dictionary
title = prefix[:-1]
summary = {title: {}}
# available contrasts
contrasts = ['saturation', 'light_dark']
# compute all available statistics for each contrast
for ctrst in contrasts:
summary[title][ctrst] = {}
# compute multivariatee contrast representation
multivariate = views.MultivariateSequence(self._frames)
multivariate.populate(ctrst=ctrst, frm_stp=stp)
# TODO: pickle instance instead of just deleating it!
# plot multivariate view
vis = visuals.MultivariatePlot(multivariate)
vis.plot(multivariate)
header = prefix[:-1] + ' MultivariatePlot for ' + ctrst + ' - ' + desc
filename = prefix + 'multivariateplot_' + ctrst + '_' + desc
vis.saveplt(fname=filename, title=header)
# compute summarizations for current contrast
univariate = views.UnivariateSequence(self._frames)
# TODO Workaround, becaus frm_stp is not part of Frames classbut
# view class so when I instantiate vis below it defaults to the
# __init__ value 10 and not the value set by the call of describe.
# This leads to a matplotlib error
univariate._frame_step = stp
# instantiate plot for all univariate summarizations
vis = visuals.UnivariatePlot(univariate)
# summarizing methods of univariate class
summarizations = ['seqmean', 'seqmad', 'seqvar'] # TODO Varianz funktioniert so nicht
for feature in summarizations:
# compute summarizations for given univariate value
getattr(univariate, feature)(ctrst=ctrst, frm_stp=stp)
# TODO Pickle current instance state
# describe current feature by summarizing statistics
summary[title][ctrst][feature[3:]] = {
'minv': int(univariate.min()),
'maxv': int(univariate.max()),
'mean': int(univariate.mean()),
'median': int(np.median(univariate)),
'perc25': int(np.percentile(univariate, 25)),
'perc75': int(np.percentile(univariate, 75)),
'std': int(univariate.std()),
'var': int(univariate.var())
}
# plot current summarization current univariate contrast plot
vis.plot(univariate)
# save univariate plot
header = prefix[:-1] + ' UnivariatePlot for ' + ctrst + ' - ' + desc
filename = self._frames.prefix + 'univariateplot_' + ctrst + '_' + desc
vis.saveplt(fname=filename, title=header)
return summary
class Frames(object):
# TODO getters und setters für start und end setzen
# TODO frm_stp sollte definitiv Teil der Frames Klasse werden
"""Parses movie frames properties"""
def __init__(self, folder, prefix, start=1, end=0):
self.folder = folder
......
......@@ -456,3 +456,89 @@ class UnivariateSequence(View):
self.resize(shape, refcheck=False)
self[:] = contrast_points
contrast_points = None
def seqper(self, ctrst='light_dark',
method='luminance', perc=50, frm_stp=10, bins=256):
"""Creates a scatterplot for the dynamic of contrast across movie frames
frm_fld: path to folder with movie images
frm_pref: file nave in fron of the count value
frm_step: take every x frame
channel: channel in the HSV color space
save: save plot also to disk
"""
# set class properties
self.feature = 'percentile ' + str(perc)
self._contrast = ctrst
self._method = method
self._frame_step = frm_stp
self._bins = bins
# TODO um start und end in der Methode zu parametrisieren müssen erst
# getters und setters in movie.frames definiert werden
# self._frames.start = start
# self._frames.end = end
contrast_points = np.empty((0), dtype=np.uint32)
# pwd list sollte in Frames sein und hier nur durchlaufen werden
for frm_nr in range(self._frames.start, self._frames.end,
self._frame_step):
pwd = self._frames.folder + self._frames.prefix + str(frm_nr) + '.png'
img = cv2.imread(pwd)
ctrst_cls = self._get_ctrst_cls_name(self._contrast)
ctrst_img = ctrst_cls(img).ctrst
percentile = np.percentile(ctrst_img.flatten(), perc)
contrast_points = np.hstack((contrast_points,
percentile))
contrast_points = np.asarray(contrast_points, np.uint32)
shape = contrast_points.shape
self.resize(shape, refcheck=False)
self[:] = contrast_points
contrast_points = None
def seqvar(self, ctrst='light_dark',
method='luminance', perc=50, frm_stp=10, bins=256):
"""Creates a scatterplot for the dynamic of contrast across movie frames
frm_fld: path to folder with movie images
frm_pref: file nave in fron of the count value
frm_step: take every x frame
channel: channel in the HSV color space
save: save plot also to disk
"""
# set class properties
self.feature = 'variance'
self._contrast = ctrst
self._method = method
self._frame_step = frm_stp
self._bins = bins
# TODO um start und end in der Methode zu parametrisieren müssen erst
# getters und setters in movie.frames definiert werden
# self._frames.start = start
# self._frames.end = end
contrast_points = np.empty((0), dtype=np.uint32)
# pwd list sollte in Frames sein und hier nur durchlaufen werden
for frm_nr in range(self._frames.start, self._frames.end,
self._frame_step):
pwd = self._frames.folder + self._frames.prefix + str(frm_nr) + '.png'
img = cv2.imread(pwd)
ctrst_cls = self._get_ctrst_cls_name(self._contrast)
ctrst_img = ctrst_cls(img).ctrst
variance = np.var(ctrst_img.flatten())
contrast_points = np.hstack((contrast_points,
variance))
contrast_points = np.asarray(contrast_points, np.uint32)
shape = contrast_points.shape
self.resize(shape, refcheck=False)
self[:] = contrast_points
contrast_points = None
......@@ -85,8 +85,8 @@ class SequencePlot(object):
class MultivariatePlot(SequencePlot):
"""Scatterplot that shows n features per frame"""
def __init__(self):
super(MultivariatePlot, self).__init__()
def __init__(self, view):
super(MultivariatePlot, self).__init__(view)
self.fig = plt.figure()
self._ax = plt.axes()
......
......@@ -9,9 +9,9 @@ cont = UnivariateSequence(movie._frames,)
cont.seqmean(frm_stp=3, ctrst='saturation')
viz = UnivariatePlot(cont)
viz.plot(cont, mark_gt=140)
cont.seqmad(frm_stp=3, ctrst='saturation')
cont.seqper(frm_stp=3, ctrst='saturation', perc=50)
viz.plot(cont)
viz.saveplt()
viz.saveplt('Percentile Test')
# viz = MultivariatePlot()
# fig, ax = viz.plot(cont)
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