Live-Bild einer Webcam anzeigen mit Python und OpenCV

Ist OpenCV erst einmal auf dem Test-System installiert, hat man unzählige Möglichkeiten, mit Bildern aus welchen Quellen auch immer, zu arbeiten.

Eine Grundaufgabe ist es oft, einfach das Bild einer Webcam auf dem Bildschirm darzustellen

Hierfür habe ich auf Github  https://gist.github.com/tedmiston/6060034 eine elegante Lösung gefunden, die ich Euch hiermit gerne vortstelle. (Vielen Dank an Taylor D. Edmiston)

Vielen Dank an geralt https://pixabay.com/de/tablet-technologie-vorf%C3%BChrung-1704813/  für das Bild zum vorliegenden Beitrag

das lauffähige Python 3.65 / OpenCV3.x Code-Snippet zum Anzeigen des Bildes auf dem Monitor

Interesant in diesem Zusammenhang ist die Rolle von cv2.waitkey(x). Während cv2.waitkey(0) nach jedem angezeigtem Bild auf eine Eingabe wartet, bewirkt jedes andere Argument hier eine flüssige Darstellung des Streams.

import cv2

cam = cv2.VideoCapture(0)
while True:
     ret_val, img = cam.read()
     img = cv2.flip(img, 1)
     cv2.imshow('my webcam', img)
     if cv2.waitKey(1) == 27:
          break  # esc to quit
cv2.destroyAllWindows()

Die Funktion „Webcam Lesen) zum Einbinden in eigene Projekte

"""
Simply display the contents of the webcam with optional 
mirroring using OpenCV 
via the new Pythonic cv2 interface.  Press <esc> to quit.
"""

import cv2


def show_webcam(mirror=False):
    cam = cv2.VideoCapture(0)
while True:
     ret_val, img = cam.read()
     if mirror: 
         img = cv2.flip(img, 1)
     cv2.imshow('my webcam', img)
     if cv2.waitKey(1) == 27: 
          break  # esc to quit
cv2.destroyAllWindows()


def main():
    show_webcam(mirror=True)


if __name__ == '__main__':
    main()

Webcam – Bewegungserkennung mit Python und OpenCV

Wenn man mit einer Webcam eine Szenerie beobachtet, macht es oft Sinn, zu wissen, ob sich irgend etwas in dieser Szenerie tut, also bewegt. Man kann z.B. nach Detektion einer Bewegung ein Bild abspeichern, eine Nachricht absetzen oder weitere Bildanalysen starten. Die Webcam wird also durch ein paar Zeilen Python-Code zu einem Bewegungsmelder, der nach meinen Erfahrungen den Vergleich mit einem passiv-Infrarot – Detektor (Piri, herkömmlicher Bewegungsmelder) nicht scheuen braucht.

In diesem Beitrag will ich Euch ein Code-Snippet für eine lauffähige Lösung vorstellen, die nach Detektion einer Bewegung ein Bild abspeichert. Die Empfindlichkeit der Unterscheidung, ob eine Bewegung erfolgt ist, ist dabei frei wählbar

Das unter Python 3.6 /OpenCV 3.4 lauffähige Code-Snippet für Bewegungserkennung mittels Webcam:

import cv2
import datetime

def diffImg(t0, t1, t2):
    d1 = cv2.absdiff(t2, t1)
    d2 = cv2.absdiff(t1, t0)
    return cv2.bitwise_and(d1, d2)

folder="BV"
message_01 = "not yet"
message_02= "not yet"
cam = cv2.VideoCapture(0)
cam.set(3,1280)
cam.set(4,720)

winName = "Bewegungserkennung"

font = "FONT_HERSHEY_SIMPLEX"
#cv2.namedWindow(winName, cv2.CV_WINDOW_AUTOSIZE)
# Read three images first:

return_value, image = cam.read()
t_minus = cv2.cvtColor(cam.read()[1], cv2.COLOR_RGB2GRAY)

t = cv2.cvtColor(cam.read()[1], cv2.COLOR_RGB2GRAY)

t_plus = cv2.cvtColor(cam.read()[1], cv2.COLOR_RGB2GRAY)

