问题描述
(抱歉格式化) 我正在尝试编写一个 opencv 程序来跟踪红色。 到目前为止它工作正常,但伺服是抖动的,当物体静止并居中时,伺服来回移动。我有一个 470uf 的电容器和一个外部电源。任何让它更顺畅的帮助都是天赐之物!
'''
from picamera.array import PiRGBArray
from picamera import PiCamera
import time
import cv2
import numpy as np
import RPi.GPIO as GPIO
import time
###SERVO SETUP###
servoPIN_x = 17
servoPIN_y = 18
GPIO.setmode(GPIO.BCM)
GPIO.setup(servoPIN_x,GPIO.OUT)
GPIO.setup(servoPIN_y,GPIO.OUT)
px = GPIO.PWM(servoPIN_x,50)
py = GPIO.PWM(servoPIN_y,50)
position_x = 7.5
position_y = 7.5
px.start(position_x)
py.start(position_y)
x_gain = 0.1#0.01 - 5.00
y_gain = 0.3#0.01 - 5.00
xon = True
yon = True
###CAMERA SETUP##
camera = PiCamera()
camera.resolution = (640,480)
camera.framerate = 32
raw_capture = PiRGBArray(camera,size=(640,480))
time.sleep(0.1)
###VIDEO CAPTURE LOOP###
for frame in camera.capture_continuous(raw_capture,format="bgr",use_video_port=True):
#cv2 video init
image = frame.array
hsv_frame = cv2.cvtColor(image,cv2.COLOR_BGR2HSV)
#color parameters
low_red = np.array([161,155,84])
high_red = np.array([179,255,255])
#find color
red_mask = cv2.inRange(hsv_frame,low_red,high_red)#create black/white mask for all reds
contours,_ = cv2.findContours(red_mask,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)#find different red contours
contours = sorted(contours,key=lambda x:cv2.contourArea(x),reverse=True)#sort contours from largest to smallest
#set line x/y var to center
x_medium=320
y_medium=240
#loop sets x/y_medium
for cnt in contours:
(x,y,w,h) = cv2.boundingRect(cnt)
y_medium = int((y+y+h)/2)
x_medium = int((x+x+w)/2)
cv2.rectangle(image,(x,y),(x+w,y+h),(0,0),2)
break
#draw lines
cv2.line(image,(x_medium,480),2)
cv2.line(image,y_medium),(640,2)
#cv2.imshow('mask',red_mask)
#show regular frame
cv2.imshow("Frame",image)
key = cv2.waitKey(1) & 0xFF
raw_capture.truncate(0)
#quit
if key == ord("q"):
cv2.waitKey(1)
px.stop()
py.stop
break
#servoX travels to place postion_x in center frame
if not xon and x_medium != 320:
px.start(position_x)
if x_medium > 320:
position_x = position_x - x_gain
elif x_medium < 320:
position_x = position_x + x_gain
elif x_medium == 320:
position_x = position_x
xon = False
else:
position_x = 7.5
if xon:
px.ChangeDutyCycle(position_x)
else:
px.stop
px.stop()
py.stop()
cv2.destroyAllWindows()
exit(0)
'''
解决方法
我在构建机器人时遇到了与这种伺服电机相同的问题。我使用另一个名为“pigpio”的库解决了这个问题,以控制 rasperry pi 的引脚。从那以后,伺服系统不再无缘无故地移动。命令非常相似。看看: