Wand TypeError

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Hast du mal in die aeusserst umfangreiche OpenCV-Dokumentation geschaut? Was da so an Beispielen zu den von mir genannten Stichworten zB steht?
Benutzeravatar
Felix92
User
Beiträge: 133
Registriert: Mittwoch 7. November 2018, 17:57

Naja ich hatte mir in der docu die Tutorials angesehen dann noch probiert über google etwas zu finden ohne großen Erfolg und die docu an sich allerdings bin ich da nicht so schlau draus geworden, da diese wie du schon sagtest ziemlich umfangreich ist.
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ich habe dir ja eine Reihe von konkreten Ansaetzen genannt, zB Histogramme. Letztlich musst du entscheiden, welche Kriterien fuer "hier ist nichts was wichtig ist" du hast. Das kann hier keiner fuer dich tun, denn es ist dein Projekt, deine Slides, deine Kriterien.

Und wenn du *ein* Kriterium hast (zb einfach alles komplett weiss), das fuer einen gegebenen Ausschnitt funktioniert, dann kannst du das ja in Zukunft erweitern. Oder deinen Prof fragen, wie das Kriterium genauer aussehen soll.
Benutzeravatar
Felix92
User
Beiträge: 133
Registriert: Mittwoch 7. November 2018, 17:57

Huhu und zwar wollte ich mal nachfragen, wie ich es hinbekomme dass in einem Bild ein Video als Overlay liegt, welches relativ zum Video abspielt.
Kurz zum Problem: ich habe eine PDF in Bilder gesplittet diese Bilder werden dann geprüft ob auf ihnen unten rechts (250x200) alles weiß ist um dort ein Bild einzufügen (soweit läuft alles) nun soll es aber auch möglich sein in diesem unteren Bereich anstatt einem Bild ein Video einzublenden.
Also kurz im unteren Beispiel sollte jetzt nur die Folie zu sehen sein und das aktuelle Video auf der Folie unten rechts wenn Platz ist ansonsten wenn kein Platz ist wird nur die Folie angezeigt.
Ich hoffe es ist einigermaßen verständlich :roll:

Bild


Das steht bisher (hat bisher mehr zum testen und probieren gedient):
check_color liefert True wenn Platz auf der Folie ist.

Code: Alles auswählen

def video_in_slide(file_path, filename, video_path, videoname, y1, y2, x1, x2):
    presentation_file = Path(file_path, filename)
    video_file = Path(video_path, videoname)
    if check_color(file_path, filename, y1, y2, x1, x2) == True:
        cap = cv2.VideoCapture(str(video_file))
        if(cap.isOpened() == False):
            print("Error opening video stream or file")
        while(cap.isOpened()):
            ret, frame = cap.read()
            if ret == True:
                cv2.imshow('Frame', frame)
                if cv2.waitKey(25) & 0xFF == ord('q'):
                    break
            else:
                break
        cap.release()
        cv2.destroyAllWindows()
    else:
        img = cv2.imread(str(presentation_file), cv2.IMREAD_COLOR)
        return img
MfG Felix
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Brauchst du keinen Ton dafuer? Woher weisst du denn, wann welche Slide dran ist?

Ansonsten ist das ganz einfach: den Frame kannst du mit imresize auf das gewuenschte Mass stutzen, und in das Image des PDFs das du ja schon als numpy-Array vorliegen hast reinpacken.

slide[y:y+hoehe,x:x+breite] = frame
Benutzeravatar
Felix92
User
Beiträge: 133
Registriert: Mittwoch 7. November 2018, 17:57

Huhu @__deets__ also Ton geht mich nichts an da kümmern sich andere drum ein Problem weniger ^^ :)
2teres ist eins der Probleme wo ich nicht so recht weiß wie ich es lösen soll ..ich hatte halt im Kopf die Bilder zu einem Video zusammenzufügen und das Video des Dozenten als Overlay an die Position zu legen wenn die Folie unten rechts Platz für hat...allerdings funktioniert dafür meine Funktion check_color vermutlich nicht wenn die Bilder dann ein Video sind !? :?:

Ich poste hier einfach mal den kompletten Code um ein wenig klarer zu machen was bisher passiert :)
check_color und video_in_slide wären hier ausschlaggebend

Code: Alles auswählen