Durchschnitt = 1
n=1


while True:

    t_minus = t

    t = t_plus

    t_plus = cv2.cvtColor(cam.read()[1], cv2.COLOR_RGB2GRAY)
    result_image = diffImg(t_minus, t, t_plus)
    cv2.putText(result_image, 'OpenCV', (100, 500), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), thickness=2)
    cv2.putText(result_image, message_01, (100, 550), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), thickness=2)
    cv2.putText(result_image, "Stop with <ESC> ",(100, 600), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), thickness=2)
    cv2.imshow(winName, result_image)

    print (cv2.countNonZero(diffImg(t_minus, t, t_plus)))

    if cv2.countNonZero(diffImg(t_minus, t, t_plus)) > 305000:
        return_value, image = cam.read()
        # cv2.imwrite("buero" + str(n) + ".png", image)
        cv2.imwrite("{0}/{1:%d%b%Y_%H_%M_%S.%f}.png".format(
            folder, datetime.datetime.utcnow()), image)
        message_01 = str(n) + "  pictures saved"
        n= n+1

    key = cv2.waitKey(10)

    if key == 27:
        cam.release
        cv2.destroyWindow(winName)
        break

Das Ergebnis: Differenzbild wird angezeigt, solange Bewegung stattfindet werden Fotos abgespeichert. Auch die Anzahl der gespeicherten Fotos wird mitgeteilt.

erlogreicher „Selbstversuch“ – bei Bewegung werden Bilder gespeichert.

Diese Lösung hat sich im praktischen Test (Bewegungsmelder im Büro) als recht robust erwiesen und kommt dank gleitender Hintergrund-Durchschnittsbildung auch mit wechselnden Lichtverhältnissen gut zurecht.

