mirror of
https://github.com/n00mkrad/flowframes.git
synced 2025-12-19 01:39:26 +01:00
78 lines
3.1 KiB
C#
78 lines
3.1 KiB
C#
|
|
using Flowframes.IO;
|
|||
|
|
using ImageMagick;
|
|||
|
|
using System;
|
|||
|
|
using System.Collections.Generic;
|
|||
|
|
using System.Drawing;
|
|||
|
|
using System.IO;
|
|||
|
|
using System.Linq;
|
|||
|
|
using System.Text;
|
|||
|
|
using System.Threading.Tasks;
|
|||
|
|
|
|||
|
|
namespace Flowframes.Magick
|
|||
|
|
{
|
|||
|
|
class SceneDetect
|
|||
|
|
{
|
|||
|
|
public static async Task RunSceneDetection (string path)
|
|||
|
|
{
|
|||
|
|
string outFolder = path + "-analyzed";
|
|||
|
|
Directory.CreateDirectory(outFolder);
|
|||
|
|
string ext = "png";
|
|||
|
|
FileInfo[] frames = IOUtils.GetFileInfosSorted(path, false, "*." + ext);
|
|||
|
|
|
|||
|
|
Logger.Log("frames count = " + frames.Length);
|
|||
|
|
|
|||
|
|
for (int i = 1; i < frames.Length; i++)
|
|||
|
|
{
|
|||
|
|
FileInfo frame = frames[i];
|
|||
|
|
FileInfo lastFrame = frames[i - 1];
|
|||
|
|
Task.Run(() => ProcessFrame(frame, lastFrame, outFolder));
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
static async Task ProcessFrame (FileInfo frame, FileInfo lastFrame, string outFolder)
|
|||
|
|
{
|
|||
|
|
MagickImage prevFrame = new MagickImage(lastFrame.FullName);
|
|||
|
|
MagickImage currFrame = new MagickImage(frame.FullName);
|
|||
|
|
|
|||
|
|
Size originalSize = new Size(currFrame.Width, currFrame.Height);
|
|||
|
|
int downscaleHeight = 144;
|
|||
|
|
prevFrame.Scale(currFrame.Width / (currFrame.Height / downscaleHeight), downscaleHeight);
|
|||
|
|
currFrame.Scale(currFrame.Width / (currFrame.Height / downscaleHeight), downscaleHeight);
|
|||
|
|
|
|||
|
|
double errNormalizedCrossCorrelation = currFrame.Compare(prevFrame, ErrorMetric.NormalizedCrossCorrelation);
|
|||
|
|
double errRootMeanSquared = currFrame.Compare(prevFrame, ErrorMetric.RootMeanSquared);
|
|||
|
|
|
|||
|
|
string str = $"Metrics of {frame.Name.Split('.')[0]} against {lastFrame.Name.Split('.')[0]}:\n";
|
|||
|
|
str += $"NormalizedCrossCorrelation: {errNormalizedCrossCorrelation.ToString("0.000")}\n";
|
|||
|
|
str += $"RootMeanSquared: {errRootMeanSquared.ToString("0.000")}\n";
|
|||
|
|
str += "\n\n";
|
|||
|
|
bool nccTrigger = errNormalizedCrossCorrelation < 0.45f;
|
|||
|
|
bool rMeanSqrTrigger = errRootMeanSquared > 0.18f;
|
|||
|
|
bool rmsNccTrigger = errRootMeanSquared > 0.18f && errNormalizedCrossCorrelation < 0.6f;
|
|||
|
|
bool nccRmsTrigger = errNormalizedCrossCorrelation < 0.45f && errRootMeanSquared > 0.11f;
|
|||
|
|
|
|||
|
|
// if (nccTrigger) str += "\nNCC SCENE CHANGE TRIGGER!";
|
|||
|
|
// if (rMeanSqrTrigger) str += "\nROOTMEANSQR SCENE CHANGE TRIGGER!";
|
|||
|
|
if (rmsNccTrigger) str += "\n\nRMS -> NCC DOUBLE SCENE CHANGE TRIGGER!";
|
|||
|
|
if (nccRmsTrigger) str += "\n\nNCC -> RMS DOUBLE SCENE CHANGE TRIGGER!";
|
|||
|
|
|
|||
|
|
currFrame.Scale(originalSize.Width / 2, originalSize.Height / 2);
|
|||
|
|
|
|||
|
|
new Drawables()
|
|||
|
|
.FontPointSize(12)
|
|||
|
|
.Font("Consolas", FontStyleType.Normal, FontWeight.Bold, FontStretch.Normal)
|
|||
|
|
.FillColor(MagickColors.Red)
|
|||
|
|
.TextAlignment(TextAlignment.Left)
|
|||
|
|
.Text(1, 10, str)
|
|||
|
|
.Draw(currFrame);
|
|||
|
|
|
|||
|
|
currFrame.Write(Path.Combine(outFolder, frame.Name));
|
|||
|
|
|
|||
|
|
prevFrame.Dispose();
|
|||
|
|
currFrame.Dispose();
|
|||
|
|
|
|||
|
|
await Task.Delay(1);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|