Kameraansteuerung

Python auf Einplatinencomputer wie Raspberry Pi, Banana Pi / Python für Micro-Controller
Nicky200
User
Beiträge: 14
Registriert: Mittwoch 19. Februar 2020, 20:00

Hallo liebe Forumsmitglieder,
ich habe ein dringendes Problem bei der Ausführung eines Skriptes in Python beim Ansteuern einer Kamera via Raspberry.
Bei der Ausführung des Codeteiles der die Distanz zwischen zwei Punkten messen soll kommt es zu im Anhang befindlicher Fehlermeldung.
Skript (Word) und Fehlermeldung im Anhang. Im Skript sind zum Teil Notizen von mir.
Bitte um Hilfe, die Geschichte sollte am Freitag laufen. Projektwoche HTL.

Danke
Nicolas
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

Hier im Forum gibt es keine Anhänge. Poste den Code und die Fehlermeldung direkt im Beitrag.
Benutzeravatar
sparrow
User
Beiträge: 4187
Registriert: Freitag 17. April 2009, 10:28

Und den Code bitte in Code-Tags. Die werden automatisch eingefügt, wenn man im vollständigrm Editor & Vorschau auf den </> Button drückt.
Nicky200
User
Beiträge: 14
Registriert: Mittwoch 19. Februar 2020, 20:00

Hallo,

Danke für die schnelle Antwort. Hier jetzt noch der Code und die Fehlermeldung nachgereicht.

Hier der Code:

Code: Alles auswählen

from scipy.spatial import distance as dist
from imutils import perspective
import picamera
import RPi.GPIO as GPIO
import time  
import imutils
import cv2
import numpy as np
import argparse 
import io 

GPIO.setmode(GPIO.BCM)


