亚博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 mpmp_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, CompressedImagefrom rclpy.time import Time
import datetimeprint("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.zpointArray.points.append(point)self.pub_point.publish(pointArray)return frame, imgdef 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 dstclass 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 = Noneself.new_seconds = 0self.fps_seconds = 1self.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).nanosecondsdelta = datetime.timedelta(seconds=total_secs * 1e-9)seconds = delta.total_seconds()*100if self.new_seconds != 0:self.fps_seconds = seconds - self.new_secondsself.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:passfinally:esp_img.destroy_node()rclpy.shutdown()

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

构建后运行:ros2 run yahboom_esp32_mediapipe FaceMesh

效果如下

 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

想品客老师的第六天:函数

函数基础的部分写在这里 函数声明 在js里万物皆对象,函数也可以用对象的方式定义 let func new Function("title", "console.log(title)");func(我是参数title); 也可以对函数赋值: let cms function (title) {console.log(tit…

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

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

Spring Boot整合JavaMail实现邮件发送

一. 发送邮件原理 发件人【设置授权码】 - SMTP协议【Simple Mail TransferProtocol - 是一种提供可靠且有效的电子邮件传输的协议】 - 收件人 二. 获取授权码 开通POP3/SMTP,获取授权码 授权码是QQ邮箱推出的,用于登录第三方客户端的专用密码。适用…

AIGC数智化赋能:创新地方文旅内容生产传播模式

随着人工智能技术的迅猛发展,AI的应用领域日益扩大。当前,如何将AI这一新质生产力转化为新质传播力和影响力,进而为城市文化和旅游产业的内容创造、传播及消费模式带来全面革新,已成为数字化文旅发展的关键议题。 AI宣传——提升…

Tensor 基本操作4 理解 indexing,加减乘除和 broadcasting 运算 | PyTorch 深度学习实战

前一篇文章,Tensor 基本操作3 理解 shape, stride, storage, view,is_contiguous 和 reshape 操作 | PyTorch 深度学习实战 本系列文章 GitHub Repo: https://github.com/hailiang-wang/pytorch-get-started Tensor 基本使用 索引 indexing示例代码 加减…

STM32 硬件I2C读写

单片机学习! 目录 前言 一、步骤 二、配置I2C外设 2.1 开启I2C外设和GPIO口时钟 2.2 GPIO口初始化为复用开漏模式 2.3 结构体配置I2C 2.4 使能I2C 2.5 配置I2C外设总代码 三、指定地址写时序 3.1 生产起始条件S 3.2 监测EV5事件 3.3 发送从机地址 3.4 …

使用 Elasticsearch 导航检索增强生成图表

作者:来自 Elastic Louis Jourdain 及 Ivan Monnier 了解如何使用知识图谱来增强 RAG 结果,同时在 Elasticsearch 中高效存储图谱。本指南探讨了根据用户查询动态生成知识子图的详细策略。 检索增强生成 (RAG) 通过将大型语言模型 (LLM) 的输出基于事实数…

【后端开发】字节跳动青训营之性能分析工具pprof

性能分析工具pprof 一、测试程序介绍二、pprof工具安装与使用2.1 pprof工具安装2.2 pprof工具使用 资料链接: 项目代码链接实验指南pprof使用指南 一、测试程序介绍 package mainimport ("log""net/http"_ "net/http/pprof" // 自…

【落羽的落羽 数据结构篇】算法复杂度

文章目录 一、数据结构和算法简介二、算法复杂度1. 时间复杂度2. 空间复杂度 一、数据结构和算法简介 数据结构是计算机存储、组织数据的方式,指相互之间存在一种或多种特定关系的数据元素的集合。没有一种单一的数据结构对所有用途都有用,所以我们要学…

VsCode安装文档

一、下载 进入VS Code官网:Visual Studio Code - Code Editing. Redefined,点击 DownLoad for Windows下载windows版本 当然也可以点击旁边的箭头,下载Windows版本 或 Mac OS 版本 备注: Stable:稳定版Insiders&#…

32、【OS】【Nuttx】OSTest分析(1):stdio测试(二)

背景 接上篇wiki 31、【OS】【Nuttx】OSTest分析(1):stdio测试(一) 继续stdio测试的分析,上篇讲到标准IO端口初始化,单从测试内容来说其实很简单,没啥可分析的,但这几篇…

机器学习-核函数(Kernel Function)

核函数(Kernel Function)是一种数学函数,主要用于将数据映射到一个更高维的特征空间,以便于在这个新特征空间中更容易找到数据的结构或模式。核函数的主要作用是在不需要显式计算高维特征空间的情况下,通过内积操作来实…

计算机网络 (60)蜂窝移动通信网

一、定义与原理 蜂窝移动通信网是指将一个服务区分为若干蜂窝状相邻小区并采用频率空间复用技术的移动通信网。其原理在于,将移动通信服务区划分成许多以正六边形为基本几何图形的覆盖区域,称为蜂窝小区。每个小区设置一个基站,负责本小区内移…

win32汇编环境,函数的编写与调用、传值或返回值等

;运行效果 ;win32汇编环境,函数的编写与调用、传值或返回值等 ;函数在被调用的时候,如果此函数实体在前面,可以不用声明。如果实体在后面,则需要先声明。类似于下面的DlgProc函数,因为它的实体在后面,所以需要在调用之…

Oracle 创建用户和表空间

Oracle 创建用户和表空间 使用sys 账户登录 建立临时表空间 --建立临时表空间 CREATE TEMPORARY TABLESPACE TEMP_POS --创建名为TEMP_POS的临时表空间 TEMPFILE /oracle/oradata/POS/TEMP_POS.DBF -- 临时文件 SIZE 50M -- 其初始大小为50M AUTOEXTEND ON -- 支持…

Java 大视界 -- Java 大数据中的异常检测技术与应用(61)

💖亲爱的朋友们,热烈欢迎来到 青云交的博客!能与诸位在此相逢,我倍感荣幸。在这飞速更迭的时代,我们都渴望一方心灵净土,而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识,也…

Anonymous,Github 匿名化工具

一.Github 匿名化工具 Anonymous,会为 github 自动生成一个匿名化的URL,保护隐私和双盲评审 待添加...

Linux(Centos、Ubuntu) 系统安装jenkins服务

该文章手把手演示在Linux系统下如何安装jenkins服务、并自定义jenkins数据文件位置、以及jenkins如何设置国内镜像源加速,解决插件下载失败问题 安装方式:war包安装 阿里云提供的war下载源地址:https://mirrors.aliyun.com/jenkins/war/?s…

MongoDB实训:电子商务日志存储任务

一、实验目的 1. 理解如何通过Java API连接MongoDB数据库。 2. 学习在Java中使用MongoDB进行数据库操作,包括插入数据、查询数据以及数据统计等。 3. 掌握电子商务日志数据在MongoDB中的存储和操作方法。 二、实验环境准备 1. JAVA环境准备:确保…

计算机网络 (59)无线个人区域网WPAN

前言 无线个人区域网(WPAN,Wireless Personal Area Network)是一种以个人为中心,采用无线连接方式的个人局域网。 一、定义与特点 定义:WPAN是以个人为中心,实现活动半径小、业务类型丰富、面向特定群体的无…