2016-07-03 13 views
0

Ich schrieb dieses Skript in Python, um Daten über die serielle Kommunikation an mein Arduino UNO zu senden. Er verwendet die OpenCV-Bibliothek, um ein Binärbild zu verarbeiten, und trifft Entscheidungen basierend auf der Position des erkannten Objekts.Bedingte Anweisungen funktionieren nicht richtig

Hier ist das Skript: -

import numpy as np 
import cv2 
import serial 
ser = serial.Serial('COM3',9600,writeTimeout = 0) 
def f(x): return 
cv2.namedWindow('Thresholding Control') 

# create trackbars for color change 
cv2.createTrackbar('High H','Thresholding Control',179,179, f) 
cv2.createTrackbar('Low H','Thresholding Control',0,179, f) 
cv2.createTrackbar('High S','Thresholding Control',255,255, f) 
cv2.createTrackbar('Low S','Thresholding Control',0,255, f) 
cv2.createTrackbar('High V','Thresholding Control',255,255, f) 
cv2.createTrackbar('Low V','Thresholding Control',0,255, f) 
cv2.createTrackbar('Guassian Blur','Thresholding Control',0,99, f) 

cap = cv2.VideoCapture(0) 
while(True): 
    ret, image = cap.read() 
    HSV = cv2.cvtColor(image, cv2.COLOR_BGR2HSV) 
    # Getting trackbar values 
    highH = cv2.getTrackbarPos('High H','Thresholding Control') 
    lowH = cv2.getTrackbarPos('Low H','Thresholding Control') 
    highS = cv2.getTrackbarPos('High S','Thresholding Control') 
    lowS = cv2.getTrackbarPos('Low S','Thresholding Control') 
    highV = cv2.getTrackbarPos('High V','Thresholding Control') 
    lowV = cv2.getTrackbarPos('Low V','Thresholding Control') 
    # Thresholding the image. 
    thresh = cv2.inRange(HSV, (lowH, lowS, lowV), (highH, highS, highV)) 
    blurVal = cv2.getTrackbarPos('Guassian Blur','Thresholding Control') 
    if(blurVal%2==0): 
     blurVal=blurVal+1 
    thresh_smooth = cv2.GaussianBlur(thresh, (blurVal, blurVal), 0) 
    #Defining the kernel to be used for Morphological ops. 
    kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5)) 
    # Applying Opening and Closing. 
    thresh_smooth = cv2.morphologyEx(thresh_smooth,cv2.MORPH_OPEN,kernel) 
    thresh_smooth = cv2.morphologyEx(thresh_smooth, cv2.MORPH_CLOSE, kernel) 

    eleR = np.count_nonzero(thresh_smooth[0:480, 320:550]) 
    eleL = np.count_nonzero(thresh_smooth[0:480, 0:320]) 
    eleO = np.count_nonzero(thresh_smooth[0:480, 550:640]) 

    if (eleL>eleR and eleL>eleO and eleL!= (eleR+eleO)): 
    cv2.putText(image,"Left Turn", (320,240), cv2.FONT_HERSHEY_SIMPLEX, 2, 255) 
    ser.write('L') 

    if (eleO>eleR and eleO>eleL): 
    cv2.putText(image,"Right Turn", (240,320), cv2.FONT_HERSHEY_SIMPLEX, 2, 255) 
    ser.write('R') 

    else: 
    cv2.putText(image,"Straight", (240,320), cv2.FONT_HERSHEY_SIMPLEX, 2, 255) 
    ser.write('S') 

    cv2.imshow("BGR", image) 
    cv2.imshow("Thresholded", thresh_smooth) 
    print ser.readline(); 
    if cv2.waitKey(1) & 0xFF == ord('q'): 
     break 
cap.release() 
cv2.destroyAllWindows() 

Das Problem hier sind die if Aussagen. Unabhängig von den drei Bedingungen wird unabhängig von der Bedingung nur der Wert "S" (in der Anweisung else) über die serielle Schnittstelle gesendet, wie durch den Befehl print ser.readline() bestätigt. Dann kann plötzlich der Wert eines der if Blöcke gesendet werden und dann wird der gleiche Wert einfach fortgesetzt, egal an welcher Position im Bild das Objekt ist. Die cv2.putText Befehle funktionieren wie erwartet, es ist nur die ser.write, die das Problem verursacht.

Ich versuchte elif anstelle der zweiten if setzen, versuchte auch, in jedem der bedingten blockiert die continue Anweisung setzen, die aus irgendeinem Grunde das Skript während der Laufzeit abstürzt. Keiner von ihnen hat geholfen. Ich habe keine Ahnung, wie ich diesen Fehler beheben kann.

Danke.

UPDATE
versucht die Baudrate auf 115.200 zu erhöhen, hat nicht funktioniert. Setzen Sie einen Kondensator zwischen RESET und GND-Pins, hat nicht funktioniert.

+0

Bevor Ihre if-Suites gedruckt werden, drucken Sie 'ele0, eleR' und' eleL'. Seien Sie sicher, dass Ihre Tests sinnvoll sind –

+0

@joelgoldstick Ich habe, habe einige Werte, jede Bedingung arbeitete entsprechend. Sie machen Sinn. –

+0

Sorry, ich habe etwas verpasst. Kommentar entfernt –

Antwort

0

Okay, ich habe es herausgefunden. Putting, was ich hier gemacht habe, für Leute, die neugierig sind und für diejenigen, die Hilfe brauchen.

Es war wahrscheinlich der Arduino, autoresetoverserialcomm, aus irgendeinem Grund der Arduino automatisch zurückgesetzt, wenn Sie einen Wert über die serielle Kommunikation zum Arduino von einem Computer senden, nicht von der seriellen Schnittstelle (natürlich). Ich wusste das früher, und ein anderes Skript, das auch Daten an den Arduino sendet, funktionierte gut mit diesem Setup.

Was habe ich getan? Ich habe nur einen 10μ Kondensator zwischen den RESET und den GND Pins gesetzt. Das hat anfangs nicht funktioniert, aber ich habe versucht, das + ve des Kondensators in den GND-Pin zu stecken und -ve in den RESET-Pin und voila! Das Skript hat gut funktioniert.

Ich denke, das war überhaupt kein Programmierproblem, aber ein Problem des Arduino und des Skripts nicht in der Lage zu kontaktieren.

Ich bin mir immer noch nicht sicher, was das Problem verursacht hat oder ob das, was ich getan habe, eine permanente Reparatur oder sogar eine Reparatur überhaupt ist, aber mein Problem scheint gelöst worden zu sein. Ich werde den Beitrag weiter aktualisieren.

Anregungen und Diskussionen sind immer willkommen!