Мой opencv-код для обнаружения объектов работает примерно полминуты, а затем останавливается.Когда я перемещаю объект, который он должен обнаружить, с камеры, окна, показывающие рамку (и я предполагаю, что код также), размораживаются до тех пор, пока я не верну объект в поле зрения камеры (он сразу же замерзнет, если распознаетобъект).
У меня есть последовательная связь, подключенная от сценария opencv к arduino, который управляет двигателями, которые ориентируют камеру так, что обнаруживаемый мной объект перемещается в центр камеры POV.
Я подумал, что это может быть проблема с обработкой, поэтому я избавился от команд .erode()
и .dilate()
, но это ничего не изменило.Кажется, что код зависает либо во время создания цветовой маски, либо во время поиска контуров.
Код Python
import cv2
import numpy
import serial
import time
ser=serial.Serial("COM11", 9600) #open serial port
def nothing(x):
pass
capture=cv2.VideoCapture(0)
while capture.isOpened:
lower_hsv=numpy.array([60, 90, 116]) #hsv values set so that it only sees a certain shade of blue
upper_hsv=numpy.array([125, 251, 255])
ret, frame=capture.read()
blur=cv2.GaussianBlur(frame, (5,5), 0) #blurs the BGR
hsv=cv2.cvtColor(blur,cv2.COLOR_BGR2HSV) #changes blurred BGR to HSV
mask=cv2.inRange(hsv, lower_hsv, upper_hsv)
mask=cv2.erode(mask, None, iterations=2)
mask=cv2.dilate(mask, None, iterations=2)
contours,_=cv2.findContours(mask.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
if len(contours)>0:
for contour in contours:
if cv2.contourArea(contour) < 800:
continue
else:
(x,y), radius=cv2.minEnclosingCircle(contour)
center=(int(x), int(y))
radius=int(radius)
cv2.circle(frame, center, radius, (0, 255, 0), 2)
print(center)
if center[0]<300:
ser.write('L'.encode()) #if ball is to the left, rotate the motor to the left
elif center[0]>340:
ser.write('R'.encode()) #if ball is to the right, rotate motor to the right
elif center[1]<220:
ser.write('D'.encode()) #if the ball is below, rotate the motor down
elif center[1]>260:
ser.write('U'.encode())
else:
print('not sending anything')
result=cv2.bitwise_and(frame, frame, mask=mask)
cv2.imshow('original',frame)
if cv2.waitKey(1)==27:
break
cv2.destroyAllWindows()
capture.release()
Код Arduino
const int motorA_1 = 9;
const int motorA_2 = 10;
const int motorB_1 = 5;
const int motorB_2 = 6;
char inputData;
void setup() {
// put your setup code here, to run once:
pinMode(motorA_1, OUTPUT);
pinMode(motorA_2, OUTPUT);
pinMode(motorB_1, OUTPUT);
pinMode(motorB_2, OUTPUT);
Serial.begin(9600);
Serial.println("<Arduino is ready>");
}
void loop() {
// put your main code here, to run repeatedly:
if (Serial.available()>0){
inputData=Serial.read();
if (inputData == 'R'){
digitalWrite(motorA_1,HIGH);
digitalWrite(motorA_2,LOW);
delay(10);
}
else if(inputData=='L'){
digitalWrite(motorA_1,LOW);
digitalWrite(motorA_2,HIGH);
delay(10);
}
else if(inputData=='U'){
digitalWrite(motorB_1,HIGH);
digitalWrite(motorB_2,LOW);
delay(10);
}
else if(inputData=='D'){
digitalWrite(motorB_1,LOW);
digitalWrite(motorB_2,HIGH);
delay(10);
}
}
else{
doNothing();
}
}
void doNothing(){
Serial.println("doing nothing");
digitalWrite(motorA_1, LOW);
digitalWrite(motorA_2, LOW);
digitalWrite(motorB_1, LOW);
digitalWrite(motorB_2, LOW);
delay(20);
Я хочу, чтобы скрипт запускался до тех пор, пока я не завершу его нажатием клавиши «esc», но он завершится сбоем, если я выполню его более 30 секунд.