亚博microros小车-原生ubuntu支持系列:7-脸部检测

背景知识

官网介绍:

Face Mesh - mediapipe 

mpFaceMesh.FaceMesh() 类的参数有:self.staticMode, self.maxFaces, self.minDetectionCon, self.minTrackCon

    staticMode:是否将每帧图像作为静态图像处理。如果为 True,每帧都会进行人脸检测;如果为 False,在检测到人脸后进行跟踪,速度更快
    maxFaces:要检测的最大人脸数量
    minDetectionCon:检测的最小置信度阈值。低于此值的人脸将被忽略
    minTrackCon:跟踪的最小置信度阈值。低于此值的跟踪将被忽略

import cv2
import mediapipe as mp

mp_drawing = mp.solutions.drawing_utils#绘图工具
mp_facemesh = mp.solutions.face_mesh
#手部模型
faceMesh = mp_facemesh.FaceMesh(
        static_image_mode=False,
        max_num_faces=2,
        min_detection_confidence=0.75,
        min_tracking_confidence=0.75)

cap = cv2.VideoCapture(0)#打开默认摄像头
while True:
    ret,frame = cap.read()#读取一帧图像
    #图像格式转换
    frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
    # 因为摄像头是镜像的,所以将摄像头水平翻转
    # 不是镜像的可以不翻转
    frame= cv2.flip(frame,1)
    #输出结果
    results = faceMesh.process(frame)
    frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)

    if results.multi_face_landmarks:
      for face_landmarks in results.multi_face_landmarks:
        # 关键点可视化
        mp_drawing.draw_landmarks(
            frame, face_landmarks, mp_facemesh.FACEMESH_CONTOURS)
    cv2.imshow('MediaPipe face', frame)
    if cv2.waitKey(1) & 0xFF == 27:
        break
cap.release()

这几个基本格式类似的,就是换个模型,输出结果不同

效果:

脸部检测

src/yahboom_esp32_mediapipe/yahboom_esp32_mediapipe/目录下新建文件04_FaceMesh.py

代码如下

#!/usr/bin/env python3
# encoding: utf-8
#import ros lib
import rclpy
from rclpy.node import Node
from geometry_msgs.msg import Point
import mediapipe as mp
#import define msg
from yahboomcar_msgs.msg import PointArray
#import commom lib
import cv2 as cv
import numpy as np
import time
from cv_bridge import CvBridge
from sensor_msgs.msg import Image, CompressedImage

from rclpy.time import Time
import datetime

print("import done")


class FaceMesh(Node):
    def __init__(self, name,staticMode=False, maxFaces=2, minDetectionCon=0.5, minTrackingCon=0.5):
        super().__init__(name)
        self.mpDraw = mp.solutions.drawing_utils#画图
        self.mpFaceMesh = mp.solutions.face_mesh
        #模型初始化
        self.faceMesh = self.mpFaceMesh.FaceMesh(
            static_image_mode=staticMode,
            max_num_faces=maxFaces,
            min_detection_confidence=minDetectionCon,
            min_tracking_confidence=minTrackingCon )
        self.pub_point = self.create_publisher(PointArray,'/mediapipe/points',1000)
        self.lmDrawSpec = mp.solutions.drawing_utils.DrawingSpec(color=(0, 0, 255), thickness=-1, circle_radius=3)
        self.drawSpec = self.mpDraw.DrawingSpec(color=(0, 255, 0), thickness=1, circle_radius=1)

    def pubFaceMeshPoint(self, frame, draw=True):
        pointArray = PointArray()
        img = np.zeros(frame.shape, np.uint8)
        imgRGB = cv.cvtColor(frame, cv.COLOR_BGR2RGB)
        self.results = self.faceMesh.process(imgRGB)#检测
        if self.results.multi_face_landmarks:
            for i in range(len(self.results.multi_face_landmarks)):#输出关键点
                if draw: self.mpDraw.draw_landmarks(frame, self.results.multi_face_landmarks[i], self.mpFaceMesh.FACEMESH_CONTOURS, self.lmDrawSpec, self.drawSpec)
                self.mpDraw.draw_landmarks(img, self.results.multi_face_landmarks[i], self.mpFaceMesh.FACEMESH_CONTOURS, self.lmDrawSpec, self.drawSpec)
                for id, lm in enumerate(self.results.multi_face_landmarks[i].landmark):
                        point = Point()
                        point.x, point.y, point.z = lm.x, lm.y, lm.z
                        pointArray.points.append(point)
        self.pub_point.publish(pointArray)
        return frame, img

    def frame_combine(slef,frame, src):
        if len(frame.shape) == 3:
            frameH, frameW = frame.shape[:2]
            srcH, srcW = src.shape[:2]
            dst = np.zeros((max(frameH, srcH), frameW + srcW, 3), np.uint8)
            dst[:, :frameW] = frame[:, :]
            dst[:, frameW:] = src[:, :]
        else:
            src = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
            frameH, frameW = frame.shape[:2]
            imgH, imgW = src.shape[:2]
            dst = np.zeros((frameH, frameW + imgW), np.uint8)
            dst[:, :frameW] = frame[:, :]
            dst[:, frameW:] = src[:, :]
        return dst

