Seite 1 von 1

OpenCv2 Screenshot

Verfasst: Dienstag 20. Dezember 2022, 16:28
von Merkator
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

Re: OpenCv2 Screenshot

Verfasst: Dienstag 20. Dezember 2022, 17:23
von __blackjack__
@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‽

Re: OpenCv2 Screenshot

Verfasst: Dienstag 20. Dezember 2022, 18:47
von Merkator
Jetzt bekomme ich den error:

[mjpeg @ 0x1d52f40] overread 8