コード例 #1
0
ファイル: bestface.py プロジェクト: mrosenf2/umd408G
    def run(self, filepath):
        detector = dlib.get_frontal_face_detector()
        # predictor = dlib.shape_predictor(os.path.join(sys.path[0], "data/")) #ignore for now

        # Start the frame queue
        vs = FileVideoStream(filepath)

        if (not vs.stream.isOpened()):
            return 0, 0

        self.maxframes = int(vs.stream.get(cv2.CAP_PROP_FRAME_COUNT))

        vs.start()
        best_frame = 0
        scoremax = 0

        self.framecounter = 0
        # loop over the frames from the video stream
        while (self.framecounter < self.maxframes):

            # grab the frame from the threaded video stream, resize it to
            # have a maximum width of 400 pixels, and convert it to
            # grayscale
            frame = vs.read()
            frame = imutils.resize(frame, width=400)
            gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
            # detect faces in the grayscale frame
            rects, scores, idx = detector.run(gray, 0, 0)
            # loop over the face detections
            self.framecounter = self.framecounter + 1

            for i, rect in enumerate(rects):
                # compute the bounding box of the face
                (bX, bY, bW, bH) = face_utils.rect_to_bb(rect)
                # keep track of the highest scored face
                if (scores[i] > scoremax):
                    scoremax = scores[i]
                    best_face = frame[bY:bY + bH, bX:bX + bW]
                    best_frame = self.framecounter
                    #cv2.imshow("BEST_FACE", best_face)

            # if the q key was pressed, break from the loop
            key = cv2.waitKey(1) & 0xFF
            if key == ord("q"):
                break

        # Stop the frame queue
        vs.stop()

        if (best_frame == 0):
            #If no face was found
            best_face = 0
        else:
            # Swap the R,B values
            best_face = cv2.cvtColor(best_face, cv2.COLOR_BGR2RGB)
        return best_face, best_frame
コード例 #2
0
def face_detection_in_video(path2video, seconds_per_frame=1):
    print(path2video)
    detected_faces = []
    face_embeddings = []
    facecodes = []

    print("[INFO] starting video file thread...")
    fvs = FileVideoStream(path2video)
    org_frame_rate = fvs.stream.get(5)
    width = fvs.stream.get(3)  # float
    height = fvs.stream.get(4)  # float
    no_of_frames_to_skip = org_frame_rate * seconds_per_frame
    no_of_frames_to_skip = no_of_frames_to_skip if no_of_frames_to_skip >= 1 else 1

    print("[INFO] original frame rate: {}".format(org_frame_rate))
    print("[INFO] no_of_frames_to_skip: {}".format(no_of_frames_to_skip))
    fvs.start()

    # start the FPS timer
    fps = FPS().start()

    frame_no = 1

    # loop over frames from the video file stream
    while fvs.more():
        # grab the frame from the threaded video file stream, resize
        # it, and convert it to grayscale (while still retaining 3
        # channels)
        frame = fvs.read()

        if frame is not None:
            if frame_no % math.floor(no_of_frames_to_skip) == 0:
                data = detect_faces_from_frame(frame, frame_no, width, height)
                detected_faces.extend(data["faces"])
                face_embeddings.extend(data["face_embeddings"])
                facecodes.extend(data["facecodes"])
            frame_no += 1

            # 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] approx. FPS: {:.2f}".format(fps.fps()))
    print("[INFO] total faces detected: {} ".format(len(detected_faces)))
    print("[INFO] total frames: {} ".format(frame_no))

    return {
        "faces": detected_faces,
        "face_embeddings": face_embeddings,
        "facecodes": facecodes
    }
コード例 #3
0
class CustomStream:
    def __init__(self, src=0, use_cv2=False):
        if use_cv2:
            self.obj = cv2.VideoCapture(src)
        elif src == 0:
            self.obj = WebcamVideoStream(src)
        elif src != 0:
            self.obj = FileVideoStream(src)

    def isOpened(self):
        if isinstance(self.obj, cv2.VideoCapture):
            return self.obj.isOpened()
        return self.obj.stream.isOpened()

    def start(self):
        self.obj.start()
        return self

    def update(self):
        self.obj.update()

    def read(self):
        if isinstance(self.obj, cv2.VideoCapture):
            return self.obj.read()
        return not self.obj.stopped, self.obj.read()

    def stop(self):
        self.obj.stop()
        if isinstance(self.obj, cv2.VideoCapture):
            self.obj.release()
        else:
            self.obj.stream.release()

    def set(self, propId, value):
        if isinstance(self.obj, cv2.VideoCapture):
            self.obj.set(propId, value)
            return
        self.obj.stream.set(propId, value)

    def get(self, propId):
        if isinstance(self.obj, cv2.VideoCapture):
            self.obj.get(propId)
            return
        return self.obj.stream.get(propId)
