通过摄像头检测步频

通过摄像头识别运动频率,比如步频。

打开摄像头

循环读取视频帧

灰度转换

统计中间一行数值和

人在摄像头前运动,该数值会呈现周期变化

通过快速傅里叶转换,将和步频相似频率显示出来。

(尝试人脸检测,跟着人脸位置变化计算频率。

这个对机器算力要求较高,视频帧处理能力不能满足需求)

复制代码
import pyqtgraph as pg
import numpy as np

import cv2 

from scipy.fftpack import fft, fftfreq

import time

timestamp = time.time()
print("当前时间戳:", timestamp)
print("cv2", cv2)


# 训练一组人脸
face_detector = cv2.CascadeClassifier("C:\\Users\\13361\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python39\\site-packages\\cv2\\data\\haarcascade_frontalface_alt2.xml")

data_list = []
fcount = 0
f_periods = []
interval = 0.0
infos = 'TEXT ON VIDEO'

def show_info():
    global fcount, interval
    global timestamp
    fcount += 1
    res = []
    if fcount == 100:
        fcount = 0
        new_time = time.time()
        interval = new_time - timestamp
        timestamp = new_time
        interval /= 100.0
        print('show_info interval ', interval)

    # pos_mask = f_periods[np.where(f_periods < 10)]
    if len(f_periods) :
        for period in f_periods:
            res.append(int(60/(period*interval)))

        # res = res[np.where(res > 100)]
    return res

def get_data():
    global data_list, interval, fcount
    global f_periods, last_y, infos

    ret, frame = vid.read()     
    # conversion of BGR to grayscale is necessary to apply this operation
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    # # print(gray.shape)

    # # 检测人脸(用灰度图检测,返回人脸矩形坐标(4个角))
    # #  param:    灰度图  图像尺寸缩小比例  至少检测次数(若为3,表示一个目标至少检测到3次才是真正目标)
    # ret = face_detector.detectMultiScale(gray, 1.05, 5)
    # ww = 0
    # for x, y, w, h in ret:
    #     cv2.rectangle(gray, (x, y), (x + w, y + h), (0, 0, 255), 3)  #画出矩形框
    #     # print("rect ", x, y, w, h)
    #     if w > 100 and w > ww:
    #         ww = w
    #         last_y = y

    # # print("pend ", last_y)
    # data_list.append(last_y)

    data = np.sum(gray, axis=1)
    data_list.append(float(data[200]))

    # print(float(data[200]))
    if len(data_list) > 200:
            data_list = data_list[1:]
            f_periods = do_fft(data_list)

    plot.setData(data_list,pen='g')

    res = show_info()
    if len(res) :
        infos = ''
        for info in res:
            if info > 100:
                infos += str(info)
                infos += ' '
        # infos = str(res)
        if fcount % 30 == 29:
            print(f"fft_periods: {f_periods}", interval)
            print(f"freq : {res}")
            print(f"infos : {infos}")
    
    # describe the type of font  to be used. 
    font = cv2.FONT_HERSHEY_SIMPLEX 

    # Use putText() method for inserting text on video 
    cv2.putText(gray, infos, (50, 50), font, 1,  
                (0, 255, 255),  2,  cv2.LINE_4) 

    # adaptive thresholding to use different threshold values on different regions of the frame.
    # Thresh = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C,
    #                                         cv2.THRESH_BINARY_INV, 11, 2)

    cv2.imshow('Thresh', gray)



def do_fft(dl):
    # print(data.shape)
    # print(len(dl))
    # print(dl[:5])
    fft_series = fft(dl)     # fft-返回复数数组
    power = np.abs(fft_series)   # 取模
    sample_freq = fftfreq(fft_series.size)
    
    pos_mask = np.where(sample_freq > 0)
    freqs = sample_freq[pos_mask]
    powers = power[pos_mask]
    
    top_k_seasons = 3
    # top K=3 index
    top_k_idxs = np.argpartition(powers, -top_k_seasons)[-top_k_seasons:]
    top_k_power = powers[top_k_idxs]
    fft_periods = (1 / freqs[top_k_idxs]).astype(int)
    
    # pos_mask = fft_periods[np.where(fft_periods > 100)]
    # print(f"fft_periods: {fft_periods}")
    # print(f"pos_mask: {pos_mask}")
    # print(pos_mask)
    return fft_periods

if __name__ == '__main__':
    import sys
    sys.setrecursionlimit(10000)
    # threading.stack_size(200000000)
    # thread = threading.Thread(target=your_code)
    # thread.start()

    vid = cv2.VideoCapture(0) 

    # pyqtgragh初始化
    app = pg.mkQApp()  # 建立app
    win = pg.GraphicsLayoutWidget(show=True)  # 建立窗口
    win.setWindowTitle(u'pyqtgraph 实时波形显示工具')
    win.resize(800, 500)  # 小窗口大小
    # 创建图表
    historyLength = 200  # 横坐标长度
    p = win.addPlot()  # 把图p加入到窗口中
    p.showGrid(x=True, y=True)  # 把X和Y的表格打开
    p.setRange(xRange=[0, historyLength], yRange=[50000, 150000], padding=0)
    # p.setRange(xRange=[0, historyLength], yRange=[0, 500], padding=0)
    p.setLabel(axis='left', text='gray')  # 靠左
    p.setLabel(axis='bottom', text='时间')
    p.setTitle('gray graph')  # 表格的名字
    plot = p.plot()
    
    timer = pg.QtCore.QTimer()
    timer.timeout.connect(get_data) # 定时刷新数据显示
    timer.start(10) # 多少ms调用一次

    app.exec_()

    vid.release()

    cv2.destroyAllWindows() 
相关推荐
chao_7897 分钟前
二分查找篇——寻找旋转排序数组中的最小值【LeetCode】
python·线性代数·算法·leetcode·矩阵
金玉满堂@bj24 分钟前
PyCharm 中 Python 解释器的添加选项及作用
ide·python·pycharm
程序员三藏28 分钟前
如何使用Pytest进行测试?
自动化测试·软件测试·python·测试工具·职场和发展·测试用例·pytest
随心点儿1 小时前
使用python 将多个docx文件合并为一个word
开发语言·python·多个word合并为一个
不学无术の码农1 小时前
《Effective Python》第十三章 测试与调试——使用 Mock 测试具有复杂依赖的代码
开发语言·python
sleepybear11131 小时前
在Ubuntu上从零开始编译并运行Home Assistant源码并集成HACS与小米开源的Ha Xiaomi Home
python·智能家居·小米·home assistant·米家·ha xiaomi home
纪伊路上盛名在1 小时前
(鱼书)深度学习入门1:python入门
人工智能·python·深度学习
夏末蝉未鸣012 小时前
python transformers笔记(TrainingArguments类)
python·自然语言处理·transformer
德育处主任Pro2 小时前
「py数据分析」04如何将 Python 爬取的数据保存为 CSV 文件
数据库·python·数据分析
咸鱼鲸2 小时前
【PyTorch】PyTorch中数据准备工作(AI生成)
人工智能·pytorch·python