def convert(file_path, filename, new_project_path, new_project_name):

    pdf_file = Path(file_path, filename)
    check_pdf = fnmatch(pdf_file, '*.pdf')
    if check_pdf == True:
        folder = Path(new_project_path, new_project_name)
        folder.mkdir(exist_ok=True) 
        input_file = Path(file_path, filename)
        pages = convert_from_path(str(input_file), 250)
        files = []
        for page_number, page in enumerate(pages, start=1):
            target = folder / f"{page_number:03d}.jpg"
            page.save(str(target),  'JPEG')
        for file in os.listdir(folder):
            files.append(file)

        files.sort()
    else:
        print("the datatype must be .pdf")


def add_file_to_project(file_path, filename, project_path, project_name):

    folder = Path(project_path, project_name)
    file_to_add = Path(file_path, filename)
    check_jpg = fnmatch(file_to_add, '*.jpg')
    check_mp4 = fnmatch(file_to_add, '*.mp4')
    check_png = fnmatch(file_to_add, '*.png')
    if check_jpg == True:
        shutil.copy(str(file_to_add), str(folder))
    elif check_mp4 == True:
        shutil.copy(str(file_to_add), str(folder))
    elif check_png == True:
        shutil.copy(str(file_to_add), str(folder))
    else:
        print("the datatype must be .jpg or .mp4 or .png")


def delete_folder(project_path, project_name):

    folder = Path(project_path, project_name)
    shutil.rmtree(folder, ignore_errors=True)


def check_color(file_path, filename, y1, y2, x1, x2):

    input_file = Path(file_path, filename)
    white = 255
    gray = 32
    img = cv2.imread(str(input_file), cv2.IMREAD_GRAYSCALE)
    roi = img[y1:y2, x1:x2]

    if np.all(roi == white) == True:
        return True
    elif np.all(roi == gray) == True:
        return True
    else:
        return False
    

def picture_in_presentation(file_path, filename, file_path_small_img, small_img, y1, y2, x1, x2, x_offset, y_offset):

    large_img = Path(file_path, filename)
    large_img = cv2.imread(str(large_img))

    small_img = Path(file_path_small_img, small_img)
    small_img = cv2.imread(str(small_img))
    small_img = cv2.resize(small_img, (250, 200))

    #x_offset = 1009 #only for resolution 250 # large_img width - 250
    #y_offset = 710 #only for resolution 250 # large_img height - 245

    if check_color(file_path, filename, y1, y2, x1, x2) == True:
        large_img[y_offset:y_offset+small_img.shape[0], x_offset:x_offset+small_img.shape[1]] = small_img
        #cv2.imwrite('test.jpg', large_img)
        return large_img
    else:
        #cv2.imwrite('test.jpg', large_img)
        return large_img


def video_in_slide(file_path, filename, video_path, videoname, y1, y2, x1, x2):
    presentation_file = Path(file_path, filename)
    video_file = Path(video_path, videoname)
    if check_color(file_path, filename, y1, y2, x1, x2) == True:
        cap = cv2.VideoCapture(str(video_file))
        if(cap.isOpened() == False):
            print("Error opening video stream or file")
        while(cap.isOpened()):
            ret, frame = cap.read()
            if ret == True:
                cv2.imshow('Frame', frame)
                if cv2.waitKey(25) & 0xFF == ord('q'):
                    break
            else:
                break
        cap.release()
        cv2.destroyAllWindows()
    else:
        img = cv2.imread(str(presentation_file), cv2.IMREAD_COLOR)
        return img
MfG Felix
und vielen Dank für eure Hilfe
Sirius3
User
Beiträge: 17710
Registriert: Sonntag 21. Oktober 2012, 17:20

man prüft nicht explizit auf == True. Die ganzen check_-Variablen sind auch nicht nötig, und statt dreimal den selben if-Block würde man auch die drei Bedingungen mit and verknüpfen. Bei `Path` gibt es dann auch noch suffix:

Code: Alles auswählen

def add_file_to_project(file_path, filename, project_path, project_name):
    file_to_add = Path(file_path, filename)
    if file_to_add.suffix in ['.jpg', '.mp4', '.png']:
        folder = Path(project_path, project_name)
        shutil.copy(str(file_to_add), str(folder))
    else:
        print("the datatype must be .jpg or .mp4 or .png")
Benutzeravatar
Felix92
User
Beiträge: 133
Registriert: Mittwoch 7. November 2018, 17:57

