【问题标题】:How to capture a picture after every 5 seconds of camera using opencv python and Raspbery Pi 3?如何使用opencv python和Raspbery Pi 3在相机每5秒后拍摄一张照片?
【发布时间】:2018-03-15 11:40:08
【问题描述】:

我正在做一个与使用 OpenCV Python 和 Raspberry Pi 3 进行图像处理相关的学校项目。

Raspberry Pi 3 的硬件无法连续处理来自摄像头的视频,因此我正在考虑每隔 5 秒从摄像头拍摄一张照片并用它来识别我需要的内容,然后继续。

我在互联网上做了一些研究,发现了一个名为 time.sleep(5) 的函数,但是这个函数只会暂停相机 5 秒然后继续。

谁能帮我解决我的问题。太感谢了。 对不起我的英语不好,这是我到目前为止的代码。在我的代码中,我先使用视频进行测试,然后在找到解决方案后,我会在相机上应用。

import cv2
import numpy as np
import time

headcc = cv2.CascadeClassifier('lib/heads_cascade.xml')
cap = cv2.VideoCapture('image/hockey_game.avi')

def video():
    ret, frame = cap.read()

    # gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    head = headcc.detectMultiScale(frame, 1.2, 2, 0 , (20, 20), (40, 40))

    print type(head)
    print head
    print head.shape
    print "Number of heads detected: " + str(head.shape[0])


    if len(head) > 0:
        for (x, y, w, h) in head:
            cv2.rectangle(frame, (x,y), (x+w, y+h), (0, 255, 255), 1)

    cv2.rectangle(frame, ((0,frame.shape[0] -25)),(270, frame.shape[0]), (255,255,255), -1)
    cv2.putText(frame, "Number of head detected: " + str(head.shape[0]), (0,frame.shape[0] -10), cv2.FONT_HERSHEY_TRIPLEX, 0.5,  (0,0,0), 1)

    cv2.namedWindow('Camera',cv2.WINDOW_NORMAL)
    cv2.imshow('Camera',frame)


while(cap.isOpened()):
    video()
    time.sleep(5)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()

2018 年 3 月 15 日更新: 感谢乔的评论,我找到了跳过帧的方法。但是,程序仍然无法知道视频是否结束,并且fps代码仍然出现0.0。因此,如果对这些错误有任何帮助,我将不胜感激。到目前为止的代码如下:

import cv2
import numpy as np
import time

headcc = cv2.CascadeClassifier('lib/heads_cascade.xml')
cap = cv2.VideoCapture('image/hockey_game.avi')
fps = cap.get(cv2.CAP_PROP_POS_FRAMES)

def video():
    ret, frame = cap.read()

    # gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    head = headcc.detectMultiScale(frame, 1.2, 2, 0 , (20, 20), (40, 40))

    # print type(head)
    # print head
    # print head.shape
    print "Number of heads detected: " + str(head.shape[0])

    if len(head) > 0:
        for (x, y, w, h) in head:
            cv2.rectangle(frame, (x,y), (x+w, y+h), (0, 255, 255), 1)

    # cv2.rectangle(frame, ((0,frame.shape[0] -25)),(270, frame.shape[0]), (255,255,255), -1)
    # cv2.putText(frame, "Number of head detected: " + str(head.shape[0]), (0,frame.shape[0] -10), cv2.FONT_HERSHEY_TRIPLEX, 0.5,  (0,0,0), 1)

    cv2.namedWindow('Camera',cv2.WINDOW_NORMAL)
    cv2.imshow('Camera',frame)


while(cap.isOpened()):
    video()
    cf = cap.get(cv2.CAP_PROP_POS_FRAMES) - 1
    cap.set(cv2.CAP_PROP_POS_FRAMES, cf+50)
    # cv2.setTrackbarPos("pos_trackbar", "Frame Grabber", 
int(cap.get(cv2.CAP_PROP_FPS)))
    time.sleep(2)
    if (cv2.waitKey(1) & 0xFF == ord('q')):
        break

print fps
cap.release()
cv2.destroyAllWindows()

【问题讨论】:

    标签: python opencv image-processing embedded-linux raspberry-pi3


    【解决方案1】:

    documentation 状态

    VideoCapture::read
    Grabs, decodes and returns the next video frame.
    

    您的视频可能每秒有 25 帧,您正在逐一阅读。

    如果这是您所期望的,视频不会在后台播放。 您的 video() 函数只是逐帧遍历它。

    解决方案是真正从设备中获取(read 函数也可以获取设备 ID,请参阅文档)。

    device – id of the opened video capturing device (i.e. a camera index).
    

    类似

    # something like
    cap = cv2.VideoCapture('/dev/video0') 
    

    另一种方法是使用跳过帧

    VideoCapture::grab
    

    如上所述here

    通过这种方式,您可以快速绕过任意数量的帧。

    grab() 似乎相当快,因为​​它不解码帧。所以你可以找出你的视频每秒有多少帧。然后拨打.read(),然后拨打.grab(),就像您的视频在5秒内有帧一样频繁。然后再次拨打.read()

    或者真的将图片保存到磁盘并处理它们。

    【讨论】:

    • 感谢您的建议,我已经找到了在我的代码中跳帧的方法。但是,当视频结束时,代码仍在运行并出现错误。那么如何避免该错误并让程序知道视频何时结束。非常感谢。 P/s:我更新了帖子中的代码。
    • 只检查grab的返回值:“方法/函数从视频文件或相机中抓取下一帧,如果成功则返回true(非零)。”并且仅在抓取成功时才检索抓取的图像。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-29
    • 2018-12-20
    • 1970-01-01
    • 2015-07-17
    • 1970-01-01
    相关资源
    最近更新 更多