Bibliothek für programmatische Videobearbeitung

Ich möchte ein Skript schreiben, das die folgende Aufgabe ausführt: Lesen Sie eine Reihe von Videos, bestimmen Sie einen gemeinsamen Teil der Frames, die in allen vorkommen, und löschen Sie dann diesen gemeinsamen Teil aus jedem Video.

Welche Bibliotheken bieten diese Art von Funktionalität zum Bearbeiten von Videos und Bildern (entweder eng aufeinander abgestimmte Funktionalitäten oder Low-Level-Blöcke, die ich verwenden kann)? Ich bin damit einverstanden, dass die Bibliothek in jeder Sprache verfügbar ist.

Welche Art von Video soll es lesen?
Ich werde überrascht sein, wenn eine solche Bibliothek hinsichtlich der Formate begrenzt sein wird. Aber im schlimmsten Fall, wenn die Funktionalitäten nur für 1 Format verfügbar sind, kann ich andere Tools verwenden, um zwischen den Formaten hin und her zu konvertieren.

Antworten (2)

Das am häufigsten verwendete Tool/Bibliothek für die Videobearbeitung ist FFMPEG - Es kann fast jedes Videoformat lesen, schneiden, würfeln und schreiben, das es gibt, und es ist kostenlos, kostenlos, Open Source und plattformübergreifend.

All diese Leistung hat ihren Preis in der Benutzerfreundlichkeit, daher gibt es viele Projekte, die die Dinge zusammenfassen, um sie ein wenig vorzeigbarer zu machen - einer meiner Favoriten ist MoviePy - auch kostenlos und plattformübergreifend und einen Blick wert, der das Schneiden erheblich vereinfachen kann und Spleißen Ihrer Dateien.

Das große Problem besteht darin, die "identischen" Blöcke in jeder Datei zu erkennen. Dies ist ein Problem, da sie aufgrund von Codierung und Komprimierung zwar für Sie identisch aussehen, für den Computer jedoch nicht identisch sind. Was uns zu Computer Vision führt, da Sie in den Dateien nach visuell ähnlichen Blöcken suchen müssen.

Das Tool der Wahl für die Bilderkennung ist OpenCV , ebenfalls kostenlos, kostenlos, Open Source und plattformübergreifend, und es gibt Tausende von Büchern, Artikeln und Artikeln darüber, wie man es verwendet. Es ist hauptsächlich C++, aber es gibt Python und andere Bindungen.

Es wäre viel zu viel zu beschreiben, wie Sie in mehreren Dateien nach visuell ähnlichen Blöcken suchen müssten, aber der Prozess besteht darin, in einem bestimmten Intervall durch jeden Film einen monochromen Fingerabdruck mit niedriger Auflösung zu extrahieren und diese dann zu vergleichen und zu verfeinern Ergebnisse mit mehreren Durchgängen.

Sie können davon ausgehen, dass Ihr Computer viel Zeit damit verbringt, nach den "identischen" Blöcken zu suchen, es sei denn, Sie können ihm einen oder zwei Hinweise geben - wenn Sie, wie ich vermute, versuchen, die Werbung aus einer Reihe von aufgezeichneten Videos zu entfernen Air, dann können Sie normalerweise bei jedem Sender Ihre Uhr darauf einstellen, wann die Werbung ausgestrahlt wird - auch viele Sender verwenden einen Cue-Block in der oberen rechten Ecke des Bildschirms, wenn die Werbung beginnt. Beides kann nützlich sein, um die Suche einzugrenzen.

Wenn Sie wirklich Glück haben oder Ihr Filmmaterial noch nicht aufgenommen haben, haben Sie die Untertitelspur auf jeder - das kann die Dinge wirklich beschleunigen, da das Durchsuchen von Text nach identischen Mustern viel schneller ist als das Durchsuchen von Frames nach Ähnlichkeiten - VideoGrep ist ein Python-Skript, das verwendet die Untertitelspur, um Filmclips zu extrahieren, die den Anforderungen entsprechen, und ist wahrscheinlich ein sehr guter Ausgangspunkt.

Wenn Sie bei der Auswahl von Videosegmenten über den Tellerrand schauen möchten, erhalten Sie möglicherweise auch einige Ideen von diesem MoviePy-Skript, das die interessanten Teile eines Fußballspiels basierend auf dem Lärm der Menge auswählt und zusammenfügt.

Besonders für Streaming-Inhalte, wenn Ihr vorgeschlagenes Tool die Keyframes leicht erfassen kann, würde Ihre Rechenlast meines Erachtens sinken, da bereits viele Vorberechnungen in den Komprimierungsmethoden stattgefunden haben.