Danke für den Tipp werde ich morgen umsetzen :)
Allerdings hilft mir das bei dem eigentlichen Problem nicht wirklich weiter hast du da vlt. eine Idee ? :D
MfG Felix
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Kann es sein, das diese ganze pdf Geschichte unnötig ist? Du willst eigentlich dir Projektion des Vortrages zugrunde legen?
Benutzeravatar
Felix92
User
Beiträge: 133
Registriert: Mittwoch 7. November 2018, 17:57

Naja nicht so ganz es soll halt möglich sein diese pdf Datei (Folien) quasi auszulesen wenn Platz ist soll es möglich sein selbstständig ein Bild einzufügen oder das halt das Video unten rechts eingeblendet wird, da das Video so wie in dem Bild nicht mehr da sein wird am Ende ...das ganze ist am Ende ein Schnittprogramm wo 2 Master und 8 Bachelor dran arbeiten und meine Task ist halt derzeit "nur" ein module für das wie oben beschrieben zu schreiben ..Ich hatte weiter oben auch mal die beiden Tasks gepostet wobei das Objekt gestrichen wurde und durch diesen temporären Ordner ersetzt wird.
MfG Felix
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Dann habe ich dein aktuelles Problem immer noch nicht verstanden. Du redest doch davon, das deine Funktion NICHT funktioniert, wenn sie mit einem video arbeiten muss. Welches Video denn dann?

Ausgesehen davon, dass ein Bild ein Bild ist. Die Quelle dafür ist egal. Aber natürlich muss die Funktion dann ein Bild alsmArgument nehmen, und es nicht selbst irgendwoher laden.
Benutzeravatar
Felix92
User
Beiträge: 133
Registriert: Mittwoch 7. November 2018, 17:57

Ok ich probiere es nochmal ausführlicher zu formulieren :)

Mein Ausgangsmaterial sind Bilder wie diese und ein mp4-Video welches in dem Bild welches ich gepostet hatte im linken Fenster zu sehen ist.

Bild

Bild

Bild

in der Funktion:

Code: Alles auswählen

def video_in_slide(file_path, filename, video_path, videoname, y1, y2, x1, x2):
    presentation_file = Path(file_path, filename)
    video_file = Path(video_path, videoname)
    if check_color(file_path, filename, y1, y2, x1, x2) == True:
        cap = cv2.VideoCapture(str(video_file))
        if(cap.isOpened() == False):
            print("Error opening video stream or file")
        while(cap.isOpened()):
            ret, frame = cap.read()
            if ret == True:
                cv2.imshow('Frame', frame)
                if cv2.waitKey(25) & 0xFF == ord('q'):
                    break
            else:
                break
        cap.release()
        cv2.destroyAllWindows()
    else:
        img = cv2.imread(str(presentation_file), cv2.IMREAD_COLOR)
        return img
(wurde nur zum testen/einarbeiten mit Videos benutzt also das was eigentlich poassieren soll fehlt noch)
Schritt 1 : soll es nun möglich sein das ein Bild durch check_color geprüft wird ob es genug freien Platz für das Video hat wenn dem so ist soll das Video auf dem Bild angezeigt werden wenn nicht dann soll nur das Bild angezeigt werden.
Schritt 2 : Schritt 1 soll für alle Bilder aus der PDF wiederholt werden ( das Video müsste also quasi im Hintergrund mitlaufen damit bei einem Wechsel des Bildes geprüft wird ob Platz ist und wenn ja das Video an der Stelle wo es gerade ist angezeigt wird)
- das ganze wird dann als Video oder Bildersequence (ist egal) zurückgegeben

Ich hatte schon überlegt die Bilder einfach zu einem Video umzuwandeln(Video1) welches die Länge der mp4-Datei(Video2) hat und dann einfach Video2 als Overlay über Video1 zu legen an die bestimmte Stelle allerdings wird dort meine check_color funktion nicht funktionieren vermute ich.

MfG Felix
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ich finde das alles sehr unstrukturiert was du da beschreibst. Du hast zwei Probleme:

- zu entscheiden, ob in einem gegebenen Bild (als BILD! Nicht als Pfad oder Seite in einem PDF oder oder oder. Das ist ein BILD. Es ist egal woher das kommt) Platz ist fuer einen Videoeinblendung.
- Fuer zwei Bilder A und B und eine Region R das Bild B in A in der Region R einzufuegen, und dieses resultierend Bild zurueck zu geben.

