How to capture a picture after every 5 seconds of camera using opencv python and Raspbery Pi 3?

空扰寡人 提交于 2020-01-25 07:40:26

问题


I am working on a school project which is related to Image Processing using OpenCV Python and Raspberry Pi 3.

The hardware of Raspberry Pi 3 cannot handle the video from camera consecutively, therefore I'm thinking about only capture a picture after every 5 seconds from the camera and use it to recognize what I need, then continue.

I did some research on the internet and found a function called time.sleep(5), however this function only pause the camera 5 seconds and then continue.

Can anyone help me to solve my problem. Thank you so much. Sorry for my bad English, here is my code so far. In my code, I use a video to test first, then when figure out the solution, I will apply on camera.

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()

Update March 15th, 2018: Thanks to comment from Joe, I have found the way to skip frames. However, the program still cannot know whether the video ends, and also the fps code still appear 0.0. So if there is any help for these errors, I will really appreciate. Here is the code so far:

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()

回答1:


The documentation states

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

Your video probably has 25 frames per second and you are reading them one by one.

The video is not playing in the background if that is what you expected. Your video() function just iterates through it frame by frame.

Solutions would be to really grab from the device (the read function can also take a device id, see doc).

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

Something like

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

Another way would be to skip frames using

VideoCapture::grab

as described here

This way you can quickly bypass however many frames you want.

grab() seems to rather fast, as it does not decode the frame. So you could find out how many frames per second your video has. Then call .read() and after that call .grab() as often as your video has frames in 5 seconds. Then call .read() again.

Or really save the pictures to disk and work on them.



来源:https://stackoverflow.com/questions/49278087/how-to-capture-a-picture-after-every-5-seconds-of-camera-using-opencv-python-and

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!