GPIO.setup(26, GPIO.IN)
GPIO.input(26) 
GPIO.setup(20, GPIO.OUT) 
GPIO.setup(16, GPIO.OUT)
GPIO.setup(12, GPIO.OUT)
GPIO.setup(7, GPIO.OUT)



   
while True: 
    if GPIO.input(26) == 0: 
        #LOW - Pegel
        
        # Setup the camera such that it closes
        #when we are done with it.  

        print("About take a picture")
        with picamera.PiCamera() as camera:
            camera.resolution = (1280,720)
            camera.capture("/var/www/html/Projekt/Testbild.jpg")
            print("Picture taken.") 
    else: 
    	#HIGH - Pegel
        
        def midpoint(ptA, ptB):
            return ((ptA[0] + ptB[0]) * 0.5, (ptA[1] + ptB[1]) * 0.5)    
        gray = cv2.imread ("/var/www/html/Projekt/Laiserbild",0)
       
        edged = cv2.Canny(gray, 50,100)
        edged = cv2.dilate(edged, None, iterations=1)
        edged = cv2.erode(edged, None, interations=1)
        
        cnts = cv2.findContours(edged.copy(), cv2.RETR_EXTERNAL, 
            cv2.CHAIN_APPROX_SIMPLE)
        cnts = imutils.grab_contours (cnts)
        
        (cntrs, _) = contours.sort_contours(cntrs)
        colors = ((0, 0, 255), (240, 0, 159), (0, 165, 255), (255, 255, 0), (255, 0, 255))
        refObj = None 
        
        for c in cnts:
        
            if cv2.contourArea(c) > 1:
                continue
        
        box = cv2. minAreaRect (c)
        box = cv2. boxPoints (box) if imutils.is_cv2() else  cv2.boxPoints (box)
        box = np.array(box, dtype="int")
        
        box = perspective.order_points(box)
        
        cX = np.average(box[:,0])
        cY = np.average(box[:, 1])
        
        if refObj is None: 
            (tl, tr, br, bl) = box
            (tlblX, tlblY) = midpoint(tl, bl)
            (trbrX, trbrY) = midpoint (tr, br)
            
            D = dist.euclidean ((tblX, tlblY), (trbrX, trbrY))
            refObj = (box, (cX, CY), D / 0.21)
            continue
        
        orig = image.copy()
        cv2.drawContrours(orig, [box.astype("int")],-1, (0,255, 0), 2)
        cv2.drawContours(orig, [refObj[0].astype("int")], -1, (0, 255, 0), 2)
        
        refCoords = np.vstack([refObj[0], refObj[1]])
        objCoords = np.vstack([box, (cX, cY)])
        
        for ((xA, yA), (xB, yB), color) in zip(refCoords, objCoords, colors):
        
            cv2.circle(orig, (int(xA), int(yA)), 5, color, -1)
            cv2.circle(orig, (int(xB), int(yB)), 5, color, -1)
            cv2.line(orig, (int(xA), int(yA)), (int(xB), int(yB)),
                color, 2)
            
            D = dist.euclidean((xA, yA), (xB, yB)) / refObj[2]
            (mX, mY) = midpoint((xA, yA), (xB, yB))
            cv2.putText(orig, "{:.1f}in".format(D), (int(mX), int(mY - 10)),
			cv2.FONT_HERSHEY_SIMPLEX, 0.55, color, 2)
            
            if D <= 0.3:
               GPIO.output(20, GPIO.HIGH)
               GPIO.output(16, GPIO.LOW)
               GPIO.output(12, GPIO.LOW)
               GPIO.output(7, GPIO.LOW)
               GPIO.output(8, GPIO.LOW)
               
            elif (D > 0.3) & (D <= 0.6): 
               GPIO.output(20, GPIO.LOW)
               GPIO.output(16, GPIO.HIGH)
               GPIO.output(12, GPIO.LOW)
               GPIO.output(7, GPIO.LOW)
               
            elif (D > 0.6) & (D <= 0.9): 
               GPIO.output(20, GPIO.LOW)
               GPIO.output(16, GPIO.LOW)
               GPIO.output(12, GPIO.HIGH)
               GPIO.output(7, GPIO.LOW)
               
            elif (D > 0.9 )& (D <= 1.2): 
               GPIO.output(20, GPIO.LOW)
               GPIO.output(16, GPIO.LOW)
               GPIO.output(12, GPIO.HIGH)
               GPIO.output(7, GPIO.LOW)
               
            elif D > 1.2:  
               GPIO.output(20, GPIO.LOW)
               GPIO.output(16, GPIO.LOW)
               GPIO.output(12, GPIO.LOW)
               GPIO.output(7, GPIO.HIGH)
            
        cv2.imshow("image", image)
        cv2.imshow("Copy", orig)
    time.sleep(0.0001)
    continue
und hier die Fehlermeldung:

OpenCV(3.4.1) Error: Assertion failed (dims <= 2 && step[0] > 0) in locateROI, file /home/pi/opencv-3.4.1/modules/core/src/matrix.cpp, line 760
Traceback (most recent call last):
File "ProjektOpenCV.py", line 45, in <module>
edged = cv2.dilate(edged, None, iterations=1)
cv2.error: OpenCV(3.4.1) /home/pi/opencv-3.4.1/modules/core/src/matrix.cpp:760: error: (-215) dims <= 2 && step[0] > 0 in function locateROI

Hoffe, jemand hat eine Idee.

Danke
Nicolas
Benutzeravatar
sparrow
User
Beiträge: 4187
Registriert: Freitag 17. April 2009, 10:28

Ich habe noch nie mit cv2 gearbeitet, aber bist du dir sicher, dass der 2. Parameter der Funktion None sein darf?
Nicky200
User
Beiträge: 14
Registriert: Mittwoch 19. Februar 2020, 20:00

Sicher nicht, aber habe andere Codes gesehen, welche den 2. Paramter auf None gesetzt haben. Diese Leute behaupteten immer, dass der Code funktioniert hat.
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

