我用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引脚之间放一个电容,不工作
好吧,我明白了。把我所做的放在这里,给那些好奇的人和那些需要帮助的人。
这可能是Arduino, autoresetoverserialcomm,由于某种原因,当你从计算机发送一个值到串行通信到Arduino时,Arduino会自动重置,而不是从串行端口(显然)。我之前知道这一点,我的另一个脚本也向Arduino发送数据,在这个设置下工作得很好。
我做了什么?我只是在RESET和GND引脚之间放了一个10µ电容。这最初不起作用,但我试着把电容器的+ve放在GND引脚上,-ve放在RESET引脚上,瞧!脚本开始运行正常。
我想这根本不是编程问题,而是Arduino和脚本无法相互联系的问题。
我仍然不确定是什么原因导致了这个问题,或者我所做的是一个永久性修复,或者甚至是一个修复,但我的问题似乎已经解决了。我会继续更新的。
随时欢迎提出建议和讨论!