class MY_Picture(Node):
    def __init__(self, name):
        super().__init__(name)
        self.bridge = CvBridge()
        self.sub_img = self.create_subscription(
            CompressedImage, '/espRos/esp32camera', self.handleTopic, 1) #获取esp32传来的图像

        self.last_stamp = None
        self.new_seconds = 0
        self.fps_seconds = 1
        self.face_mesh = FaceMesh('face_mesh')

    def handleTopic(self, msg):
        self.last_stamp = msg.header.stamp  
        if self.last_stamp:
            total_secs = Time(nanoseconds=self.last_stamp.nanosec, seconds=self.last_stamp.sec).nanoseconds
            delta = datetime.timedelta(seconds=total_secs * 1e-9)
            seconds = delta.total_seconds()*100

            if self.new_seconds != 0:
                self.fps_seconds = seconds - self.new_seconds

            self.new_seconds = seconds#保留这次的值

        start = time.time()
        frame = self.bridge.compressed_imgmsg_to_cv2(msg)
        frame = cv.resize(frame, (640, 480))
        cv.waitKey(10)
        frame, img = self.face_mesh.pubFaceMeshPoint(frame,draw=False)
        
        end = time.time()
        fps = 1 / ((end - start)+self.fps_seconds)
        text = "FPS : " + str(int(fps))
        cv.putText(frame, text, (20, 30), cv.FONT_HERSHEY_SIMPLEX, 0.9, (0, 0, 255), 1)

        dist = self.face_mesh.frame_combine(frame, img)
        cv.imshow('dist', dist)
        # print(frame)
    
        cv.waitKey(10)

def main():
    print("start it")
    rclpy.init()
    esp_img = MY_Picture("My_Picture")
    try:
            rclpy.spin(esp_img)
    except KeyboardInterrupt:
        pass
    finally:
        esp_img.destroy_node()
        rclpy.shutdown()

订阅esp32传出来的图像后,通过MediaPipe去做相关的识别后显示。主体流程跟之前一样,换了检测模型。

构建后运行:ros2 run yahboom_esp32_mediapipe FaceMesh

效果如下

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/959136.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

写作利器:如何用 PicGo + GitHub 图床提高创作效率

你好呀,欢迎来到 Dong雨 的技术小栈 🌱 在这里,我们一同探索代码的奥秘,感受技术的魅力 ✨。 👉 我的小世界:Dong雨 📌 分享我的学习旅程 🛠️ 提供贴心的实用工具 💡 记…

thingsboard 动态报警

前言 考虑将报警上下限写入设备属性,设备遥测数据与设备属性实时做报警逻辑。这样做的好处在于,可以动态修改设备属性,进而修改设备报警触发上下限。 1、修改设备属性 基于mq ,向设备写入属性。 topic v1/devices/me/attribut…

三、双链表