`argparse` und `io` werden importiert aber nicht genutzt. GPIO.cleanup wird nicht aufgerufen. Die while-Schleife ist viel zu lang und sollte in mehrere Funktionen aufgeteilt werden. Ein `continue` als letzten Befehl in der Schleife ist unsinnig. Du mischst Tabs und Leerzeichen-Einrückung, das sollte nicht passieren.
Funktionen werden auf oberster Ebene definiert, nicht irgendwo tief verschachtelt in einer while-Schleife.
& ist ein Bit-Operator, was Du suchst ist das logische `and`. Dann sind auch die Klammern um die Bedingungen überflüssig. Die erste Bedingung ist eh immer überflüssig, da Du mit elif arbeitest. Bei D<=0.3 wird ein Pin 8 gesetzt, obwohl der nie initialisiert wurde. Da ist wohl ein Fehler. Man sollte keinen Code wiederholen, sondern ein passendes Konstrukt nutzen.

Benutze keine Abkürzungen, aus contours wird cntrs oder cnts? Welches davon ist jetzt richtig?
Der Fehler kommt dann wahrscheinlich davon, dass Du zwar behauptest, ein Graustufenbild zu haben, in Wirklichkeit ist es aber RGB.

Die for-Schleife über c ist unsinnig. Entweder ist danach alles falsch eingerückt, oder Du willst damit irgendetwas anderes erreichen?
Die Verwendung von refObj und continue läßt ersteres vermuten. Wie weit der for-Block dann aber gehen soll, ???
Nicky200
User
Beiträge: 14
Registriert: Mittwoch 19. Februar 2020, 20:00

Danke für die Antwort.

Habe mich bei meinen Code an den Code von folgender Seite orientiert:

https://www.pyimagesearch.com/2016/04/0 ... th-opencv/
Nicky200
User
Beiträge: 14
Registriert: Mittwoch 19. Februar 2020, 20:00

Gehe den Code jetzt nochmal nach deinen Tipps durch.

Danke
Nicolas
Nicky200
User
Beiträge: 14
Registriert: Mittwoch 19. Februar 2020, 20:00

Hallo,

Habe mir den Code noch einmal angeschaut.

Folgende Fehler habe ich ausgebessert:
  • Bei D <= 0.3 Pin 8 entfernt
  • Das cntrs zu cnts geändert
  • Bei edged = cv2.erode (edged, None, interations=1) gehört das n nicht hin
Würde mich über weitere Hilfe sehr freuen.

Danke
Nicolas
Nicky200
User
Beiträge: 14
Registriert: Mittwoch 19. Februar 2020, 20:00

Interessant vielleicht noch anzumerken ist, dass wenn ich am Pin 26 keinen HIGH - Pegel anlege, die Fotos von der Kamera normal gemacht werden. Der Fehler erscheint erst , sobald ich Spannung am Pin anlege.
__deets__
User
Beiträge: 14528
Registriert: Mittwoch 14. Oktober 2015, 14:29

Naja, du machst ja nichts mit Opencv in dem Fall. Natürlich passiert dann nichts.

Bau mal imshows und waitkeys ein nach jedem berechnungsschritt. Ob die Bilder so aussehen, wie gewünscht. Und schau auf den shape der Bilder, da ist offensichtlich was falsch, denn das sagt der assert aus.
Nicky200
User
Beiträge: 14
Registriert: Mittwoch 19. Februar 2020, 20:00

Wenn ich imshow und waitkeys dort einbaue,
bekomme ich folgende Fehlermeldung:

OpenCV(3.4.1) Error: Assertion failed (size.width>0 && size.height>0) in imshow, file /home/pi/opencv-3.4.1/modules/highgui/src/window.cpp, line 356
Traceback (most recent call last):
File "ProjektOpenCV.py", line 45, in <module>
cv2.imshow("Bild",edged)
cv2.error: OpenCV(3.4.1) /home/pi/opencv-3.4.1/modules/highgui/src/window.cpp:356: error: (-215) size.width>0 && size.height>0 in function imshow

Code:

Code: Alles auswählen

from scipy.spatial import distance as dist
from imutils import perspective
import picamera
import RPi.GPIO as GPIO
import time  
import imutils
import cv2
import numpy as np
import argparse 
import io 

