通过摄像头检测步频

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

打开摄像头

循环读取视频帧

灰度转换

统计中间一行数值和

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

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

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

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

复制代码
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() 
相关推荐
用户8356290780519 分钟前
Python 删除 Excel 工作表中的空白行列
后端·python
Json_10 分钟前
使用python-fastApi框架开发一个学校宿舍管理系统-前后端分离项目
后端·python·fastapi
数据智能老司机7 小时前
精通 Python 设计模式——分布式系统模式
python·设计模式·架构
数据智能老司机8 小时前
精通 Python 设计模式——并发与异步模式
python·设计模式·编程语言
数据智能老司机8 小时前
精通 Python 设计模式——测试模式
python·设计模式·架构
数据智能老司机8 小时前
精通 Python 设计模式——性能模式
python·设计模式·架构
c8i8 小时前
drf初步梳理
python·django
每日AI新事件8 小时前
python的异步函数
python
这里有鱼汤9 小时前
miniQMT下载历史行情数据太慢怎么办?一招提速10倍!
前端·python
databook18 小时前
Manim实现脉冲闪烁特效
后端·python·动效