Das war's erstmal. Was du darum drum baust haengt von lauter Variablen ab, die hier keiner kennt. Es ist dir doch ueberhaupt nichts damit geholfen, aus den PDFs ein Video zu machen. Ein Video ist nichts anderes als eine Abfolge von Bildern. Und deine PDF-Datei ist *AUCH* eine Abfolge von Bildern. Was ist also dadurch gewonnen, das du da ein Video draus machst?

WAS dir hilft ist zu wissen, WANN welche Folie dargestellt wird. Denn ohne diese Information kannst du auch kein Video bauen, wo dann halt 1000 Frames Folie 1, dann 2000 Frames Folie2, dann 500 Frames Folie 3 gezeigt wird, bloss damit du dann "einfach" jeden Frame aus dem Dozenten-Video mit einem Frame aus deinem PDF-Video mit der gleichen Frame-Nummer verbandeln kannst.

Diese Information musst du irgendwoher bekommen. Wenn ich das machen wuerde, dann wuerd ich dazu versuchen das Dozenten-Video zu analysieren um rauszufinden, wann welche Folie gezeigt wird. So das der Vorgang automatisch passiert. Aber dafuer braucht man ein paar mehr OpenCV-Kenntnisse als du sie hast. Alternativ kannst du das von hand machen, durch eine Datei mit Zeitpunkten und Seitennummern zB. Oder eine grafische Oberflaeche bauen dafuer. Oder. Oder. Oder. Weswegen ich schrieb "haengt von lauter Variablen ab, die hier keiner kennt."
Benutzeravatar
Felix92
User
Beiträge: 133
Registriert: Mittwoch 7. November 2018, 17:57

vielen Dank erstmal für deine Antwort :)
Ich werde da aufjedenfall nochmal Rücksprache halten wie das genau gewollt ist.
Das wäre also rein mit OpenCV möglich ohne Tensorflow/Keras zwecks Object Detection module ??
Hast du da eine Quelle die sich lohnt zu lesen oder anzusehen um ein wenig tiefer ins Thema zu kommen ?

Btw: die Folien werden nicht im Video gezeigt sondern sind mit dem alten Programm (Ubicut) vom Prof einfach reingebastelt wie in dem Bild was ich gepostet hatte wir haben eine pdf also die Folie und 2 mp4-Dateien(Video von ihm + Tafel und ein Video vom Visualiser) zur Verfügung, da ist also denke nicht viel mit Videoanalyse :/
Aber gut das nochmal so durchzugehen da kommen mir für unsere Master echt so einige Fragen :D

Eine Frage hätte ich noch und zwar probiere ich gerade einfach ein wenig rum und wollte jetzt einfach mal das komplette Video auf einem Bild unten rechts abspielen also Bild wird gezeigt und unten rechts läuft das Video.
Allerdings gibt es immer

Code: Alles auswählen

TypeError: 'PosixPath' object does not support item assignment
aus.
Ich dachte ich kann das Video einfach als Overlay drüber legen :?

Code: Alles auswählen

def video_in_slide(file_path, filename, video_path, videoname, y1, y2, x1, x2):
    presentation_file = Path(file_path, filename)
    img = cv2.imread(str(presentation_file))

    height = img.shape[0] #y
    width = img.shape[1]

    video_file = Path(video_path, videoname)

    if check_color(file_path, filename, y1, y2, x1, x2) == True:
        cap = cv2.VideoCapture(str(video_file))
        if(cap.isOpened() == False):
            print("Error opening video stream or file")

        while(cap.isOpened()):
            ret, frame = cap.read()
            if ret == True:
                x_offset = width - 250
                y_offset = height - 200
                frame = cv2.resize(frame, (250, 200))
                #cv2.imshow('Frame', frame)

                presentation_file[y_offset:y_offset+200, x_offset:x_offset+250] = frame
                cv2.imshow('Frame', presentation_file)
                #cv2.imshow('image', presentation_file)

                if cv2.waitKey(25) & 0xFF == ord('q'):
                    break
            else:
                break
        cap.release()
        cv2.destroyAllWindows()
    else:
        cv2.imshow('image', img)
        cv2.waitKey(0)
        cv2.destroyAllWindows()
        return img
Benutzeravatar
__blackjack__
User
Beiträge: 13003
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Felix92: So eine Ausnahme besteht ja nicht nur aus der letzten Zeile. Im Traceback davor siehst Du in welcher Zeile die Ausnahme ausgelöst wurde. Schau Dir doch mal an was Du da versuchst. Das sollte eigentlich klar sein dass das so nicht funktionieren kann.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Also wenn das Bild das dort oben stellvertretend ist fuer ein Video das ihr bekommt - doch, dann kann man da rechts die Folie versuchen im PDF zu finden.

Ich habe mir aus beruflichen Gruenden vor zwei Jahren Zugang zu pyimagesearch.com gekauft, ich finde Adrian hat da einen guten Online-Kurs erstellt. Das kostet aber ein paar hundert $. Er hat auch viel freien Content, sich da durch zu arbeiten kann nicht schaden.

Und Keras & Co helfen hier nur bedingt, denn die Aufgabe ist nicht "erkenne irgendwas, das irgendwie eine Folie/Katze/Maus/Hund ist", sondern eine *konkrete* Folie die du vor allem auch vorher noch nicht trainieren konntest. In vorvearbeitenden Stufen mag da ein NN zur Anwendung kommen, aber schlussendlich ist das eine Frage die eher durch Image Deskriptoren (zB SIFT) und ggf. OCR. Denn du hast ja meistens Text auf den Folien.

https://web.archive.org/web/20170207033 ... ecognition

Und mit SIFT und Co kannst du Aehnlichkeiten zwischen dem Video-Ausschnitt und einer Folie auch unabhaengig von Text berechnen, und das fuer eine Heuristik zugrunde legen.
Benutzeravatar
Felix92
User
Beiträge: 133
Registriert: Mittwoch 7. November 2018, 17:57

Ok vielen Dank erstmal :) Ich werde mich da mal ein wenig durcharbeiten
Benutzeravatar
Felix92
User
Beiträge: 133
Registriert: Mittwoch 7. November 2018, 17:57

Huhu ich mal wieder :)
Und zwar möchte ich einen bestimmten Bereich aus einem Video als "extra" Video abspeichern klappt auch alles super allerdings lässt sich das Video nach dem speichern nicht abspielen woran liegt das ?
Fehler:

Code: Alles auswählen

OpenCV: FFMPEG: tag 0x5634504d/'MP4V' is not supported with codec id 12 and format 'mp4 / MP4 (MPEG-4 Part 14)'
OpenCV: FFMPEG: fallback to use tag 0x7634706d/'mp4v'
Code:

Code: Alles auswählen

def large_video_in_slide(video_path, videoname):
    video_file = Path(video_path, videoname)

    cap = cv2.VideoCapture(str(video_file))

    fourcc = cv2.VideoWriter_fourcc(*'MP4V')
    out = cv2.VideoWriter('output.mp4', fourcc, 20.0, (1280,720))

    if(cap.isOpened() == False):
        print("Error opening video stream or file")

    while(cap.isOpened()):
        ret, frame = cap.read()
        if ret == True:
            frame = frame[275:805, 17:955]
            out.write(frame)
            cv2.imshow('Frame', frame)

            if cv2.waitKey(25) & 0xFF == ord('q'):
                break
        else:
            break
    cap.release()
    cv2.destroyAllWindows()
Vielen Dank und MfG Felix :)
Benutzeravatar
__blackjack__
User
Beiträge: 13003
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Felix92: Es fehlt irgendwie das schliessen der Videodatei‽ Und was bedeutet denn das letzte Argument beim `VideoWriter()`-Aufruf? Das scheint mir falsch zu sein.

``if`` und ``while`` sind keine Funktionen, also sollte man das auch nicht so schreiben dass es wie ein Funktionsaufruf aussieht. Statt aber nur ein Leerzeichen nach diesen Schlüsselworten zu setzen, kann man auch gleich die überflüssige Klammern weg lassen.

Man vergleicht kleine Werte mit literalen Wahrheitswerten. Da kommt doch sowieso nur wieder ein Wahrheitswert bei heraus. Entweder der, den man eh schon hatte, dann kann man den auch gleich verwenden, oder dessen Gegenteil. Wenn man auf das Gegenteil testen möchte, nimmt man einfach ``not``. also ``if not cap.isOpened():`` und ``if ret:``.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Antworten