【问题标题】:Raspberry Pi + Camera + Stepper Motors + Open CV树莓派 + 相机 + 步进电机 + Open CV
【发布时间】:2019-04-06 15:50:23
【问题描述】:

我编写了一个程序,该程序基本上使用步进电机 + a4988 驱动程序将托盘放在连接到 Raspberry Pi 的相机下。代码将托盘带到起始位置,迈出一步,拍照并重复此操作 10 次。然后托盘返回到起始位置。我应该得到的是托盘每个部分的 10 张照片,以及托盘上的任何东西。

但是,我得到的是 7 张完全相同的照片,然后是 3 张不同的照片,我不知道为什么。

我认为相机拍摄照片的速度比托盘移动的速度要快,但从代码中我不明白为什么会这样。

我使用 openCV 来获取照片,因为我计划分析每张照片。

谢谢!!

这是我的代码:

from time import sleep
import RPi.GPIO as GPIO
import cv2

cam = cv2.VideoCapture(0)

DIR = 20   # Direction GPIO Pin
STEP = 21  # Step GPIO Pin
CW = 1     # Clockwise Rotation
CCW = 0    # Counterclockwise Rotation
SPR = 200   # Steps per Revolution (360 / 1.8)

GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.setup(DIR, GPIO.OUT)
GPIO.setup(STEP, GPIO.OUT)
GPIO.output(DIR, CW)

MODE = (14, 15, 18)   # Microstep Resolution GPIO Pins
GPIO.setup(MODE, GPIO.OUT)
RESOLUTION = {'Full': (0, 0, 0),
              'Half': (1, 0, 0),
              '1/4': (0, 1, 0),
              '1/8': (1, 1, 0),
              '1/16': (1, 1, 1),}

GPIO.output(MODE, RESOLUTION['1/16'])
delay2 = 0.0208/32
GPIO.output(DIR, CCW)
for x in range (1500): # Brings Tray to level of first photo
    GPIO.output(STEP, GPIO.HIGH)
    sleep(delay2)
    GPIO.output(STEP, GPIO.LOW)
    sleep(delay2)
sleep(.5)
for a in range (0,9): # Begins 10 photos
    for b in range (250): #Motor steps between photos
        GPIO.output(STEP, GPIO.HIGH)
        sleep(delay2)
        GPIO.output(STEP, GPIO.LOW)
        sleep(delay2)
    sleep(.5)

    ret, frame = cam.read() #Sets up cam for photo
    cv2.imwrite("image"+str(a)+".jpg", frame)  #Write photo to file
    sleep(2)

GPIO.output(DIR, CW)
for x in range(3750): # Pushes Tray out to original starting position
    GPIO.output(STEP, GPIO.HIGH)
    sleep(delay2)
    GPIO.output(STEP, GPIO.LOW)
    sleep(delay2)
sleep(.5)

cam.release()
GPIO.cleanup()

【问题讨论】:

  • 您是否尝试将所有延迟设置为 2 秒或类似的荒谬的东西?这应该会告诉你同步问题在哪里。
  • 是的,最多 3 秒,图像文件是在每个步骤中生成的,而不是我所期望的如果照片是在奇怪的时间拍摄的一次生成的。前 7 张照片始终相同,后 3 张正确。
  • 我还在拍照的每一步之间设置了睡眠,以让相机“热身”,但还是一样
  • 我认为相机会缓冲 5 帧,因此您需要一直(连续)阅读并丢弃不需要的。
  • 马克可能是对的,也尝试在相机循环之前开始视频捕捉呼叫

标签: python opencv raspberry-pi


【解决方案1】:

感谢 Mark 和 Matt 解决了这个问题。感谢你的帮助。通过在每个电机步骤调用视频捕获然后每次释放它来解决。

代码如下:

for a in range(1,10):
cam=cv2.VideoCapture(0)
ret, frame = cam.read()
cv2.imwrite('iamge'+str(a)+"jpg", frame)
cam.release

...等等等等

因此,对于每一步,相机都会被调用和释放,这似乎可以解决问题

谢谢大家

【讨论】:

  • 每次拍摄时打开和关闭相机并不理想——您不妨拍摄静止图像(照片而不是视频)。也许考虑让第二个线程保持相机打开并以循环方式连续获取 4 个缓冲区,并在处理线程中需要时获取最后一个完整帧。