Der Lösungsansatz auf Basis Differenzbilder geht auf Matthias Stein (http://www.steinm.com/blog/motion-detection-webcam-python-opencv-differential-images/) zurück, ich habe einige Anpassungen und Erweiterungen bezüglich meiner Applikation vorgenommen.

Anm: Das Titelbild stammt von: https://pixabay.com/de/person-bewegung-beschleunigen-2146508/, vielen Dank an ATDSPHOTO 

Nachrichten vom Raspberry Pi erhalten, mit Python und unter Nutzung des Dienstes „pushingbox“

Mit dem Raspberry Pi ist es einfach und sehr preiswert geworden, beliebige Sachverhalte zu überwachen. Passiert dann das Ereignis, auf welches man wartet, will man schnellstmöglich darüber informiert werden, gewöhnlicherweise durch eine Nachricht per mail oder direkt  aufs Mobiltelefon. Hier kommt der kostenlose Dienst „pushingbox“ (https://www.pushingbox.com/) gerade recht, der auch diese Aufgabe sehr einfach macht und effektiv löst.

Bei „pushingbox“ gibt es nur eine einzige API, die sich verschiedenartig triggern lässt, z.B. durch:

  • Arduino
  • Raspberry Pi
  • Spark Core
  • IFTTT
  • Email
  • SmartThings
  • HTTP Request
  • Dein eigenes Script…
  • Vera, Fibaro, …

Die durch die o.g. Trigger ausgelöste Nachricht lässt sich dann wie folgt empfangen:

  • Emails
  • Tweets
  • Notifications on SmartWatch like Pebble
  • Smartphone Push Notifications (iOS, Android, WindowsPhone)
  • Windows8 Notifications
  • MacOS Notifications
  • Karotz Text-to-Speech
  • Custom HTTP Request

Um „pushingbox“ zu nutzen, muss man sich dort mit seinem „Google“-Account anmelden. Sofort danach kann man den Dienst, am einfachsten mit einem html-Aufruf, ausprobieren.

unmittelbar nach Aufruf finden sich die entsprechenden mails im Posteingang.

Dies Funktionalität lässt sich auch in Python mit wenigen Zeilen Quelltext nutzen: (Dieser Quelltext stammt von guiguiabloc, http://blog.guiguiabloc.fr/index.php/2012/02/22/pushingbox-vos-notifications-in-the-cloud/22.02.2012)

iimport urllib, urllib2
class pushingbox():
  url = ""
  def __init__(self, key):
    url = 'http://api.pushingbox.com/pushingbox'
    values = {'devid' : key}
    try:
      data = urllib.urlencode(values)
      req = urllib2.Request(url, data)
      sendrequest = urllib2.urlopen(req)
    except Exception, detail:
      print "Error ", detail

Aufruf der Klasse

from PushingBox import pushingbox
key = "v35883B72B89AFAC"
pushingbox(key)

Das Beitragsbild kommt diesmal con Comfreak, Herzlichen Dank !  https://pixabay.com/de/meer-flaschenpost-schiffbr%C3%BCchig-1377712/

Realisierung eines Farberkennungssensors mit Python und OpenCV – Teil 1

In der Praxis gibt es häufig die Aufgabe, die Farbe von Objekten  (z.B, Produkten) automatisch zu erkennen und aus der ermittelten Information irgendwelche Aktionen abzuleiten, sei es das Generieren einer Nachricht oder auch das Schalten eines Relais.

Aus diesem Grunde zeige ich heute, wie man mit sehr wenig Aufwand mittels einer Webcam, einem Rechner (kann auch ein Raspberry Pi sein), Python und OpenCV) ein System erstellt, welche die Farbe eines beliebigen Objektes (repräsentiert durch die 3 Werte des HSV-Farbraumes) digital ermittelt. Dies geschieht, in dem man ein Fadenkreuz auf den interessierenden Bereich des Bildes bewegt. Hierzu lassen sich im Programm folgende Tasten benutzen:

G- nach links

Z- nach oben

J-nach rechts

N- nach unten

Hat mein den interessierenden Farbwert (Hue) gefunden, lässt er sich mit der m -Taste (Memory) abspeichern.

Aus dem hier vorgestellten Code-Snippet lässt sich dann einfach ein Sensor entwickeln, der bei Auftauchen einer vorher festgelegten Farbe  (Farbbereich) eine Aktion auslöst, dies wird dann im Teil 2 dieses Artikel behandelt, wenn Interesse besteht.

Code-snippet Erkennung von Farbwerten in einer Region of Interest (ROI) mit Python 3.x und OpenCV

Dieses Codesnippet einfach in den Editor Deiner Wahl kopieren und mit Python ausführen. nympy und OpenCV müssen installiert sein.

# calculation  of HSV - color values

import numpy as np
import cv2

# initialisiere Webcam
cam = cv2.VideoCapture(0)

cam.set(3,1280)
cam.set(4,720)

# initiale Koordinaten für Auslesung definieren
x, y, w, h = 250, 150, 100, 100

# show stream from WebCam
while cam.isOpened():
    # lese frame von WebCam
    ret, frame = cam.read()

    # convert Frame into HSV
    frame = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)

    # zeige Hue-Wert im Fadenkreuz
    cv2.putText(frame, "HSV: {0}".format(frame[y + 1, x + 1]), (x, 100),
                cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), thickness=2)
    cv2.line(frame,(x-100,y),(x+100,y),(0,0,0),2)
    cv2.line(frame, (x, y-100), (x , y+100), (0, 0, 0), 2)
    cv2.circle(frame,(x, y) ,50 , (0, 0, 0), 2)

    # show complete frame
    cv2.imshow("frame", frame)

    # wait for key
    key = cv2.waitKey(1)
    print (key)
    if key == 106:        # J-Taste
        x=x+5
    elif key == 103:      # G -Taste
        x = x - 5
    elif key == 122:      # Z-Taste
        y = y -5
    elif key == 110:      #  N-Taste
        y = y +5
    elif key == 109:      #  M-Taste (memory)
        HSV_mem = frame [(x,y)]
        H_mem = HSV_mem[0]
        # break
    # wenn ESC gedrueckt, beende Programm
    elif key == 27:
        cv2.destroyAllWindows()
        break

Ergebnisse

Nach Positionierung des Fadenkreuzes auf dem entsprechenden Modellauto werden die HSV- Werte des jeweiligen Modells angezeigt.

Originalansicht des verwendeten „Test-Aufbaus“

Erläuterungen