GPIO.setmode(GPIO.BCM)


GPIO.setup(26, GPIO.IN)
GPIO.input(26) 
GPIO.setup(20, GPIO.OUT) 
GPIO.setup(16, GPIO.OUT)
GPIO.setup(12, GPIO.OUT)
GPIO.setup(7, GPIO.OUT)



   
while True: 
    if GPIO.input(26) == 0: 
        #LOW - Pegel
        
        # Setup the camera such that it closes
        #when we are done with it.  

        print("About take a picture")
        with picamera.PiCamera() as camera:
            camera.resolution = (1280,720)
            camera.capture("/var/www/html/Projekt/Testbild.jpg")
            print("Picture taken.") 
    else: 
    	#HIGH - Pegel
        
        def midpoint(ptA, ptB):
            return ((ptA[0] + ptB[0]) * 0.5, (ptA[1] + ptB[1]) * 0.5)    
        gray = cv2.imread ("/var/www/html/Projekt/Laiserbild",0)
       
        edged = cv2.Canny(gray, 50,100)
        cv2.imshow("Bild",edged)
        cv2.waitkeys(0)
        edged = cv2.dilate(edged, None, iterations=1)
        edged = cv2.erode(edged, None, iterations=1)
        
        cnts = cv2.findContours(edged.copy(), cv2.RETR_EXTERNAL, 
            cv2.CHAIN_APPROX_SIMPLE)
        cnts = imutils.grab_contours (cnts)
        
        (cnts, _) = contours.sort_contours(cnts)
        colors = ((0, 0, 255), (240, 0, 159), (0, 165, 255), (255, 255, 0), (255, 0, 255))
        refObj = None 
        
        for c in cnts:
        
            if cv2.contourArea(c) > 1:
                continue
        
        box = cv2. minAreaRect (c)
        box = cv2. boxPoints (box) if imutils.is_cv2() else  cv2.boxPoints (box)
        box = np.array(box, dtype="int")
        
        box = perspective.order_points(box)
        
        cX = np.average(box[:,0])
        cY = np.average(box[:, 1])
        
        if refObj is None: 
            (tl, tr, br, bl) = box
            (tlblX, tlblY) = midpoint(tl, bl)
            (trbrX, trbrY) = midpoint (tr, br)
            
            D = dist.euclidean ((tblX, tlblY), (trbrX, trbrY))
            refObj = (box, (cX, CY), D / 0.21)
            continue
        
        orig = image.copy()
        cv2.drawContrours(orig, [box.astype("int")],-1, (0,255, 0), 2)
        cv2.drawContours(orig, [refObj[0].astype("int")], -1, (0, 255, 0), 2)
        
        refCoords = np.vstack([refObj[0], refObj[1]])
        objCoords = np.vstack([box, (cX, cY)])
        
        for ((xA, yA), (xB, yB), color) in zip(refCoords, objCoords, colors):
        
            cv2.circle(orig, (int(xA), int(yA)), 5, color, -1)
            cv2.circle(orig, (int(xB), int(yB)), 5, color, -1)
            cv2.line(orig, (int(xA), int(yA)), (int(xB), int(yB)),
                color, 2)
            
            D = dist.euclidean((xA, yA), (xB, yB)) / refObj[2]
            (mX, mY) = midpoint((xA, yA), (xB, yB))
            cv2.putText(orig, "{:.1f}in".format(D), (int(mX), int(mY - 10)),
			cv2.FONT_HERSHEY_SIMPLEX, 0.55, color, 2)
            
            if D <= 0.3:
               GPIO.output(20, GPIO.HIGH)
               GPIO.output(16, GPIO.LOW)
               GPIO.output(12, GPIO.LOW)
               GPIO.output(7, GPIO.LOW)
               
               
            elif (D > 0.3) & (D <= 0.6): 
               GPIO.output(20, GPIO.LOW)
               GPIO.output(16, GPIO.HIGH)
               GPIO.output(12, GPIO.LOW)
               GPIO.output(7, GPIO.LOW)
               
            elif (D > 0.6) & (D <= 0.9): 
               GPIO.output(20, GPIO.LOW)
               GPIO.output(16, GPIO.LOW)
               GPIO.output(12, GPIO.HIGH)
               GPIO.output(7, GPIO.LOW)
               
            elif (D > 0.9 )& (D <= 1.2): 
               GPIO.output(20, GPIO.LOW)
               GPIO.output(16, GPIO.LOW)
               GPIO.output(12, GPIO.HIGH)
               GPIO.output(7, GPIO.LOW)
               
            elif D > 1.2:  
               GPIO.output(20, GPIO.LOW)
               GPIO.output(16, GPIO.LOW)
               GPIO.output(12, GPIO.LOW)
               GPIO.output(7, GPIO.HIGH)
            
        cv2.imshow("image", image)
        cv2.imshow("Copy", orig)
    time.sleep(0.0001)
