OpenCv2 Screenshot

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.
Antworten
Merkator
User
Beiträge: 151
Registriert: Sonntag 5. Dezember 2021, 17:15

Hey,

mein Code:

Code: Alles auswählen


import cv2 
import numpy as np 
import time
import os

i=0
cap = cv2.VideoCapture('XXXXXXXXXXXXXXXXXX')
fourcc=cv2.VideoWriter_fourcc(*'XVID') 
out=cv2.VideoWriter('output.avi',fourcc,20.0,(1280,720)) 
_,frame1=cap.read() 
_,frame2=cap.read() 

cv2.namedWindow('Detection', cv2.WINDOW_NORMAL)
 
while cap.isOpened(): 
    diff=cv2.absdiff(frame1,frame2) 
    diff_gray=cv2.cvtColor(diff,cv2.COLOR_BGR2GRAY) 
    blur=cv2.GaussianBlur(diff_gray,(5,5),0) 
    _,thresh=cv2.threshold(blur,20,255,cv2.THRESH_BINARY) 
    dilated=cv2.dilate(thresh,None,iterations=3) 
    countours,_=cv2.findContours(dilated,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE) 
    cv2.drawContours(frame1,countours,-1,(0,255,0),2,cv2.LINE_AA) 
    for contour in countours: 
        (x,y,w,h)=cv2.boundingRect(contour) 
        if cv2.contourArea(contour)<700 : 
            continue 
        else: 
                cv2.rectangle(frame1,(x,y),(x+w,y+h),(0,255,0),2) 
                cv2.putText(frame1,"Status: {}".format("movement"),(10,20),cv2.FONT_HERSHEY_SIMPLEX,0.5,(0,0,255),2) 
                i += 1
                file_name = "screenshot_{}.png".format(i)
                cv2.imwrite(file_name, frame1)
                
    image = cv2.resize(frame1, (3120, 2580))
    out.write(image) 
    cv2.imshow('Detection',frame1) 
    frame1=frame2 
    _,frame2=cap.read() 
  
  
    k=cv2.waitKey(10) 
    if k==27: 
        break 
cv2.destroyAllWindows() 
cap.release() 
out.release()
Mein Problem:

Screenshot wird nicht bei bewegung aufgenommen. (nach dem else befehl das zeug)


Danke für jegliche Hilfe
Benutzeravatar
__blackjack__
User
Beiträge: 13117
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Merkator: `os`, `time`, und `numpy` werden importiert aber nirgends verwendet.

Es ist Erfahrungsgemäss keine gute Idee das erste Element vom Ergebnis von `read()` zu ignorieren.

Das Aufräumen sollte man besser absichern (``try``/``finally``).

``continue`` ist ja an sich schon nicht schön, hier bringt es aber überhaupt nichts ausser den Code schwerer verständlich zu machen.

Es macht nicht so wirklich Sinn eine statische Zeichenkette in eine andere Zeichenkette zu formatieren.

Zwischenstand (ungetestet):

Code: Alles auswählen

#!/usr/bin/env python3
from contextlib import contextmanager

import cv2
from more_itertools import pairwise, with_iter

GREEN = (0, 255, 0)
RED = (0, 0, 255)


@contextmanager
def iter_frames(capture_device):
    reader = cv2.VideoCapture(capture_device)
    try:
        while reader.isOpened():
            is_ok, frame = reader.read()
            if is_ok:
                yield frame
    finally:
        reader.release()


def main():
    image_count = 0
    writer = cv2.VideoWriter(
        "writerput.avi", cv2.VideoWriter_fourcc(*"XVID"), 20.0, (1280, 720)
    )
    try:
        cv2.namedWindow("Detection", cv2.WINDOW_NORMAL)
        try:
            for frame1, frame2 in pairwise(
                with_iter(iter_frames("XXXXXXXXXXXXXXXXXX"))
            ):
                diff = cv2.absdiff(frame1, frame2)
                diff_gray = cv2.cvtColor(diff, cv2.COLOR_BGR2GRAY)
                blurred = cv2.GaussianBlur(diff_gray, (5, 5), 0)
                _, thresh = cv2.threshold(blurred, 20, 255, cv2.THRESH_BINARY)
                dilated = cv2.dilate(thresh, None, iterations=3)
                countours, _ = cv2.findContours(
                    dilated, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE
                )
                cv2.drawContours(frame1, countours, -1, GREEN, 2, cv2.LINE_AA)
                for contour in countours:
                    if cv2.contourArea(contour) >= 700:
                        x, y, width, height = cv2.boundingRect(contour)
                        cv2.rectangle(
                            frame1, (x, y), (x + width, y + height), GREEN, 2
                        )
                        cv2.putText(
                            frame1,
                            "Status: movement",
                            (10, 20),
                            cv2.FONT_HERSHEY_SIMPLEX,
                            0.5,
                            RED,
                            2,
                        )
                        image_count += 1
                        cv2.imwrite(f"screenshot_{image_count}.png", frame1)

                writer.write(cv2.resize(frame1, (3120, 2580)))
                cv2.imshow("Detection", frame1)
                if cv2.waitKey(10) == 27:
                    break
        finally:
            cv2.destroyAllWindows()
    finally:
        writer.release()


if __name__ == "__main__":
    main()
Gibt es denn ausreichend grosse Konturen, dass der Zweig überhaupt betreten wird? Ich finde auch etwas komisch das für jede Kontur ein eigenes Bild erzeugt wird, wo aber alle Konturen die bisher gezeichnet wurden, enthalten sind.

Die Bildnummer im Dateinamen würde man besser mit führenden 0en versehen, damit eine lexikographische Sortierung der Dateinamen korrekte Ergebnisse liefert.

Funktioniert das mit der Videodatei? Das Format ist mit 1280x720 angegeben, die Bilder die geschrieben werden, werden aber vorher auf 3120x2580 hoch skaliert‽
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Merkator
User
Beiträge: 151
Registriert: Sonntag 5. Dezember 2021, 17:15

Jetzt bekomme ich den error:

[mjpeg @ 0x1d52f40] overread 8
Antworten