条件语句无法正常工作

时间:2016-07-03 19:06:07

标签: python opencv image-processing arduino-uno pyserial

我在python中编写了这个脚本,通过串口通信将数据发送到我的Arduino UNO。它使用OpenCV库处理二进制图像,并根据检测到的对象的位置做出决定。

这是脚本: -

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()

这里的问题是if语句。在这三个条件中,无论哪个条件为真,只有值'S'(在else语句中)通过串行发送,由print ser.readline()命令确认。然后突然发送任何if块的值,然后相同的值继续,无论对象是在图像中的什么位置。 cv2.putText命令按预期工作,只是引起问题的ser.write

我尝试用elif代替第二个if,还尝试在每个条件块中放置continue语句,这在某些原因会在运行时崩溃脚本。他们都没有帮助。我不知道如何修复这个错误。

感谢。

更新
试图将波特率提高到115200,没有用。在RESET和GND引脚之间放一个电容,不起作用。

1 个答案:

答案 0 :(得分:0)

好吧我明白了。把我在这里所做的,给那些好奇的人和那些需要帮助的人。

可能是Arduino,autoresetoverserialcomm,出于某种原因Arduino会自动重置,无论何时通过串行通信从计算机向Arduino发送值,而不是从串口(显然)。我之前已经知道了,我的另一个脚本也将数据发送到Arduino,这个设置正常。

我做了什么?我只需在RESET和GND引脚之间放一个10μ电容。这在最初没有用,但是我尝试将电容器的+ ve放在GND引脚中,-ve放在RESET引脚中,然后瞧!该脚本开始正常工作。

我想这根本不是编程问题,而是Arduino和脚本无法相互联系的问题。

我仍然不确定导致问题的原因或我所做的是永久性修复,甚至修复,但我的问题似乎已经解决了。我会不断更新帖子。

欢迎提出建议和讨论!