Permalink
Browse files

added autotag feature. pretty print times. code organization. wmvs no…

…t written as mkvs anymore.
  • Loading branch information...
1 parent 5108e9f commit 104dc40857e4d0e84d7e4f7adf3ba013b463b829 @ryanjay0 committed Nov 16, 2016
Showing with 367 additions and 144 deletions.
  1. +24 −3 README.md
  2. +153 −119 cut_movie.cpp
  3. +17 −3 cut_movie.hpp
  4. +46 −19 miles-deep.cpp
  5. +102 −0 util.cpp
  6. +25 −0 util.hpp
View
@@ -51,23 +51,23 @@ I'm working on a version for Windows. Sorry, I don't have a Mac but it should ru
##Usage
Example:
-```shell
+```bash
miles-deep -t sex_back,sex_front movie.mp4
```
This finds the scenes sex from the back or front and outputs the result
in `movie.cut.avi`
Example:
-```shell
+```bash
miles-deep -x movie.avi
```
This edits out all the non-sexual scenes from `movie.avi`
and outputs the result in `movie.cut.avi`.
Example:
-```
+```bash
miles-deep -b 16 -t cunnilingus -o /cut_movies movie.mkv
```
@@ -93,6 +93,27 @@ Tested on an Nvidia GTX 960 with 4GB VRAM and a 24.5 minute video file. At batch
In addition to batching, Miles Deep also uses threading, which allows the screenshots to be captured and processed while they are classified.
+###Auto-Tagging Without Cutting
+
+Example:
+```bash
+miles-deep movie.mp4 -a
+```
+
+By popular demand I added this option, which outputs `movie.tag`:
+
+```
+movie_name, label_1, ..., label_n
+total_time, label_1_time, ..., label_n_time
+label, start, end, score, coverage
+.
+.
+.
+
+```
+
+The file contains the cuts for each target, ordered as they occur in the movie. The first lines give the movie name, the labels, the total movie time, and the total seconds for each label. Then for each cut it list the start time, end time, average score, and coverage. Because of the threshold and the gaps, these cuts may overlap and aren't guaranteed to cover ever second.
+
###Prediction Weights
Here is an example of the predictions for each second of a video:
View
@@ -13,77 +13,173 @@
#include <string>
#include "cut_movie.hpp"
+#include "util.hpp"
using namespace std;
-float scoreMax(vector<float> x)
+//find the cuts using the winners and their values (returns the cut_list)
+int findTheCuts(int score_list_size, const vector<int>& winners,const vector<float>& vals,
+ const vector<int>& target_on, string target, int min_cut, int max_gap, float threshold, float min_coverage,
+ CutList* cut_list)
{
- return *max_element(x.begin(), x.end());
-}
-int scoreArgMax(vector<float> x)
-{
- return distance(x.begin(), max_element(x.begin(), x.end()));
+ int cut_start = -1;
+ int gap = 0;
+ int win_sum = 0;
+ float val_sum = 0.0;
+ int total_size = 0;
+
+ for( int i=0; i<score_list_size; i++)
+ {
+ if( cut_start >= 0 )
+ {
+ if( target_on[winners[i]] )
+ {
+ win_sum++;
+ val_sum += vals[i];
+ }
+
+ if( !target_on[winners[i]] || vals[i] < threshold || i == score_list_size-1 )
+ {
+ if(i < score_list_size-1) gap++;
+
+ if( gap > max_gap || i == score_list_size-1 )
+ {
+ if( cut_start < i - gap - min_cut )
+ {
+ //output cut
+ int win_size = (i - gap) - cut_start + 1;
+ float score_avg = val_sum / (float)win_sum;
+ float coverage = (float)win_sum / (float)win_size;
+
+ if(coverage >= min_coverage)
+ {
+ cout << PrettyTime(cut_start) << " - " << PrettyTime(i - gap)
+ << ": size= " << PrettyTime(win_size) << " coverage= " << coverage
+ << " score= " << score_avg << '\n';
+ total_size += win_size;
+ Cut cut;
+ cut.s = cut_start;
+ cut.e = i-gap;
+ cut.score = score_avg;
+ cut.coverage = coverage;
+ cut.label = target;
+ cut_list->push_back(cut);
+ }
+ }
+ cut_start = -1;
+ gap = 0;
+ val_sum = 0.0;
+ win_sum = 0;
+ }
+ }
+ else
+ {
+ gap = 0;
+ }
+
+ }
+ else if( target_on[winners[i]] && vals[i] >= threshold )
+ {
+ cut_start = i;
+ gap = 0;
+ val_sum = 0.0;
+ win_sum = 0.0;
+ }
+ }
+
+ return(total_size);
+
}
-string getFileName(const string& s)
-{
- char sep = '/';
+void TagTargets( ScoreList score_list, string movie_file, string output_dir,
+ vector<string> labels, int total_targets, int min_cut, int max_gap,
+ float threshold, float min_coverage)
+{
+ //path stuff with movie file
+ char sep = '/';
#ifdef _WIN32
- sep = '\\';
+ char sep = '\\';
#endif
+ string movie_base = getBaseName(getFileName(movie_file));
+ string movie_directory = getDirectory(movie_file);
+ string tag_movie = movie_base + ".tag";
+ if(output_dir == "")
+ output_dir = movie_directory;
+ string tag_path = output_dir + sep + tag_movie;
- size_t i = s.rfind(sep, s.length());
- if( i != string::npos)
- return(s.substr(i+1, s.length() -i));
- return(s);
-}
+ //find winners and their scores
+ vector<int> winners(score_list.size());
+ vector<float> vals(score_list.size());
+ for( int i=0; i < score_list.size(); i++ )
+ {
+ winners[i] = scoreArgMax(score_list[i]);
+ vals[i] = scoreMax(score_list[i]);
+ }
-string getFileExtension(const string& s)
-{
- char sep = '.';
+ //open tag output file
+ ofstream f(tag_path);
+ if(!f)
+ {
+ cerr << "Cannot open file: " << tag_path << endl;
+ exit(EXIT_FAILURE);
+ }
- size_t i = s.rfind(sep, s.length());
- if( i != string::npos)
- return(s.substr(i, s.length() -i));
- return(s);
-}
+ //write header
+ f << getFileName(movie_file) << ",";
+ for(int i=0; i < labels.size(); i++)
+ f << labels[i] << ",";
+ f << endl;
-string getBaseName(const string& s)
-{
- char sep = '.';
+ //find the predicted cuts for each target
+ vector<int> target_time(total_targets,0);
+ CutList cut_list;
+ for(int i=0; i < total_targets; i++)
+ {
- size_t i = s.rfind(sep, s.length());
- if( i != string::npos)
- return(s.substr(0, i));
- return(s);
-}
+ vector<int> target_on(total_targets,0);
+ target_on[i] = 1;
-bool queryYesNo()
-{
- cout << "Replace movie with cut? This will delete the movie. [y/N]?";
- string input;
- getline(cin, input);
- if( input == "YES" || input == "Yes" || input == "yes"
- || input == "Y" || input == "y")
- return true;
- else
- return false;
-}
+ cout << "Target [" << labels[i] << "]" << endl;
+
+ target_time[i] = findTheCuts(score_list.size(), winners, vals, target_on, labels[i], min_cut,
+ max_gap, threshold, min_coverage, &cut_list);
+
+
+ cout << "Total cut length: " << PrettyTime(target_time[i]) << endl;
+ cout << endl;
+
+ }
+
+ //write target total information
+ f << score_list.size() << ",";
+ for(int i=0; i< total_targets; i++)
+ f << target_time[i] << ",";
+ f << endl;
+
+ //sort the list based on cut start time
+ sort(cut_list.begin(),cut_list.end(), [](const Cut &x, const Cut &y){ return (x.s < y.s);});
+
+
+ //write cutlist to tag file
+ f << "label,start,end,score,coverage" << endl;
+ for( int j=0; j<cut_list.size(); j++)
+ {
+ Cut this_cut = cut_list[j];
+ f << this_cut.label << "," << this_cut.s << "," << this_cut.e
+ << "," << this_cut.score << "," << this_cut.coverage << endl;
+ }
+
+ cout << "Writing tag data to: " << tag_path << endl;
+ f.close();
-std::string GetDirectory (const std::string& path)
-{
- int found = path.find_last_of("/\\");
- if(found < 0)
- return(".");
- else
- return(path.substr(0, found));
}
-void cut( ScoreList score_list, string movie_file, vector<int> target_list, string output_dir, string temp_dir,
- int total_targets, int min_cut, int max_gap, float threshold, float min_coverage)
+void CutMovie( ScoreList score_list, string movie_file, vector<int> target_list,
+ string output_dir, string temp_dir, int total_targets, int min_cut, int max_gap,
+ float threshold, float min_coverage)
{
//path stuff with movie file
@@ -96,10 +192,9 @@ void cut( ScoreList score_list, string movie_file, vector<int> target_list, stri
string cut_movie = movie_base + ".cut";
string temp_base = temp_dir + sep + "cuts";
string temp_path = temp_base + sep + cut_movie;
- string movie_directory = GetDirectory(movie_file);
+ string movie_directory = getDirectory(movie_file);
//will come from input
-
vector<int> target_on(total_targets,0);
for(int i=0; i<target_list.size(); i++)
target_on[target_list[i]] = 1;
@@ -115,79 +210,22 @@ void cut( ScoreList score_list, string movie_file, vector<int> target_list, stri
//init
CutList cut_list;
- int cut_start = -1;
- int gap = 0;
- int win_sum = 0;
- float val_sum = 0.0;
bool did_concat = true;
//find winners and their scores
vector<int> winners(score_list.size());
vector<float> vals(score_list.size());
- for( int i=0; i < score_list.size(); i++ ){
+ for( int i=0; i < score_list.size(); i++ )
+ {
winners[i] = scoreArgMax(score_list[i]);
vals[i] = scoreMax(score_list[i]);
}
- //find the cuts
- for( int i=0; i<score_list.size(); i++)
- {
- if( cut_start >= 0 )
- {
- if( target_on[winners[i]] )
- {
- win_sum++;
- val_sum += vals[i];
- }
-
- if( !target_on[winners[i]] || vals[i] < threshold || i == score_list.size()-1 )
- {
- if(i < score_list.size()-1) gap++;
-
- if( gap > max_gap || i == score_list.size()-1 )
- {
- if( cut_start < i - gap - min_cut )
- {
- //output cut
- int win_size = (i - gap) - cut_start + 1;
- float score_avg = val_sum / (float)win_sum;
- float coverage = (float)win_sum / (float)win_size;
-
- if(coverage >= min_coverage)
- {
- cout << cut_start << " - " << i - gap << ": size= "
- << win_size << " coverage= " << coverage
- << " score= " << score_avg << '\n';
- Cut cut;
- cut.s = cut_start;
- cut.e = i-gap;
- cut_list.push_back(cut);
- }
- }
- cut_start = -1;
- gap = 0;
- val_sum = 0.0;
- win_sum = 0;
- }
- }
- else
- {
- gap = 0;
- }
-
- }
- else if( target_on[winners[i]] && vals[i] >= threshold )
- {
- cut_start = i;
- gap = 0;
- val_sum = 0.0;
- win_sum = 0.0;
- }
- }
-
-
+ int total = findTheCuts(score_list.size(), winners, vals, target_on,
+ "", min_cut, max_gap, threshold, min_coverage, &cut_list);
+ cout << "Total cut length: " << PrettyTime(total) << endl;
//make the cuts
if( cut_list.size() > 0 )
{
@@ -205,11 +243,7 @@ void cut( ScoreList score_list, string movie_file, vector<int> target_list, stri
//use output_seek for wmv. fixed bug where cuts would freeze
bool output_seek = false;
if(movie_type == ".wmv" || movie_type == ".WMV" || movie_type == ".Wmv")
- {
- movie_type = ".mkv";
output_seek = true;
- }
-
//output a file for each cut in the list
for( int i=0; i<cut_list.size(); i++)
Oops, something went wrong.

0 comments on commit 104dc40

Please sign in to comment.