Sie können sich das LEADTOOLS Multimedia SDK ansehen, um diese Art von Aufgabe zu implementieren. Es unterstützt C, C++, .NET und funktioniert mit anderen Sprachen, die COM-Objekte unterstützen. Dieses SDK unterstützt das Dekomprimieren von Videodateien und bietet einen Video-Callback-Filter, um die einzelnen Frames für eine benutzerdefinierte Bildverarbeitung zu erhalten. Dies würde es Ihnen ermöglichen, denselben Algorithmus für die Verarbeitung zu verwenden, ohne dass Sie speziellen Code benötigen, um unterschiedliche Dateiformate zu verarbeiten. Wenn die Dateien, die Sie verarbeiten, MPEG-2- oder H.264-Komprimierung verwenden, können Sie auch die (native) Hardware-Dekomprimierung verwenden, um einen Teil der Arbeit auf die GPU zu verlagern.

Hier ist ein Forumsbeitrag in den LEADTOOLS Support-Foren, der ein Beispielprojekt enthält, das die Verwendung des Video-Rückrufs veranschaulicht: HOW TO: OCR Video using the callback filter

Ein wichtiger Teil dieses Forumsbeitrags ist das Hinzufügen des Videorückrufs. Hier ist der entsprechende Code, wie das geht:

Processor videoCallback = playctrl.VideoProcessors.Callback;
playctrl.SelectedVideoProcessors.Add(videoCallback);
lmvCallback = (LMVCallback)playctrl.GetSubObject(PlayObject.SelVideoProcessor);
lmvMyUserCallback = new LMVMyUserCallback();
lmvCallback.ReceiveProcObj = lmvMyUserCallback;

Der andere wichtige Teil dieser Demo ist die Implementierung der ReceivePro()-Methode, da dies die aufgerufene Callback-Funktion ist. Der zu beachtende Code ist folgender:

public void ReceiveProc(int pData, int lWidth, int lHeight, int lBitCount, int lSize, int bTopDown)
{
   try
   {
      if (m_bSnapshot)
      {
         // Get the background image
         RasterViewPerspective viewPerspective;
         if (bTopDown == 1)
            viewPerspective = RasterViewPerspective.TopLeft;
         else
            viewPerspective = RasterViewPerspective.BottomLeft;

         RasterImage img = new RasterImage(
            RasterMemoryFlags.User, //A combination of the RasterMemoryFlags enumeration members indicating the type of memory to allocate for the image data.
            lWidth, // Width of the image in pixels.
            lHeight, //Height of the image in pixels.
            lBitCount, //The number of bits per pixel.
            RasterByteOrder.Bgr, //Color order for 16-, 24-, 32-, 48- and 64-bit images.
            viewPerspective, //Specifies where the beginning of the image is stored.
            null, //The palette that the image will use. You can specify your own palette, or use null (Nothing in Visual Basic) for LEAD's fixed palette. The palette member is used only when bitsPerPixel is less than or equal to 8.
            IntPtr.Zero, //Unmanaged data pointer that will contain the image data when flags is RasterMemoryFlags.User.
            0); //Length in bytes of the data passed to userData. Only when used when userData is not IntPtr.Zero and flags is RasterMemoryFlags.User.

         img.SetUserData(new IntPtr(pData), lSize);

Wie dieses Projekt auch zeigt, können Sie Funktionen aus dem LEADTOOLS Recognition Imaging SDK verwenden, wenn die gängigen Frames, nach denen Sie suchen, Text enthalten. Dieses SDK enthält auch die Bildverarbeitungsklasse CorrelationCommand , die darauf ausgelegt ist, bestimmte Bilddaten in einem anderen Bild zu finden. Hier ist ein Beispielcode, der veranschaulicht, wie Sie diese Methode einrichten und ausführen würden:

RasterCodecs codecs = new RasterCodecs();
// Prepare the command
RasterImage DstImage = codecs.Load("source.png");
CorrelationCommand command = new CorrelationCommand();
command.CorrelationImage = DstImage;
command.Threshold = 70;
command.XStep = 1;
command.YStep = 1;
command.Points = new LeadPoint[90];
//Apply the correlation filter.
command.Run(img);

Mit Zugriff auf jeden Frame im Videostream können Sie jede Art von Bildverarbeitung durchführen, die Sie für den Frame durchführen möchten.

Haftungsausschluss: Ich bin ein Mitarbeiter des Unternehmens, das diese Bibliothek geschrieben hat.