链表的种类有很多,单链表是不带头不循环单向链表,但双链表是带头循环双向链表,并且双链表还有一个哨兵位,哨兵位不是头节点 typedef int LTDataType;typedef struct ListNode{struct ListNode* next; //指针保存下⼀个结点的地址s…

(算法竞赛)使用广度优先搜索(BFS)解决迷宫最短路径问题

在这个充满奇思妙想的世界里,每一次探索都像是打开了一扇通往新世界的大门。今天,我们将踏上一段特别的旅程,去揭开那些隐藏在代码、算法、数学谜题或生活智慧背后的秘密。🎉😊 所以,系好安全带&#xff0…

支持大功率输出高速频闪的图像处理用光源控制器

机器视觉系统中的光源控制器在确保图像质量、提高系统稳定性、降低能耗以及方便系统扩展和升级等方面发挥着重要作用。它可提供稳定光源,调节参数,另外具有操作便捷性。 下面我们来看Gardasoft的光源控制器,Gardasoft拥有作为图像处理用LED光…

鸿蒙模块概念和应用启动相关类(HAP、HAR、HSP、AbilityStage、UIAbility、WindowStage、window)

目录 鸿蒙模块概念 HAP entry feature har shared 使用场景 HAP、HAR、HSP介绍 HAP、HAR、HSP开发 应用的启动 AbilityStage UIAbility WindowStage Window 拉起应用到显示到前台流程 鸿蒙模块概念 HAP hap包是手机安装的最小单元,1个app包含一个或…

为什么IDEA提示不推荐@Autowired❓️如果使用@Resource呢❓️

前言 在使用 Spring 框架时,依赖注入(DI)是一个非常重要的概念。通过注解,我们可以方便地将类的实例注入到其他类中,提升开发效率。Autowired又是被大家最为熟知的方式,但很多开发者在使用 IntelliJ IDEA …

【Uniapp-Vue3】uni-icons的安装和使用

一、uni-icon的安装 进入到如下页面中,点击“点击下载&安装”。 uni-icons 图标 | uni-app官网 点击“下载插件并导入HBuilder”,如果没有登录就登陆一下 网页中会打开Hbuilder,进入Hbuilder以后,选择需要使用该插件的项目进…

论文笔记(六十三)Understanding Diffusion Models: A Unified Perspective(三)

Understanding Diffusion Models: A Unified Perspective(三) 文章概括 文章概括 引用: article{luo2022understanding,title{Understanding diffusion models: A unified perspective},author{Luo, Calvin},journal{arXiv preprint arXiv:…

群晖docker获取私有化镜像http: server gave HTTP response to HTTPS client].

群晖docker获取私有化镜像提示http: server gave HTTP response to HTTPS clien 问题描述 层级时间用户事件Information2023/07/08 12:47:45cxlogeAdd image from xx.xx.31.240:1923/go-gitea/gitea:1.19.3Error2023/07/08 12:47:48cxlogeFailed to pull image [Get "http…

Charles 4.6.7 浏览器网络调试指南:HTTPS抓包(三)

概述 在现代互联网应用中,网络请求和响应是服务交互的核心。对于开发者和测试人员来说,能够准确捕获并分析这些请求,是保证系统稳定性和性能的关键。Charles作为一个强大的网络调试工具,不仅可以捕获普通的HTTP请求,还…

从spec到iso的koji使用

了解一下Linux发行版流程::从spec到iso的koji使用 for Fedora 41。 Fedora 41有24235个包,我们选择 minimal 的几十个源码包,百多个rpm包构建。 配3台服务器 40C64G 44C64G 80C128G,有点大材小用,一台就够了 &#xf…

系统思考—复杂问题的根源分析

在企业中,许多问题看似简单,背后却潜藏着复杂的因果关系。传统的思维方式往往只能看到表面,而无法深入挖掘问题的真正根源。我们常常通过“表面解决”来应对眼前的症状,但这往往只是治标不治本。 比如,销量下降时&…

低代码开发:效率革命与市场机遇

一、引言 IT技术推动了全球信息化的浪潮,然而软件开发效率的提升却未能像摩尔定律那样迅速,逐渐成为发展的瓶颈。近年来,低代码领域发展迅猛,不仅诞生了估值超10亿美元的独角兽OutSystems,还吸引了AWS、Google、Micro…

leetcode——相交链表(java)

给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null 。 图示两个链表在节点 c1 开始相交: 题目数据 保证 整个链式结构中不存在环。 注意,函数返回结果后&…

浅谈APP之历史股票通过echarts绘图

浅谈APP之历史股票通过echarts绘图 需求描述 今天我们需要做一个简单的历史股票收盘价格通过echarts进行绘图,效果如下: 业务实现 代码框架 代码框架如下: . 依赖包下载 我们通过网站下载自己需要的涉及的图标,勾选之后进…

【音视频处理】FFmpeg for Windows 安装教程

FFmpeg 是一个强大的多媒体处理工具,可以处理音视频的各种任务,包括格式转换、裁剪、合并等操作,市面上你可以看到的几乎所有的音视频的处理工具内部都离不开FFmpeg的身影。 本文将详细介绍如何在 Windows 系统上安装 FFmpeg。 1. 下载 FFmp…

leetcode刷题记录(八十一)——236. 二叉树的最近公共祖先

(一)问题描述 236. 二叉树的最近公共祖先 - 力扣(LeetCode)236. 二叉树的最近公共祖先 - 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。百度百科 [https://baike.baidu.com/item/%E6%9C%80%E8%BF%91%E5%85%AC%E5%85%B…

【28】Word:石油化工设备技术❗

目录 题目 NO1.2 NO3 NO4 题目 NO1.2 F12:另存为将“Word素材.docx”文件另存为“Word. docx”(“docx”为文件扩展名) 光标来到表格上方→插入→形状→新建画布→单击选中→格式→高度/宽度(格式→大小对话框→取消勾选✔锁定…

总线、UART、IIC、SPI

一图流 总线 概念 连接多个部件的信息传输线,是各部件共享的传输介质 类型 片内总线:连接处理器内核和外设的总线,在芯片内部 片外总线:连接芯片和其他芯片或者模块的总线 总线的通信 总线通信的方式 串行通信 数据按位顺序传…