diff --git a/butterflow-ui/FlowFilterType.cs b/butterflow-ui/FlowFilterType.cs new file mode 100644 index 0000000..2d125b0 --- /dev/null +++ b/butterflow-ui/FlowFilterType.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace butterflow_ui +{ + /// Values that represent a flow filter type used for optical flow calculations. + [Serializable] + public enum FlowFilterType + { + /// Box. + box, + /// Guassian. + guassian + } +} diff --git a/butterflow-ui/Localization/Localization.Designer.cs b/butterflow-ui/Localization/Localization.Designer.cs index db8c665..afd0955 100644 --- a/butterflow-ui/Localization/Localization.Designer.cs +++ b/butterflow-ui/Localization/Localization.Designer.cs @@ -249,6 +249,24 @@ namespace butterflow_ui.Localization { } } + /// + /// Looks up a localized string similar to Flow Filter. + /// + public static string FlowFilterLabel { + get { + return ResourceManager.GetString("FlowFilterLabel", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Filter used for optical flow estimation.. + /// + public static string FlowFilterTooltip { + get { + return ResourceManager.GetString("FlowFilterTooltip", resourceCulture); + } + } + /// /// Looks up a localized string similar to Height. /// @@ -303,6 +321,24 @@ namespace butterflow_ui.Localization { } } + /// + /// Looks up a localized string similar to Keep Subregions. + /// + public static string KeepSubregionsLabel { + get { + return ResourceManager.GetString("KeepSubregionsLabel", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Renders subregions not explicitly specified.. + /// + public static string KeepSubregionsTooltip { + get { + return ResourceManager.GetString("KeepSubregionsTooltip", resourceCulture); + } + } + /// /// Looks up a localized string similar to Levels. /// diff --git a/butterflow-ui/Localization/Localization.resx b/butterflow-ui/Localization/Localization.resx index ebf53cf..8fe7f88 100644 --- a/butterflow-ui/Localization/Localization.resx +++ b/butterflow-ui/Localization/Localization.resx @@ -240,12 +240,24 @@ + + Flow Filter + + + Filter used for optical flow estimation. + Pyramid iterations The number of iterations to use for each pyramid layer. + + Keep Subregions + + + Renders subregions not explicitly specified. + Levels diff --git a/butterflow-ui/MainWindow.xaml b/butterflow-ui/MainWindow.xaml index 0338a63..364caf6 100644 --- a/butterflow-ui/MainWindow.xaml +++ b/butterflow-ui/MainWindow.xaml @@ -11,12 +11,18 @@ x:Name="butterflowUIWindow" Title="{x:Static loc:Localization.Title}" Height="600" Width="800"> - + + + + + @@ -109,7 +115,7 @@ - + @@ -157,7 +163,18 @@ - + + + + + @@ -176,7 +193,7 @@ - + @@ -185,6 +202,9 @@ + + + @@ -195,19 +215,22 @@ - + - + - + - + - + + + + diff --git a/butterflow-ui/MainWindow.xaml.cs b/butterflow-ui/MainWindow.xaml.cs index c53b523..158d752 100644 --- a/butterflow-ui/MainWindow.xaml.cs +++ b/butterflow-ui/MainWindow.xaml.cs @@ -47,6 +47,39 @@ namespace butterflow_ui InitializeComponent(); } + #region Methods + + /// Gets the recursive children of a element that are of type . + /// Generic type parameter. + /// The parent element. + /// + /// An enumerator that allows foreach to be used to process the recursive childrens in this + /// collection. + /// + private IEnumerable GetRecursiveChildren(object parent) where T : DependencyObject + { + if (parent is DependencyObject) + { + var list = new List(); + + foreach (var child in LogicalTreeHelper.GetChildren((DependencyObject)parent)) + { + if (child is DependencyObject) + { + if (child is T) + { + list.Add((T)child); + } + list.AddRange(GetRecursiveChildren((DependencyObject)child)); + } + } + + return list; + } + + return Enumerable.Empty(); + } + /// Butterflow wrapper parsed console output recieved. /// Source of the event. /// The ButterflowOutputArgs to process. @@ -234,5 +267,21 @@ namespace butterflow_ui } } } + + /// Event handler. Called by TextBox for got focus events. + /// Source of the event. + /// Routed event information. + private void TextBox_GotFocus(object sender, RoutedEventArgs e) + { + //Clear all the radio buttons because we got focus from the user in the playbackrate textbox. + var playbackRateRadioButtons = GetRecursiveChildren(this.butterflowUIWindow); + + foreach(var radioButton in playbackRateRadioButtons) + { + radioButton.IsChecked = false; + } + } + + #endregion } } diff --git a/butterflow-ui/OptionsConfiguration.cs b/butterflow-ui/OptionsConfiguration.cs index 4932c43..e52fb37 100644 --- a/butterflow-ui/OptionsConfiguration.cs +++ b/butterflow-ui/OptionsConfiguration.cs @@ -16,6 +16,14 @@ namespace butterflow_ui { #region Members + private const decimal DEFAULT_PYRAMID_SCALE = 0.5m; + private const int DEFAULT_LEVELS = 3; + private const int DEFAULT_WINDOW_SIZE = 25; + private const int DEFAULT_ITERATIONS = 3; + private const int DEFAULT_PIXEL_NEIGHBORHOOD = 5; + private const decimal DEFAULT_SMOOTH_DERIVATIVE_STANDARD_DEVIATION = 1.1m; + private const FlowFilterType DEFAULT_FLOW_FILTER_TYPE = FlowFilterType.box; + /// An interpreter used to ensure numeric input is correctly calculated. private InputInterpreter interpreter = new InputInterpreter(); /// The aspect ratio used for calculating heights when the aspect ratio is locked. @@ -25,7 +33,7 @@ namespace butterflow_ui private bool keepAudio; private int width; private int height; - private bool keepAspectRatio; + private bool keepSubRegions; private bool losslessQuality; private bool smoothMotion; private bool lockAspectRatio; @@ -38,6 +46,7 @@ namespace butterflow_ui private int iterations; private int pixelNeighborhood; private decimal smoothDerivativeStandardDeviation; + private FlowFilterType flowFilterType = FlowFilterType.box; private ObservableCollection subregions = new ObservableCollection(); #endregion @@ -109,7 +118,7 @@ namespace butterflow_ui } set { - if (value) + if (value && this.width != 0 && this.height != 0) { this.aspectRatio = Convert.ToDecimal(this.height) / Convert.ToDecimal(this.width); } @@ -162,17 +171,17 @@ namespace butterflow_ui } } - /// Gets or sets a value indicating whether the keep aspect ratio of the input video file for the output video file. - /// True if keep aspect ratio, false if not. - public bool KeepAspectRatio + /// Gets or sets a value indicating whether the keep subregions that are not explicitly specified. + /// True if keeping subregions not explicitly specified, false if not. + public bool KeepSubregions { get { - return this.keepAspectRatio; + return this.keepSubRegions; } set { - this.keepAspectRatio = value; + this.keepSubRegions = value; OnPropertyChanged(); } } @@ -312,7 +321,13 @@ namespace butterflow_ui set { interpreter.Interpret(value); - this.pixelNeighborhood = interpreter.Int; + + // Per butterflow's documentation, the valid range for --poly-n is {5,7} + if (interpreter.Int >= 5 || interpreter.Int <= 7) + { + this.pixelNeighborhood = interpreter.Int; + } + OnPropertyChanged(); } } @@ -333,6 +348,21 @@ namespace butterflow_ui } } + /// Gets or sets the type of the flow filter used for optical flow calculations. + /// The type of the flow filter used for optical flow calculations. + public FlowFilterType FlowFilterType + { + get + { + return this.flowFilterType; + } + set + { + this.flowFilterType = value; + OnPropertyChanged(); + } + } + /// Gets or sets the subregions of the video on which to work. /// The subregions of the video. public ObservableCollection Subregions @@ -355,12 +385,24 @@ namespace butterflow_ui /// Default constructor. public OptionsConfiguration() { + // Set default values + this.pyramidScale = DEFAULT_PYRAMID_SCALE; + this.levels = DEFAULT_LEVELS; + this.windowSize = DEFAULT_WINDOW_SIZE; + this.iterations = DEFAULT_ITERATIONS; + this.pixelNeighborhood = DEFAULT_PIXEL_NEIGHBORHOOD; + this.smoothDerivativeStandardDeviation = DEFAULT_SMOOTH_DERIVATIVE_STANDARD_DEVIATION; + this.flowFilterType = DEFAULT_FLOW_FILTER_TYPE; + AddConstantCallProperty("CommandLineOutput"); - this.subregions.CollectionChanged += SubregionsCollectionChanged; + this.subregions.CollectionChanged += Subregions_CollectionChanged; ; } - private void SubregionsCollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) + /// Event handler. Called by Subregions for collection changed events. + /// Source of the event. + /// Notify collection changed event information. + private void Subregions_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) { if (e.NewItems != null) { @@ -393,9 +435,9 @@ namespace butterflow_ui /// This object as a string. public string ToButterflowArguments() { - var stringBuilder = new StringBuilder("-v "); //Verbose + var stringBuilder = new StringBuilder("-v "); // Verbose - if (this.KeepAspectRatio) + if (this.LockAspectRatio) { stringBuilder.AppendFormat("-vs {0}:-1 ", this.Width); } @@ -435,6 +477,17 @@ namespace butterflow_ui stringBuilder.Append(" "); } + if (this.KeepSubregions) stringBuilder.Append("-k "); + if (this.SmoothMotion) stringBuilder.Append("-sm "); + if (this.FastPyramid) stringBuilder.Append("--fast-pyr "); + if (this.pyramidScale != DEFAULT_PYRAMID_SCALE) stringBuilder.AppendFormat("--pyr-scale {0} ", this.PyramidScale); + if (this.levels != DEFAULT_LEVELS) stringBuilder.AppendFormat("--levels {0} ", this.Levels); + if (this.windowSize != DEFAULT_WINDOW_SIZE) stringBuilder.AppendFormat("--winsize {0} ", this.WindowSize); + if (this.iterations != DEFAULT_ITERATIONS) stringBuilder.AppendFormat("--iters {0} ", this.Iterations); + if (this.pixelNeighborhood != DEFAULT_PIXEL_NEIGHBORHOOD) stringBuilder.AppendFormat("--poly-n {0} ", this.PixelNeighborhood); + if (this.smoothDerivativeStandardDeviation != DEFAULT_SMOOTH_DERIVATIVE_STANDARD_DEVIATION) stringBuilder.AppendFormat("--poly-s {0} ", this.SmoothDerivativeStandardDeviation); + if (this.FlowFilterType != DEFAULT_FLOW_FILTER_TYPE) stringBuilder.AppendFormat("-ff {0} ", this.FlowFilterType); + return stringBuilder.ToString(); } diff --git a/butterflow-ui/RegionType.cs b/butterflow-ui/RegionType.cs index 97363e0..6515cfe 100644 --- a/butterflow-ui/RegionType.cs +++ b/butterflow-ui/RegionType.cs @@ -7,6 +7,7 @@ using System.Threading.Tasks; namespace butterflow_ui { /// Values that represent subregion types. + [Serializable] public enum RegionType { /// Speed. diff --git a/butterflow-ui/butterflow-ui.csproj b/butterflow-ui/butterflow-ui.csproj index b88aa9b..cc232c0 100644 --- a/butterflow-ui/butterflow-ui.csproj +++ b/butterflow-ui/butterflow-ui.csproj @@ -60,6 +60,7 @@ MSBuild:Compile Designer +