<reponame>freewebfish/lightweight-human-pose-estimation-3d-demo.pytorch<filename>scripts-test/testwebcamstream.py
#!/usr/bin/env python

from threading import Thread, Lock
import time
import datetime
import cv2

class FPS:
    def __init__(self):
        # store the start time, end time, and total number of frames
        # that were examined between the start and end intervals
        self._start = None
        self._end = None
        self._numFrames = 0
    
    def start(self):
        # start the timer
        self._start = datetime.datetime.now()
        return self
	
    def stop(self):
        # stop the timer
        self._end = datetime.datetime.now()

    def update(self):
        # increment the total number of frames during the start and end intervals
        self._numFrames += 1
    
    def numframes(self) :
        return self._numFrames
	
    def elapsed(self):
        # total number of seconds between the start and end interval
        return (self._end - self._start).total_seconds()
        
    def fps(self):
        # compute the (approximate) frames per second
        return self._numFrames / self.elapsed()


class WebcamVideoStream :
    def __init__(self, src = 0, width = 640, height = 480) :
        self.stream = cv2.VideoCapture(src, cv2.CAP_DSHOW)
        self.stream.set(cv2.CAP_PROP_FRAME_WIDTH, width)
        self.stream.set(cv2.CAP_PROP_FRAME_HEIGHT, height)
        if (self.stream.isOpened()== False): 
            raise IOError("Camera {src} cannot be opened")
        (self.grabbed, self.frame) = self.stream.read()
        self.started = False
        self.read_lock = Lock()

    def isOpened(self) :
        return self.stream.isOpened()

    def width(self) :
        if self.stream.isOpened() == True :
            return self.stream.get(cv2.CAP_PROP_FRAME_WIDTH)
        else:        
            return None

    def height(self) :
        if self.stream.isOpened() == True :
            return self.stream.get(cv2.CAP_PROP_FRAME_HEIGHT)
        else:        
            return None

    def start(self) :
        if self.started :
            print("already started!!")
            return None
        self.started = True
        self.thread = Thread(target=self.update, args=())
        self.thread.start()
        return self

    def update(self) :
        while self.started :
            (grabbed, frame) = self.stream.read()
            self.read_lock.acquire()
            self.grabbed, self.frame = grabbed, frame
            if not self.grabbed: break
            self.read_lock.release()

    def read(self) :
        self.read_lock.acquire()
        frame = self.frame.copy()
        self.read_lock.release()
        return frame

    def stop(self) :
        self.started = False
        self.thread.join()

    def __exit__(self, exc_type, exc_value, traceback) :
        self.stream.release()


if __name__ == "__main__" :
    #cam_id = "D:\\myData\\VideoClips\\short-exercise-720.mp4"
    cam_id = 0
    cam_width = 1280
    cam_height = 720
    mirror_flip = True
    show_frame = True
    is_threaded = True
    fps_video = 0

    if is_threaded:

        print("[INFO] grabbing frames from webcam using threads...")
        fps = FPS().start()
        vs = WebcamVideoStream(cam_id, cam_width, cam_height).start()
        while True :
            tic0 = cv2.getTickCount()
            frame = vs.read()
            if mirror_flip: frame = cv2.flip(frame, 1)
            
            if show_frame:
                cv2.putText(frame, 'FPS-video: {}'.format(int(fps_video)), (20, 20), cv2.FONT_HERSHEY_COMPLEX, 0.6, (0, 0, 255), 1)        
                cv2.imshow('webcam', frame)
            fps_video = cv2.getTickFrequency() / (cv2.getTickCount() - tic0) 

            if cv2.waitKey(1) == 27 :
                break
            # update the FPS counter
            fps.update()

        # stop the timer and display FPS information
        fps.stop()
        print("[INFO] elasped time: {:.2f}".format(fps.elapsed()))
        print("[INFO] number of frames: {:d}".format(fps.numframes()))                
        print("[INFO] approx. FPS: {:.2f}".format(fps.fps()))

        vs.stop()
        cv2.destroyAllWindows()

    else:

        # grab a pointer to the video stream and initialize the FPS counter
        print("[INFO] grabbing frames from webcam...")
        fps = FPS().start()
        stream = cv2.VideoCapture(cam_id)
        stream.set(cv2.CAP_PROP_FRAME_WIDTH, cam_width)
        stream.set(cv2.CAP_PROP_FRAME_HEIGHT, cam_height)
        stream.set(cv2.CAP_PROP_FPS, 30)            
    
        # loop over some frames
        while True: 
            tic0 = cv2.getTickCount()                                    
            (grabbed, frame) = stream.read()
            if not grabbed: break
            if mirror_flip: frame = cv2.flip(frame, 1)

            # update the FPS counter
            fps.update()

            # check to see if the frame should be displayed to our screen
            if show_frame:
                #update frame rates
                cv2.putText(frame, 'FPS-video: {}'.format(int(fps_video)), (20, 20), cv2.FONT_HERSHEY_COMPLEX, 0.6, (0, 0, 255), 1)
                cv2.imshow("Frame", frame)
            fps_video = cv2.getTickFrequency() / (cv2.getTickCount() - tic0)            

            key = cv2.waitKey(1)
            if key == 27 or key == 113: #'q' or 'esc'
                break

        # stop the timer and display FPS information
        fps.stop()
        print("[INFO] elasped time: {:.2f}".format(fps.elapsed()))
        print("[INFO] number of frames: {:d}".format(fps.numframes()))        
        print("[INFO] approx. FPS: {:.2f}".format(fps.fps()))

        # do a bit of cleanup
        stream.release()
        cv2.destroyAllWindows()
