inteligent script om kleverig.eu folder en fanart te maken voor bv kodi.

Stel hier je vragen in het Nederlands.
Je zult sneller (en misschien betere) antwoorden in de engelstalige "boards" krijgen. TIP: je kunt je "profile" ook op Nederlands instellen.
Post Reply
Richard63NL
Newbie
Newbie
Posts: 16
Joined: August 22nd, 2019, 10:32 am

inteligent script om kleverig.eu folder en fanart te maken voor bv kodi.

Post by Richard63NL »

Hallo ik heb Kodi om films af te spelen op tv (chromecast met google tv)
Nu heb ik daar vaak een breed plaatje en niet een staande dvd style hoes.
Ik heb daar een python script voor gemaakt dat computervision gebruikt.

Het kijkt naar het formaat (liggend of staand)
als je een liggend plaatje (png of jpg) laat vallen op het programma icoon in de Incompleet folder dan KIJKT het programma of er gezichten in voor komen, zo ja dan neemt hij het gevonden gezicht als midden voor de uitsnede van een staand plaatje en schrijft dat weg als folder.jpg in de LAATST gemaakte map (de film die je aan het binnen halen bent) dan kopieert hij ook het originele plaatje en noemt dat fanart.jpg.
Mochten er meerdere gezichten herkend zijn, dan opend hij de foto en een invoer veld waarop gevraagd word het juiste gezicht nummer in te voeren.
Dat is herkenbaar aan gekleurde randen om het herkende gezicht.
Bij een volledige dvd inlay zal dat bijna altijd de voorzijde van de dvd zijn (ongelijk of die links of rechts geplaatst is)

Ik ben het nog verder in functie aan het uitbreiden, maar mogelijk heeft iemand hier iets aan :-)

Stuur mij een bericht als je de laatste versie wil hebben incl de haarcascade files voor de gezichts herkenning (het zijn 3 files in totaal)
het werkt LOS van SAB

Code: Select all

import os
import sys
import cv2
import winreg as reg
from PIL import Image
import numpy as np
import tkinter as tk
from tkinter import simpledialog
import shutil

# Versie 1.8 - 25 september 2023

# Dit is een POST process script voor SABNZBD
# Het word aangeroepen door er een plaatje op te laten vallen