コード例 #4
0
if args["movie"]:
    vs = FileVideoStream(args["movie"])
    imageSrc = MOVIE
elif args["image"]:
    vs = FileVideoStream(args["image"])
    imageSrc = IMAGE
else:
    vs = VideoStream(src=args["webcam"])
    imageSrc = WEBCAM
    #logging.info(f'fps: {vs.get(cv2.CAP_PROP_FPS):%.1f}')
    time.sleep(1.0)

if args["log"]:
    log_file = open(args["log"], "w")

vs.start()
fps = FPS().start()
log_start = time.time()
frameID = -1
eventID = 0
frame = None
faces = []

# loop over frames from the video stream
while True:
    # grab the frame from the threaded video file stream, resize
    # it, and convert it to grayscale
    # channels)
    frameID += 1

    if imageSrc in [MOVIE,WEBCAM]:
コード例 #5
0
class IP(object):
    def __init__(self):
        #self.cap = cv2.VideoCapture(1)

        self.fvs = FileVideoStream(1)

        # self.fvs.stream.set(3,FULL_WIDTH)
        # self.fvs.stream.set(4,FULL_HEIGHT)

        self.fvs.start()

        #self.fvs = FileVideoStream(0).start

        # self.cap.set(3,FULL_WIDTH) #3 - WIDTH
        # self.cap.set(4,FULL_HEIGHT)  #4 - HEIGHT

    def get_image(self):
        #ret,image = self.cap.read()
        # print image
        image = self.fvs.read()
        i = 0
        #image = np.dstack([image, image, image])
        #print ("SHAPE : ",image.shape)
        image = imutils.resize(image, width=FULL_WIDTH)  #,height=FULL_HEIGHT)
        print("SHAPE : ", image.shape)
        # while not np.size(image,0) == FULL_HEIGHT or not np.size(image,1) == FULL_WIDTH :
        #      print ("trying",i)
        #      print ("SHAPE : ",image.shape)
        #      i += 1
        #      image = self.fvs.read()
        #      #ret,image = self.cap.read()
        return image

    def perspective_transform(self, image, pts1, pts2):
        return cv2.warpPerspective(image,
                                   cv2.getPerspectiveTransform(pts1, pts2),
                                   (FINAL_WIDTH, FINAL_HEIGHT))

    def rgb2gray(self, image):
        return cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

    def rgb2hsv(self, image):
        return cv2.cvtColor(image, cv2.COLOR_BGR2HSV)

    def threshold_image(self, image, threshold, max_val):
        return cv2.threshold(image, threshold, max_val, cv2.THRESH_BINARY)

    def display_image(self, image, window_name="Image"):
        cv2.imshow(window_name, image)
        if cv2.waitKey(1) == ord('q'):
            cv2.destroyAllWindows()
            self.fvs.stop()
            return 0
        return 1

    def find_contours(self, image):
        major, _, _ = cv2.__version__.split('.')
        if major == '3':
            _, contour, hierarchy = cv2.findContours(image, cv2.RETR_TREE, 2)
        else:
            contour, hierarchy = cv2.findContours(image, cv2.RETR_TREE, 2)
        return contour, hierarchy

    def find_area(self, contour):
        return cv2.contourArea(contour)

    def find_moments(self, contour):
        return cv2.moments(contour)

    def crop_image(self, image, center, amount):
        #print int(center[1])-amount,int(center[0])-amount
        #print int(center[1])+amount,int(center[0])+amount
        if int(center[1]) - amount >= 0 and int(center[0]) - amount >= 0:
            if int(center[1]) + amount <= FINAL_HEIGHT and int(
                    center[0]) + amount <= FINAL_WIDTH:
                img = image[(int(center[1]) - amount):(int(center[1]) +
                                                       amount),
                            (int(center[0]) - amount):(int(center[0]) +
                                                       amount)]
                return img
            else:
                return -1
        else:
            return -1

    def get_hsv_mask(self, image, lower, upper):
        return cv2.inRange(image, lower, upper)

    def end_all(self):
        self.fvs.release()
        cv2.destroyAllWindows()

    def draw_grid(self, im2, x_grid_num, y_grid_num):
        #ret,frame = self.cap.read()
        row = [0 for i in range(18)]
        mat = np.zeros((12, 18), dtype=np.uint64)
        #for i in range(12):
        #	mat.append([])
        X = im2.shape[1]
        Y = im2.shape[0]
        start_x = 0
        start_y = 0
        end_x = X / 18
        end_y = Y / 12

        for i in range(18):
            for j in range(12):
                if i not in range(x_grid_num - 1,
                                  x_grid_num + 2) or j not in range(
                                      y_grid_num - 1, y_grid_num + 2):
                    im2 = cv2.rectangle(
                        im2, (start_x + (X / 18) * i, start_y + (Y / 12) * j),
                        (end_x + (X / 18) * i, end_y + (Y / 12) * j),
                        (0, 0, 255))
                    mat[j][i] = 0
                else:
                    im2 = cv2.rectangle(
                        im2, (start_x + (X / 18) * i, start_y + (Y / 12) * j),
                        (end_x + (X / 18) * i, end_y + (Y / 12) * j),
                        (0, 0, 255), -1)
                    mat[j][i] = 1
                #print "HI", mat[j][i]
        '''
    	print "Printing mat..."
    	for i in range(12):
    		s = ""
    		for j in range(18):
    			s += str(mat[i][j]) + " "
    		print s
    	'''
        MAT = np.copy(mat)
        #print "MAT.shape", MAT.shape
        return im2, MAT

    '''
コード例 #6
0
class movement_direction:
    def __init__(self, video_source_info, user_roi):
        self.source_info = video_source_info
        self.source = None
        if self.source_info == '0' or self.source_info == '1':
            self.source = 'Camera'
        elif isinstance(self.source_info, str) and Path(
                self.source_info).exists() and Path(sys.argv[1]).is_file():
            self.source = self.source_info
        self._is_valid = not (self.source is None)

        self.frame_count = 0
        self.prev_frame = None
        self.prev_angle = None
        self.current_angle = None
        self.angle_estimate_available = False
        self.angle_posts = dict(Right=75, Left=120)
        self.angle_diff_threshold = 7
        self.current_state = State.eUnknown
        self.prev_state = self.current_state
        self.logger = get_logger()
        self.angle_states = {}
        self.angle_states[State.eRight] = 'Right'
        self.angle_states[State.eLeft] = 'Left'
        self.angle_states[State.eSame] = 'Straight'
        self.angle_states[State.eUnknown] = 'Unknown'
        '''
        Initialize Capture and set up region of interest
        '''
        if self.source == 'Camera':
            self.cap = WebcamVideoStream(src=int(self.source_info))
        else:
            self.cap = FileVideoStream(self.source_info)
        self.cap.start()
        frame = self.cap.read()
        self.prev_frame = frame.copy()
        shape = self.prev_frame.shape
        time.sleep(2)
        (self.source_height, self.source_width) = self.prev_frame.shape[:2]
        self._is_loaded = True
        self.logger.info('Source is ' + self.source)
        video_roi = user_roi
        if self.source == 'Camera':
            camera_roi = dict(row_low=0,
                              row_high=self.source_height - 1,
                              column_low=0,
                              column_high=self.source_width - 1)
            video_roi = camera_roi

        self.logger.info(video_roi)

        self.row_range = (video_roi['row_low'], video_roi['row_high'])
        self.column_range = (video_roi['column_low'], video_roi['column_high'])
        self.settings = initialize_settings_from_video_roi(video_roi)
        self.width = video_roi['column_high'] - video_roi['column_low']
        self.height = video_roi['row_high'] - video_roi['row_low']

        assert (self.width <= self.source_width)
        assert (self.height <= self.source_height)
        self.logger.info((self.source_width, self.source_height))
        '''
            Initialize tracking parameters 
            '''
        self.feature_params = self.settings['feature_params']
        self.lk_params = self.settings['lk_params']
        self.max_dist = self.settings['max_distance']
        self.prev_frame = None
        self.keypoint_dist = 0
        self.min_features = self.settings['min_features']
        self.old_points = []
        self.new_points = []
        self.keypoints = []

        self.display = None
        self.debug = False
        self.direction = []
        self.avg_angle = None
        self.show_vectors = False
        self.show_axis = False

    def is_loaded(self):
        return self._is_loaded

    def is_valid(self):
        return self._is_valid

    def run(self):
        frame = self.prev_frame.copy()
        self.prev_frame = self.prepare_frame(frame)
        self.logger.info(('frame: ', self.frame_count))
        self.frame_count = self.frame_count + 1
        cv.namedWindow('Frame', cv.WINDOW_NORMAL)

        while self.cap.running():
            captured_frame = self.cap.read()
            if not (captured_frame is None):
                self.frame_count = self.frame_count + 1
                frame = self.prepare_frame(captured_frame)
                assert (not (self.prev_frame is None))
                self.update_features()
                self.get_flow(frame)
                self.prev_frame = frame.copy()

                #    self.draw_tracks( self.keypoints, self.new_points)
                cv.imshow("Frame", self.display)

    def prepare_frame(self, frame):
        frame = frame[self.row_range[0]:self.row_range[1],
                      self.column_range[0]:self.column_range[1]]
        self.display = frame.copy()
        frame = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
        return frame

    def get_features(self):
        self.keypoint_dist = 0
        # collect features on the prev frame and compute its geometric median
        self.old_points = cv.goodFeaturesToTrack(self.prev_frame,
                                                 mask=None,
                                                 **self.feature_params)
        self.keypoints = np.copy(self.old_points)

    def update_features(self):
        # if moved too much re create features on the prev frame
        if self.keypoint_dist > self.max_dist:
            self.get_features()

            def set_state(_instant_angle):
                if _instant_angle <= self.angle_posts['Right']:
                    self.current_state = State.eRight
                elif _instant_angle >= self.angle_posts['Left']:
                    self.current_state = State.eLeft
                else:
                    self.current_state = State.eSame

            if self.debug: self.logger.debug('max distance passed: reset ')
            avg_angle = self.measure_tracks(self.keypoints, self.new_points)
            avg_angle = math.degrees(avg_angle) % 360
            self.direction.append(avg_angle)
            instant_angle = int(np.average(self.direction))
            if self.prev_angle is None:
                self.prev_angle = instant_angle
                self.prev_state = State.eUnknown

            self.current_angle = instant_angle
            diff = self.current_angle - self.prev_angle
            ok = diff < self.angle_diff_threshold
            if ok and self.current_state == self.prev_state:
                self.current_state = State.eSame
            else:
                set_state(instant_angle)

            self.prev_angle = self.current_angle
            self.prev_state = self.current_state

            ## determine current direction:
            ## difference = current - prev
            ## if difference < 0 threshold and current is not Unknow ==> Straight
            ## if prev != current ==> current

            self.logger.info(('frame, direction:', self.frame_count,
                              instant_angle, self.current_state))

        # if few new points create features on the prev frame
        elif len(self.new_points) < self.min_features:
            self.get_features()
            if self.debug:
                self.logger.debug('copied old points to keypoints   ')
        else:
            # check number of features in each quadrant to ensure a good distribution of features across entire image
            nw = ne = sw = se = 0
            w = self.width
            h = self.height
            for x, y in self.new_points:
                if x > w // 2:
                    if y > h // 2:
                        se += 1
                    else:
                        ne += 1
                else:
                    if y > h // 2:
                        sw += 1
                    else:
                        nw += 1

            self.num_features = min((nw, ne))
            if self.num_features < self.min_features // 4:
                self.get_features()
        #        if self.debug: self.logger.debug('too few features reset  ')
            else:
                # just copy new points to old points
                dim = np.shape(self.new_points)
                self.old_points = np.reshape(self.new_points, (-1, 1, 2))
                if self.debug: self.logger.debug('ok')

    def get_flow(self, frame):
        self.new_points, self.status, self.error = cv.calcOpticalFlowPyrLK(
            self.prev_frame, frame, self.old_points, None, **self.lk_params)
        self.keypoints = np.reshape(
            self.keypoints,
            (-1, 1, 2))  # TODO find out why this is necessary?!
        self.old_points = self.old_points[self.status == 1]
        self.new_points = self.new_points[self.status == 1]
        self.keypoints = self.keypoints[self.status == 1]
        self.keypoint_dist += self.get_mean_distance_2d(
            self.old_points, self.new_points)

    def get_mean_distance_2d(self, features1, features2):
        num_features = min((len(features1), len(features2)))
        features1 = np.reshape(features1, (num_features, 2))
        features2 = np.reshape(features2, (num_features, 2))

        features = zip(features1, features2)
        n = 0
        dist = 0
        for f1, f2 in features:
            dx = f1[0] - f2[0]
            dy = f1[1] - f2[1]
            d = math.sqrt(dx**2 + dy**2)
            dist += d
            n += 1

        if n == 0:
            return 0

        dist /= n
        return dist

    def draw_direction(self):
        if self.prev_state != State.eUnknown and self.current_state != State.eUnknown:
            direction = self.angle_states[self.current_state]
            cv.putText(self.display, direction,
                       (self.width // 2, self.height // 2),
                       cv.FONT_HERSHEY_DUPLEX, 2, (225, 0, 0), 7)

    def draw_tracks(self, points1, points2):
        if self.show_vectors:
            for i, (new, old) in enumerate(zip(points1, points2)):
                a, b = new.ravel()
                c, d = old.ravel()
                cl = (0, 255, 0)
                if a < self.width / 2: cl = (255, 0, 0)
                frame = cv.line(self.display, (c, d), (a, b), cl, 1)
                cv.circle(self.display, (a, b), 5, cl, 0, 3)

        self.draw_direction()
        cv.putText(self.display, str(self.frame_count),
                   (self.width // 16, (15 * self.height) // 16),
                   cv.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)

        if self.show_axis:
            cv.line(self.display, (0, self.height // 2),
                    (self.width, self.height // 2), (255, 0, 0), 1)
            cv.line(self.display, (self.width // 2, 0),
                    (self.width // 2, self.height), (255, 0, 0), 1)

    def measure_tracks(self, points1, points2):
        angles = []
        for i, (new, old) in enumerate(zip(points1, points2)):
            a, b = new.ravel()
            c, d = old.ravel()
            line = [c, d, a, b]
            angle = get_line_angle(line)
            angles.append(angle)

        angles = np.asanyarray(angles)
        mean_angle = np.arctan2(np.sin(angles).mean(), np.cos(angles).mean())
        if mean_angle < 0:
            mean_angle = math.pi + math.pi + mean_angle

        return mean_angle
コード例 #7
0
class Moviebarcode:
    """
    Generate moviebarcode from an input video
    """

    # TODO: Optimize the resize process and rescale 1K+ size videos to 480
    def __init__(
        self,
        video_path=None,
        verbose=True,
        # optimize=True                          # TODO: Work on to optimize the moviebarcode generation
        barcode_width=1):
        self.video_path = video_path
        self.verbose = verbose
        self.generate_features = True  # Generate input video specs such as fps, width, and height
        self.video = None
        self.fvs = None  # FVS object for accelerating video stream to threads
        self.frame_count = 0
        self.video_fps = 0  # We get FPS value from OpenCV Flags
        self.video_width = None  # We get width value from OpenCV Flags
        self.video_height = None  # We get height value from OpenCV Flags
        self.frame_avgs = []  # Raw pixel values of frame pixel averages
        self.elapsed_time = 0.0  # Accelerated video queueing time
        self.processed_frame_count = 0  # How many frames of video is processed in threaded process
        self.processed_video_width = 0  # Final version of each frame processed width value
        self.processed_video_height = 0  # Final version of each frame processed height value
        self.barcode_frame_count = 0  # don't want to visualize all frames, change barcode_frequency
        self.barcode_frequency = None
        self.fps = 0  # We get this value from imutils' fps() function
        self.barcode = None  # Keep barcode object for further use
        self.barcode_height = 224  # Set barcode image height
        self.barcode_width = barcode_width

    def if_exist(self):
        """
        For provided video path, check if it exists

        :return: The result of if the video exists
        """
        if not os.path.exists(self.video_path):
            logging.info(msg=f"{self.video_path} doesn't exist!")
            return False
        return True

    def load_video(self):
        """
        Accelerated video stream with multi-threading support

        :return:
        """
        if self.verbose:
            logging.info(msg=f"{self.video_path} is loading ..")
        if self.if_exist():
            self.video = FileVideoStream(self.video_path)

    def get_frames_avgs(self):
        """
        Calculate frames' average pixel values for all frames of loaded video

        :return: build the list for average pixel values
        """
        if self.video is None:
            self.load_video()

        # Start video stream
        if self.verbose:
            logging.debug(msg=f"Video is being started ..")
        self.fvs = self.video.start()
        fps = FPS().start()

        # Generate video features before processing
        if self.generate_features:
            self.frame_count = int(
                self.video.stream.get(cv2.CAP_PROP_FRAME_COUNT))
            self.video_fps = int(self.video.stream.get(cv2.CAP_PROP_FPS))
            self.video_width = int(
                self.video.stream.get(cv2.CAP_PROP_FRAME_WIDTH))
            self.video_height = int(
                self.video.stream.get(cv2.CAP_PROP_FRAME_HEIGHT))

            if self.verbose:
                logging.info(msg=f"[Video] frame count: {self.frame_count}")
                logging.info(msg=f"[Video] FPS: {self.video_fps}")
                logging.info(
                    msg=
                    f"[Video] Size: {self.video_width} x {self.video_height}")

        # Loop frames in a while
        if self.verbose:
            logging.info(
                msg=f"Video frame average pixel values are being calculated .."
            )
        while self.fvs.more():
            frame = self.fvs.read()
            self.frame_avgs.append(cv2.mean(frame)[:3])
            fps.update()
        fps.stop()
        self.fvs.stop()

        # Generate video features after processing
        if self.generate_features:
            self.fps = int(fps.fps())
            self.elapsed_time = fps.elapsed()
            self.processed_frame_count = fps.elapsed() * fps.fps()
            self.processed_video_width = int(self.video_width)
            self.processed_video_height = int(self.video_height)
            if self.verbose:
                logging.info(
                    msg=f"[Processed] frame count: {self.frame_count}")
                logging.info(msg=f"[Processed] FPS: {self.fps}")
                logging.info(
                    msg=
                    f"[Processed] Size: {self.processed_video_width} x {self.processed_video_height}"
                )

    def get_barcode_frame_count(self):
        """
        Get the total number of frames for input video

        :return:
        """
        if self.barcode is not None:
            self.barcode_frame_count = self.barcode.shape[0]
        if self.verbose:
            logging.info(
                msg=
                f"Total number of frames in barcode: {self.barcode_frame_count}"
            )

    def barcode_frame_sequence(self):
        """
        On moviebarcode generation, the sequence of frames average can be set

        :return: Setting the frequency with the user input
        """
        # per frame
        if self.barcode_frequency is None:
            self.barcode_frequency = 1

        # per second
        elif self.barcode_frequency == "second":
            self.barcode_frequency = self.fps

        # per n-frame
        elif "frames" in self.barcode_frequency:
            freq = self.barcode_frequency.split("frames")[0]
            if freq != int(freq):
                self.barcode_frequency = freq

        # per n-second
        elif "seconds" in self.barcode_frequency:
            freq = self.barcode_frequency.split("seconds")[0]
            if freq != int(freq):
                self.barcode_frequency = self.fps * freq

        # per minute
        elif self.barcode_frequency == "minute":
            self.barcode_frequency = self.fps * 60

        # per n-minute
        elif "minutes" in self.barcode_frequency:
            freq = self.barcode_frequency.split("minutes")[0]
            if freq != int(freq):
                self.barcode_frequency = self.fps * freq * 60

    def generate(self, colors=None):
        """
        Moviebarcode generation function.
        This function has options, if a list of pixel values are provided, the moviebarcode image can be generated
        :param colors: A list or list-like object that contains pixel values
        Default value is None

        :return: RGB image of generated moviebarcode
        """
        if colors is None:
            # generate frames average
            self.get_frames_avgs()
        else:
            self.frame_avgs = colors

        # TODO: Add barcode_frequency option to this assignment
        self.barcode = np.zeros((self.barcode_height, len(self.frame_avgs), 3),
                                dtype="uint8")

        for (i, avg) in enumerate(np.array(self.frame_avgs)):
            cv2.rectangle(
                self.barcode, (int(i * self.barcode_width), 0),
                (int(i + 1) * self.barcode_width, self.barcode_height),
                (int(avg[0]), int(avg[1]), int(avg[2])), 3)

        if self.verbose:
            logging.info(msg="Barcode is being calculated ...")

    # TODO: Make the barcode name dynamic to input video id
    def make_image(self, file_name="output/moviebarcode.png"):
        """
        Create the PNG RGB image for the barcode object.
        :param file_name: The filename to name and record the image.
        The default value is "output/moviebarcode.png"

        :return: Write RGB image to a PNG file.
        """
        # save as image
        if self.barcode is not None:
            cv2.imwrite(filename=file_name, img=self.barcode)
        else:
            self.generate()
            cv2.imwrite(filename=file_name, img=self.barcode)

    def display_barcode(self):
        """
        visualize the moviebarcode image with OpenCV
        :return:
        """
        if self.verbose:
            logging.info(msg="Barcode is displayed with OpenCV")
        cv2.imshow("Barcode", self.barcode)
        cv2.waitKey(0)

    # TODO: make json file name dynamic to input video id
    def write2json(self, file_name="output/barcode.json"):
        """
        Write moviebarcode pixel values to a json file
        :param file_name: Name the json file to record to the disk
        The default value is "output/barcode.json"
        :return:
        """
        # Since our values are OpenCV image object which is BGR imager, convert the moviebarcode array to RGB
        b = np.array(self.frame_avgs)[:, 0].reshape(-1, 1)
        g = np.array(self.frame_avgs)[:, 1].reshape(-1, 1)
        r = np.array(self.frame_avgs)[:, 2].reshape(-1, 1)
        self.frame_avgs = np.concatenate([r, g, b], axis=1)
        with open(file_name, "w") as json_file:
            json_file.write(json.dumps(self.frame_avgs.tolist()))
        if self.verbose:
            logging.info(msg="Barcode is being written to json file!")
コード例 #8
0
    def detect(self, video_path,
               output_path=None,
               skip_secs=0,
               real_show=False,
               show_fps=True,
               ):
        logging.info("Detect video: " + str(video_path))

        fvs = FileVideoStream(video_path, transform=_transform)
        vid = fvs.stream

        if not vid.isOpened():
            raise IOError("Couldn't open webcam or video")
        video_FourCC = int(vid.get(cv2.CAP_PROP_FOURCC))
        video_fps = int(vid.get(cv2.CAP_PROP_FPS))
        video_size = (int(vid.get(cv2.CAP_PROP_FRAME_WIDTH)),
                      int(vid.get(cv2.CAP_PROP_FRAME_HEIGHT)))

        total_frames = int(vid.get(cv2.CAP_PROP_FRAME_COUNT))
        skip_frames = int(skip_secs) * video_fps
        if skip_secs > total_frames:
            print("Can't skip over total video!")
        else:
            vid.set(cv2.CAP_PROP_POS_FRAMES, skip_frames)

        isOutput = True if output_path is not None else False
        if isOutput:
            logging.info(f"Output Type: {output_path}, {video_FourCC}, {video_fps}, {video_size}")
            out = cv2.VideoWriter(output_path, self.fourcc, video_fps, video_size)

        if real_show:
            cv2.namedWindow("result", cv2.WINDOW_NORMAL)
            cv2.resizeWindow("result", 960, 540)
            pass
        fvs.start()

        accum_time = 0
        curr_fps = 0
        fps = "FPS: ??"
        prev_time = time.time()

        hold_detections = None
        actions = []

        frames = 0
        try:
            while fvs.more():
                frame = fvs.read()

                #frame = cv2.resize(frame, (608, 608), interpolation=cv2.INTER_LINEAR)
                # frame = cv2.hconcat([frame, frame, frame])

                if frame is None:
                    break

                # BGR -> RGB
                if frames % self.skip_frames == 0:
                    detections = self.image_detector.detect(frame)

                    if detections is not None and self.tracker is not None:
                        boxs = p1p2Toxywh(detections[:, :4])
                        class_ids = detections[:, -1]
                        confidences = detections[:, 4]
                        if self.class_mask is not None:
                            mask_set = [class_ids == mask_id for mask_id in self.class_mask]
                            mask = reduce(lambda a, b: a | b, mask_set)

                            boxs = boxs[mask]
                            confidences = confidences[mask]
                            class_ids = class_ids[mask]

                        detections = self.tracker.update(boxs.float(), confidences, frame, class_ids)

                        if self.action_id is not None:
                            actions = self.action_id.update(detections)
                        else:
                            actions = []

                    hold_detections = detections
                    frames = 0
                else:
                    actions = []

                if hold_detections is not None:
                    if self.tracker is not None:
                        image, plane, plane_mask = self.label_drawer.draw_labels_by_trackers(frame,
                                                                                             hold_detections,
                                                                                             only_rect=False)
                    else:
                        image, plane, plane_mask = self.label_drawer.draw_labels(frame, hold_detections,
                                                                                 only_rect=False)
                else:
                    image, plane, plane_mask = frame, None, None

                # RGB -> BGR
                result = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)

                frames += 1

                curr_time = time.time()
                exec_time = curr_time - prev_time
                prev_time = curr_time
                accum_time += exec_time
                curr_fps += 1

                if accum_time > 1:
                    accum_time = accum_time - 1
                    fps = "FPS: " + str(curr_fps)
                    curr_fps = 0
                    print(fps)

                if show_fps:
                    cv2.putText(result, text=fps, org=(3, 15), fontFace=cv2.FONT_HERSHEY_SIMPLEX,
                                fontScale=0.6, color=(255, 0, 0), thickness=self.thickness)

                # Show the video in real time.
                if real_show:
                    cv2.imshow("result", result)

                if isOutput:
                    out.write(result)
                yield result, hold_detections, actions

                if real_show:
                    if cv2.waitKey(1) & 0xFF == ord('q'):
                        break
        finally:
            if isOutput:
                out.release()
            if real_show:
                cv2.destroyAllWindows()
コード例 #9
0
ファイル: main.py プロジェクト: angustrau/soccer-360-vision
    def start(self):
        thread = Thread(target=self.process,
                        args=(),
                        name='BallFinderProcess',
                        daemon=True)
        thread.start()

    def stop(self):
        self.stopped = True


if __name__ == "__main__":
    video_file = "data/VID_20201224_134735.mp4"
    video = FileVideoStream(video_file)
    video.start()
    output_video = cv.VideoWriter('output.avi', cv.VideoWriter_fourcc(*"MJPG"),
                                  20.0, (320, 568))

    finder = BallFinder(video)
    try:
        finder.start()

        while True:
            ball_found, ball_center, frame, ball_greyscale, hsv_mask, ball_mask = finder.get_frame(
            )
            if frame is not None:
                if ball_found:
                    print('Ball found at ' + str(ball_center))
                    cv.circle(frame, ball_center, 4, (255, 0, 0), -1)
                else:
コード例 #10
0
def main(video, shape_predictor):
    def eye_aspect_ratio(eye):
        # compute the euclidean distances between the two sets of
        # vertical eye landmarks (x, y)-coordinates
        A = dist.euclidean(eye[1], eye[5])
        B = dist.euclidean(eye[2], eye[4])

        # compute the euclidean distance between the horizontal
        # eye landmark (x, y)-coordinates
        C = dist.euclidean(eye[0], eye[3])

        # compute the eye aspect ratio
        ear = (A + B) / (2.0 * C)

        # return the eye aspect ratio
        return ear

    # construct the argument parse and parse the arguments
    # ap = argparse.ArgumentParser()
    # ap.add_argument("-p", "--shape-predictor", required=True,
    # 	help="path to facial landmark predictor")
    # ap.add_argument("-v", "--video", type=str, default="",
    # 	help="path to input video file")
    ap = argparse.ArgumentParser()
    ap.add_argument(shape_predictor, nargs=1)
    ap.add_argument(video, nargs=1)
    args = vars(ap.parse_args())

    # define two constants, one for the eye aspect ratio to indicate
    # blink and then a second constant for the number of consecutive
    # frames the eye must be below the threshold
    EYE_AR_THRESH = 0.3
    EYE_AR_CONSEC_FRAMES = 3

    # initialize the frame counters and the total number of blinks
    COUNTER = 0
    global TOTAL
    TOTAL = 0

    # initialize dlib's face detector (HOG-based) and then create
    # the facial landmark predictor
    #print("[INFO] loading facial landmark predictor...")
    detector = dlib.get_frontal_face_detector()
    predictor = dlib.shape_predictor(shape_predictor)

    # grab the indexes of the facial landmarks for the left and
    # right eye, respectively
    (lStart, lEnd) = face_utils.FACIAL_LANDMARKS_IDXS["left_eye"]
    (rStart, rEnd) = face_utils.FACIAL_LANDMARKS_IDXS["right_eye"]

    # start the video stream thread
    #print("[INFO] starting video stream thread...")
    cap = cv2.VideoCapture(video)
    vs = FileVideoStream(video)
    vs.start()
    fileStream = True
    # vs = VideoStream(src=0).start()
    # vs = VideoStream(usePiCamera=True).start()
    # fileStream = False
    time.sleep(1.0)

    # loop over frames from the video stream
    while True:
        # if this is a file video stream, then we need to check if
        # there any more frames left in the buffer to process
        if fileStream and not vs.more():
            break

        # grab the frame from the threaded video file stream, resize
        # it, and convert it to grayscale
        # channels)
        frame = vs.read()
        if np.shape(frame) != ():
            frame = imutils.resize(frame, width=450)
            gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

        # detect faces in the grayscale frame
        rects = detector(gray, 0)

        # loop over the face detections
        for rect in rects:
            # determine the facial landmarks for the face region, then
            # convert the facial landmark (x, y)-coordinates to a NumPy
            # array
            shape = predictor(gray, rect)
            shape = face_utils.shape_to_np(shape)

            # extract the left and right eye coordinates, then use the
            # coordinates to compute the eye aspect ratio for both eyes
            leftEye = shape[lStart:lEnd]
            rightEye = shape[rStart:rEnd]
            leftEAR = eye_aspect_ratio(leftEye)
            rightEAR = eye_aspect_ratio(rightEye)

            # average the eye aspect ratio together for both eyes
            ear = (leftEAR + rightEAR) / 2.0

            # compute the convex hull for the left and right eye, then
            # visualize each of the eyes
            leftEyeHull = cv2.convexHull(leftEye)
            rightEyeHull = cv2.convexHull(rightEye)
            cv2.drawContours(frame, [leftEyeHull], -1, (0, 255, 0), 1)
            cv2.drawContours(frame, [rightEyeHull], -1, (0, 255, 0), 1)

            # check to see if the eye aspect ratio is below the blink
            # threshold, and if so, increment the blink frame counter
            if ear < EYE_AR_THRESH:
                COUNTER += 1

            # otherwise, the eye aspect ratio is not below the blink
            # threshold
            else:
                # if the eyes were closed for a sufficient number of
                # then increment the total number of blinks
                if COUNTER >= EYE_AR_CONSEC_FRAMES:
                    TOTAL += 1

                # reset the eye frame counter
                COUNTER = 0

            # draw the total number of blinks on the frame along with
            # the computed eye aspect ratio for the frame
            #cv2.putText(frame, "Blinks: {}".format(TOTAL), (10, 30),
            #cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)
            #cv2.putText(frame, "EAR: {:.2f}".format(ear), (300, 30),
            #cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)

        # show the frame
        #if np.shape(frame) != ():
        #cv2.imshow("Frame", frame)
        key = cv2.waitKey(1) & 0xFF

        # if the `q` key was pressed, break from the loop
        if key == ord("q"):
            break

    # output final results
    # if "FAKE" in str(video):
    # 	print("Fake " + str(TOTAL))
    # else:
    # 	print("Real " + str(TOTAL))
    print(str(TOTAL))

    # do a bit of cleanup
    cv2.destroyAllWindows()
    vs.stop()