当前位置: 首页 > article >正文

python 涉及opencv mediapipe知识,眨眼计数 供初学者参考

基本思路  我们知道正面侦测到人脸时,任意一只眼睛水平方向上的两个特征点构成水平距离,上下两个特征点构成垂直距离 当头像靠近或者远离摄像头时,垂直距离与水平距离的比值基本恒定 

根据这一思路 当闭眼时 垂直距离变小 比值固定小于某一个值 当睁眼时 比值大于某个比率,比如35%,我们将比值扩大一百倍 (35% X 100) 这样我们认为大于35时是睁眼 小于为闭眼,根据程序侦测画面帧数 我们认为某一段连续的帧画面就是同一个事件 所以我们只处理其中一帧画面。基本背景知识需要用到mediapipe中人脸模型 下面给出右眼特征点编号

完整代码:

import cv2
import cvzone
from cvzone.FaceMeshModule import FaceMeshDetector
from cvzone.PlotModule import  LivePlot
from PIL import Image, ImageDraw, ImageFont
import numpy as np

def putText2(img,text,pos,size=36,color=(255,0,0)):

    img_pil = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
    font = ImageFont.truetype(font=r'simsun.ttc', size=size)
    draw = ImageDraw.Draw(img_pil)
    draw.text(pos, text, font=font, fill=color)  # PIL中RGB=(255,0,0)表示红色
    img_cv = np.array(img_pil)                         # PIL图片转换为numpy
    img = cv2.cvtColor(img_cv, cv2.COLOR_RGB2BGR)      # PIL格式转换为OpenCV的BGR格式
    return img

cap=cv2.VideoCapture("out.mp4")
detector=FaceMeshDetector(maxFaces=1)
#绘制Y坐标为20到50之间的实时波形图,宽度 高度 范围
plotY=LivePlot(480,640,[20,50],invert=True)
idEyeList=[22,23,24,26,110,157,158,159,160,161,162,130]

ratioList=[]
blinkCouter=0
counter=0
color=(255,0,255)
while True:
    if cap.get(cv2.CAP_PROP_POS_FRAMES)==cap.get(cv2.CAP_PROP_FRAME_COUNT):
        cap.set(cv2.CAP_PROP_POS_FRAMES,0)

    success,img=cap.read()
    # print(img.shape)

    img, faces = detector.findFaceMesh(img,draw=False)
    if faces:
        face=faces[0]
        for id in idEyeList:
            cv2.circle(img,face[id],5,(255,0,255),cv2.FILLED)
            cv2.line(img,face[159],face[23],(0,255,0),1)
            cv2.line(img, face[130], face[243], (0, 255, 0), 1)
        leftUp=face[159]
        leftDown=face[23]

        leftLeft=face[130]
        leftRight=face[243]
        #垂直距离与水平距离
        lengthVer,_=detector.findDistance(leftUp,leftDown)
        lengthHor, _ = detector.findDistance(leftLeft,leftRight)
        # print("比率",lengthVer/lengthHor)

        #获取随时变化的值
        ratio=int((lengthVer/lengthHor)*100)

        #让波形看起来平滑
        ratioList.append(ratio)
        if len(ratioList)>10:
            ratioList.pop(0)

        ratioAvg=sum(ratioList)/len(ratioList)
        # imgPlot=plotY.update(ratio)

        if ratioAvg<40 and counter==0:
            blinkCouter += 1
            color=(0,255,0)
            counter=1
        if counter !=0:
            counter +=1
            #保持20毫秒内不重复计数
            if counter>20:
                color=(255,0,255)
                counter=0

        # cvzone.putTextRect(img,f'blink count:{blinkCouter}',(50,50),colorR=(0,255,0))
        cv2.rectangle(img,(50,50),(260,85),color,cv2.FILLED)
        img=putText2(img,f'眨眼计数:{blinkCouter}',(50,50),color=(0,0,255))

        imgPlot = plotY.update(int(ratioAvg),color)
        # cv2.imshow("Imgplot",imgPlot)
        cv2.resize(img, (640, 480))
        imgStack=cvzone.stackImages([img,imgPlot],2,1)

    cv2.imshow("img",imgStack)

    cv2.waitKey(1)

截取任意一帧画面演示效果:


http://www.kler.cn/a/161689.html

相关文章:

  • RabbitMQ高效的消息队列中间件原理及实践
  • 鸿蒙next版开发:相机开发-适配不同折叠状态的摄像头变更(ArkTS)
  • JVM 中的完整 GC 流程
  • STM32问题集
  • uniapp使用scroll-view下拉刷新与上滑加载
  • 【最新版】Stable Diffusion4.9(AI绘画)下载及安装教程(附软件安装包)!
  • 【Linux】进程通信之命名管道mkfifo
  • 【设计模式-3.1】结构型——外观模式
  • GO设计模式——5、建造者模式(创建型)
  • 深眸科技以机器视觉高性能优势,为消费电子行业提供优质解决方案
  • vuepress路径问题,导致图片不显示
  • 十一.图像处理与光学之图像缩放方式
  • Course2-Week3-使用机器学习的建议
  • 【开源】基于Vue.js的二手车交易系统
  • 力扣102. 二叉树的层序遍历
  • GO设计模式——14、代理模式(结构型)
  • 【深度学习】迁移学习中的领域转移及迁移学习的分类
  • 2024山东健博会,第六届济南国际大健康产业博览会5月举办
  • 1.PyTorch数据结构Tensor常用操作
  • ChatGPT/GPT4科研实践篇: AI绘图+论文写作+编程
  • ChatGPT学习笔记
  • yolov5 获取漏检图片脚本
  • 【Java】图论笔记
  • 2023-12-03 C语言最小二乘法备忘
  • 零基础自学C语言|深入理解指针 ④
  • 2002-2021年全国各地级市环境规制18个相关指标数据