def crop_portrait(image_path):
    # Laad de afbeelding
    image = cv2.imread(image_path)

    # Controleer of de breedte van de afbeelding groter is dan de hoogte
    if image.shape[1] > image.shape[0]:
        # Converteer de afbeelding naar grijswaarden
        gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

        # Laad het Haar-cascade XML-bestand voor gezichtsdetectie
        cascade_path = cv2.data.haarcascades + 'haarcascade_frontalface_default.xml'
        face_cascade = cv2.CascadeClassifier(cascade_path)

        # Voer gezichtsdetectie uit
        faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=15, minSize=(100, 100)) # was 30,30

        if len(faces) == 0:
            status = "Geen gezichten gevonden in de afbeelding."
        else:
            # Beperk het aantal gedetecteerde gezichten tot maximaal 5
            if len(faces) > 5:
                faces = faces[:5]

            # Bereken het midden van elk gedetecteerd gezicht
            colors = [(0, 0, 255), (0, 255, 0), (255, 0, 0), (0, 255, 255), (255, 255, 0)]  # Rood, Groen, Blauw, Geel, Cyaan
            output_image = image.copy()
            for i, (x, y, w, h) in enumerate(faces):
                color = colors[i % len(colors)]
                cv2.rectangle(output_image, (x, y), (x + w, y + h), color, 2)
                cv2.putText(output_image, str(i+1), (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.8, color, 2)

            # Sla de afbeelding op met de gedetecteerde gezichten en hun corresponderende nummers als "temp.jpg"
            output_image = cv2.cvtColor(output_image, cv2.COLOR_BGR2RGB)
            pil_output_image = Image.fromarray(output_image)
            pil_output_image.save("temp.jpg", format='JPEG')


            if len(faces) == 1:
                # Als er slechts één gezicht is, gebruik het dan direct voor bijsnijden
                x, y, w, h = faces[0]
            else:
                os.system("temp.jpg") # Hier word het plaatje geopend im een viewer (systeem standaard viewer)
                # Als er meerdere gezichten zijn, vraag de gebruiker om er een te kiezen

                root = tk.Tk()
                root.withdraw()
                choice = simpledialog.askinteger("Kies een gezicht", "Meerdere gezichten gedetecteerd. Kies een gezicht om te gebruiken voor de DVD-hoes:", minvalue=1, maxvalue=len(faces), parent=root)
                root.destroy()
                os.remove("temp.jpg")
                
                if choice is None:
                    # Gebruiker heeft het dialoogvenster gesloten, gebruik het eerste gezicht standaard
                    x, y, w, h = faces[0]
                    os.remove("temp.jpg")
                else:
                    x, y, w, h = faces[choice - 1]

            # Bereken het midden van het geselecteerde gezicht
            center_x = x + w // 2
            center_y = y + h // 2

            # Bereken de gewenste hoogte voor de DVD-hoes
            desired_height = image.shape[0]

            # Bereken de gewenste breedte op basis van de beeldverhouding en gewenste hoogte
            desired_width = int(desired_height * 4 / 6)

            # Bereken de coördinaten van de linkerbovenhoek voor bijsnijden
            left = max(0, center_x - desired_width // 2)
            top = max(0, center_y - desired_height // 2)

            # Bijsnijden van de afbeelding op basis van de gewenste breedte en hoogte
            cropped_image = image[top:top + desired_height, left:left + desired_width]

            # Beschrijf waarom het bijsnijden op deze locatie is gedaan
            explanation = "Bijsnijden om te focussen op het gezicht op (x={}, y={}).".format(center_x, center_y)
            status = explanation + "\nFolder.jpg succesvol gecreëerd.\n"

            # Krijg de map van het momenteel uitgevoerde script
            script_directory = os.path.dirname(os.path.abspath(__file__))

            # Sla de bijgesneden afbeelding op als "Folder.jpg"
            folder_image_name = "Folder.jpg"
            cv2.imwrite(folder_image_name, cropped_image)

            # Zoek de nieuwste map op basis van de aanmaaktijd in dezelfde map als de scriptmap
            script_parent_directory = os.path.dirname(script_directory)
            latest_directory = max([f.path for f in os.scandir(script_directory) if f.is_dir()], key=os.path.getctime, default=None)

            if latest_directory:
                # Verplaats "Folder.jpg" naar de nieuwste map
                shutil.move(folder_image_name, os.path.join(latest_directory, "Folder.jpg"))
                shutil.move(image_path, os.path.join(latest_directory,"Fanart.jpg" ))
                # Voeg een statusbericht toe voor de kopieeroperatie
                copy_status = f"Folder.jpg is verplaatst naar {latest_directory}"

                # Exporteer de kopieerstatus naar een tekstbestand
                output_status_file = os.path.join(script_directory, "output_status.txt")
                with open(output_status_file, 'a') as file:  # 'a' mode voegt toe aan het bestand
                    file.write(copy_status + "<1>\n")  # Voeg een nieuwe regel toe
                    os.remove("temp.jpg")
                    os.system("taskkill PhotosApp.exe") 
                    
    else:
        status = "Het plaatje is NIET in Landschaps oriëntatie.<3>\n"
        # Exporteer de status naar een tekstbestand
        output_file = "output_status.txt"
        with open(output_file, 'a') as file:  # 'a' mode voegt toe aan het bestand
            file.write(status + "\n")  # Voeg een nieuwe regel toe

# Krijg het bestandspad van de neergezette afbeelding
if len(sys.argv) > 1:
    dropped_file_path = sys.argv[1]
    crop_portrait(dropped_file_path)
    output_file = "output_status.txt"
    with open(output_file, 'a') as file:  # 'a' mode voegt toe aan het bestand
        file.write("Image " + dropped_file_path + " verwijderd\n")  # Voeg een nieuwe regel toe
        os.remove(dropped_file_path)
else:
    # print("Geen afbeeldingsbestand op het programma-icoon neergezet.")
    # Voeg een statusbericht toe voor de de beeldbewerkings aktie
    # Dit deel is feitelijk overbodig geworden met de drop functie
    copy_status = f"Geen afbeeldingsbestand op het programma-icoon neergezet."
    with open(output_file, 'a') as file:  # 'a' mode voegt toe aan het bestand
        file.write(status + "<2>\n")  # Voeg een nieuwe regel toe

status = "temp.jpg is weer verwijderd.\n"
# verwijder het evt aan gemaakte temp.jpg image
output_file = "output_status.txt"
with open(output_file, 'a') as file:  # 'a' mode voegt toe aan het bestand
    file.write(status + "\n")  # Voeg een nieuwe regel toe
   # os.remove("temp.jpg")
User avatar
sander
Release Testers
Release Testers
Posts: 8832
Joined: January 22nd, 2008, 2:22 pm

Re: inteligent script om kleverig.eu folder en fanart te maken voor bv kodi.

Post by sander »

TIL:
"Face Detection using Haar Cascades"
"Haar-cascade Detection in OpenCV"

... maar ... hij ziet gezichten? Niet van wie dat gezicht is?

En het subject: dat is toch een bepaald genre films?
Richard63NL
Newbie
Newbie
Posts: 16
Joined: August 22nd, 2019, 10:32 am

Re: inteligent script om kleverig.eu folder en fanart te maken voor bv kodi.

Post by Richard63NL »

Ja idd De meeste xxx films hebben geen echte cover :-) alle andere wel vandaar
en hij ziet idd gezichten maar niet van wie. en dat doet er ook niet toe.
ik kon persoonsherkenning niet werkend krijgen.
Soms ziet haarcascade ook gezichten die er helemaal niet zijn. bv noesten in een boomstam.
verder werkt dit script (programma) heel goed. mn op kleverig.eu dus
Post Reply