GPIO.cleanup()
    
Benutzeravatar
__blackjack__
User
Beiträge: 13077
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Nicky200: Na dann schau Dir am besten mal `gray` an. Also nicht als Bild sondern per `print()`. Ich vermute mal die Datei gibt's nicht oder sie kann nicht geladen werden. Die `cv2`-API ist an der Stelle ein bisschen (sehr) blöd weil die keine Ausnahmen kennt. Man muss im Grunde jeden Rückgabewert auf Gültigkeit prüfen, wie in C.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Nicky200
User
Beiträge: 14
Registriert: Mittwoch 19. Februar 2020, 20:00

@_blackjack_User: Danke für die Antwort. Habe dies nun gemacht. Die Datei war nicht vorhanden. Die Fehlermeldung von Anfang erscheint nicht mehr. Schaue allerdings gerade wegen einer anderen Fehlermeldung, welche lautet:

Traceback (most recent call last):
File "ProjektOpenCV.py", line 52, in <module>
(cnts, _) = contours.sort_contours(cnts)
NameError: name 'contours' is not defined

contours scheint nicht definiert zu sein.

Auf jeden Fall Danke bei der Lösung des einen Problems.

Nicolas
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

Die ganzen weiteren Fehler, die jetzt auftauchen werden, habe ich Dir schon in meiner ersten Antwort geschrieben. `contours.sort_contours` scheint irgendeine Funktion zu sein, die jemand, der so ein Tutorial zusammengeschustert hat, selbst programmiert oder selbst von irgendwo anders kopiert hat, oder von wo kopiert, wo es von woanders kopiert wurde, wo es von wo anders kopiert wurde, ...
Nicky200
User
Beiträge: 14
Registriert: Mittwoch 19. Februar 2020, 20:00

Allerdings bekomme ich bei cv2. imread für gray und edged folgende Fehlermeldung:

Traceback (most recent call last):
File "ProjektOpenCV.py", line 45, in <module>
cv2.imread("gray",gray)
TypeError: only length-1 arrays can be converted to Python scalars

Danke für die Hilfe
Nicolas
Nicky200
User
Beiträge: 14
Registriert: Mittwoch 19. Februar 2020, 20:00

@Sirius3 Danke, werde es mir nocheinmal anschauen
einfachTobi
User
Beiträge: 491
Registriert: Mittwoch 13. November 2019, 08:38

Dabei handelt es sich um die `imutils`-Lib des Autos vom pyimagesearch-Blog. Hier mit einigen Beispielen zur Verwendung zu finden: https://github.com/jrosebr1/imutils.

Dann musst du mal prüfen, was in `gray` tatsächlich steckt. Da sollte ein einzelner Wert drin stecken. Ist das der Fall? Oder willst du eigentlich das Bild anzeigen und imshow("gray", gray) verwenden?
Nicky200
User
Beiträge: 14
Registriert: Mittwoch 19. Februar 2020, 20:00

@einfachTobi Vielen Dank für die Antwort
Werde dies gleich überprüfen
Antworten