Das von der Camera gelieferte Bild wird zunächst in den HSV-Farbraum, konvertiert

Der HSV-Farbraum wird in OpenCV in folgenden Wertebereichen gepeichert:

  • Hue (H, Farbwert):  0 bis 180 
  • Saturation (S, Sättigung):  0 bis 255
  • Value (V, Helligkeit):  0 bis 255

Diesr Wertebereich unterscheidet sich von vielen anderen Programmen und Bibliotheken (wie z.B. Gimp), also Vorsicht, das ist die Ursache für einige schwer zu findende Fehler. 

Das Bild liegt jetzt in Form einer Matrix vor, die alle gewünschten Informationen bereitstellt.     Über ein Fadenkreuz, welches sich über das eingelesen Bild mittels der Tasten auf der Tastatur bewegen läßt, wird dem Programm die gewünscht Position für die Farbwertermittlung mitgeteilt. Die HSV-Werte werden jetzt ermittelt und auf dem Bild angezeigt. Zur späteren Weiterverarbeitung läßt sich aktuelle Farbwert durch die „m“-Taste in einer Variable speichern.

Dieser Artikel zeigt natürlich nur de generelle Vorgehensweise. Unter industriellen Bedingungen müsste man sich als erstes um konstante Beleuchtungsbedingen kümmern, um verlässliche Aussagen zu erhalten.

Kanten zählen mit Python und OpenCV

Computer Vision 

Heute stellen wir und der Aufgabe, die Schärfe eines auf dem Datenträger vorliegenden Bildes automatisch zu ermitteln. Hierzu habe ich mir von Pixabay ein Bild ((https://pixabay.com/de/youtuber-blogger-drehbuchautor-2838945 vielen Dank an Lucas!) besorgt und mit Photoshop über den Gaußschen Weichzeichner 3 verschiedene Schärfe-Muster erstellt. Das erste Bild ist unverändert (also scharf), die folgenden wurden mit dem Gaußschen Weichzeichner jeweils mit Einstellung 2px bearbeitet.

Der Lösungsansatz für die Schärfeermittlung ist es, über Python 3.6 und OpenCV 3.x  die Anzahl der Kanten in den Bildern zu ermitteln. Voraussetzung ist, wie bei allen Computer -Vision-Projekten hier, das die OpenCV-Bibliothek auf dem Entwicklungssystem installiert ist. Den verwendeten Algorithmus und Quelltext werde ich in den nächsten Tagen gerne detailliert erklären, falls das gewünscht wird. 

Das lauffähige Code-Snipplet (Python 3.6, OpenCV 3.x) für das Zählen der Kanten (Schärfeermittlung) in einem Bild:

import numpy as np
import cv2
image = cv2.imread("test07.jpg")
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (11, 11), 0)
cv2.imshow("blurred", image)
canny = cv2.Canny(image, 30, 150)
cv2.imshow("Canny-Algorithmus", canny)
edged = cv2.Canny(blurred, 30, 150)
cv2.imshow("Kanten", edged)
(_, cnts, _) = cv2.findContours(edged.copy(), cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
anz= str(len(cnts))
kanten = image.copy()
cv2.putText(kanten, "gezaehlt: "+ anz + " Kanten", (50, 50), cv2.FONT_HERSHEY_SIMPLEX,
0.75, (0, 255, 0), 2)
cv2.drawContours(kanten, cnts, -1, (0, 255, 0), 2)
cv2.imshow("Kanten", kanten)
cv2.waitKey(0)
cv2.destroyAllWindows()

Das sind die 3 Ausgangsbilder, derminimale Schärfeverlust von Bild zu Bild ist mit dem Auge kaum feststellbar

trotzdem fallen die Zählergebnisse des Kantenzählalgorithmus signifikant unterschiedlich aus, was eine sichere automatische Schärfebeurteilung erlaubt.

Zusammenfassung

Der vorgestellte Algorithmus ist sehr gut in der Lage, die Schärfe eines Bildes durch Zählen der Kanten im Bild zu beurteilen. Mit bloßem Auge kaum wahrnehmbare Unterschiede in der Schärfe wirken sich signifikant in der Anzahl der Kanten aus.