基于相邻帧差异判断固定相机拍摄的视频运动情况(Python)

直方图阈值设置为2000以下,视为该视频人体未发生运动,由于肢体像素相同,识别误差显著,存在较大误差。

import time
import cv2
import os, shutil
from tqdm import tqdm
import numpy as np
import matplotlib.pyplot as plt

def cvt(img):  # 肤色提取
    YCrCb = cv2.cvtColor(img, cv2.COLOR_BGR2YCR_CB)  # 转换至YCrCb空间
    # 人体肤色在YCrCb空间的粗略映射
    skin = cv2.inRange(YCrCb, np.array([0, 133, 77]), np.array([255, 173, 127]))
    res = cv2.bitwise_and(YCrCb, YCrCb, mask=skin)
    return res

def video_traverse(path):
    dirs, files = [], []
    for item in os.scandir(path):
        if item.is_dir():
            dirs.append(item.path)
        elif item.is_file():
            files.append(item.path)
    return files

path = r'E:\InfantVideo\new_path\dataset_add2'
files = video_traverse(path)
dest_file_path = r'E:\InfantVideo\new_path\dataset_add2\2000-3000'

for item in tqdm(files, desc='Processing'):
    cap = cv2.VideoCapture(item)
    cap.set(3, 640)
    cap.set(4, 480)
    # print(item)
    firstlaunch = True # 首次运行的标志
    prev_frame = None # 用于保存上一帧图像
    plt.ion() # 交互模式,使绘制的直方图可以不断变化

    sum_diff = 0.0

    ret, frame_read = cap.read()
    while ret:
        frame_read = cv2.flip(frame_read, 1)
        frame_read = cv2.medianBlur(frame_read, 5)
        frame_read = cv2.GaussianBlur(frame_read, (5, 5), 0)
        # 提取肤色,然后再转化为灰度图
        present_frame = cvt(frame_read)
        present_frame = cv2.cvtColor(present_frame, cv2.COLOR_YCrCb2BGR)
        present_frame = cv2.cvtColor(present_frame, cv2.COLOR_BGR2GRAY)
        if not firstlaunch:
            sub = cv2.subtract(present_frame, prev_frame)
            hist = cv2.calcHist([sub], [0], None, [256], [0, 255])
            # 只统计灰度值10-100的部分,这只是随意取的
            # 可以自己实验调整找到适合的范围
            diff = np.sum(hist[10:100]) # 统计产生变化的像素点个数
            if sum_diff < diff:
                sum_diff = diff
            # print(diff)
            # plt.plot(hist[6:100], color='red') # 绘制直方图
            # plt.ylim([0, 2000])
            # plt.show()
            # cv2.imshow('preview', sub)
        else:
            firstlaunch = False # 首次运行的标志
        # cv2.waitKey(10)
        if not firstlaunch:
            pass
            # plt.clf() # 清除直方图图像
        prev_frame = present_frame.copy() # 存储此帧
        ret, frame_read = cap.read()
    cap.release()
    if sum_diff > 3000:
        pass
    else:
        shutil.move(item, dest_file_path)
    time.sleep(1)

    plt.close('all')
    cap.release()
        # time.sleep(1)

你可能感兴趣的:(python,音视频,计算机视觉)