将获取pose 服务拆分为两个服务

简单拆分

要将该代码拆分为两个服务,我们需要创建两个FastAPI应用。第一个服务(我们可以称之为ImageCaptureService)将负责捕获视频流中的图像,并将图像数据发送到第二个服务(我们可以称之为PoseEstimationService)。第二个服务将接收图像数据,使用MediaPipe处理图像以获取姿态数据,并将结果返回给客户端。
以下是拆分后的两个服务的基本结构:

ImageCaptureService

from fastapi import FastAPI, HTTPException
import cv2
app = FastAPI()
# 初始化摄像头
cap = cv2.VideoCapture("q888.mp4")
@app.get("/image")
def get_image():# 从摄像头读取一帧success, image = cap.read()if not success:raise HTTPException(status_code=500, detail="Failed to capture image")# 将图像转换为JPEG格式以进行传输ret, buffer = cv2.imencode('.jpg', image)image_data = buffer.tobytes()return {"image_data": image_data}
if __name__ == "__main__":# 运行服务,这里只是示例,实际部署时需要根据实际情况配置uvicorn.run(app, host="0.0.0.0", port=8001)

PoseEstimationService

from fastapi import FastAPI, HTTPException
import cv2
import mediapipe as mp
from pydantic import BaseModel
import requests
app = FastAPI()
# 创建一个模型来序列化姿态数据
class PoseData(BaseModel):landmarks: list
# 初始化MediaPipe的姿态估计模型
mp_pose = mp.solutions.pose
pose = mp_pose.Pose()
@app.post("/pose")
def get_pose(image_data: bytes):# 将接收到的图像数据转换为图像image = cv2.imdecode(np.frombuffer(image_data, np.uint8), cv2.IMREAD_COLOR)image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)# 处理图像以获取姿态数据results = pose.process(image)# 如果没有检测到姿态,返回错误if not results.pose_landmarks:raise HTTPException(status_code=404, detail="No pose detected")# 获取所有地标的位置和IDlandmarks = []for landmark in results.pose_landmarks.landmark:landmarks.append({'x': landmark.x,'y': landmark.y,'z': landmark.z,'visibility': landmark.visibility})# 返回姿态数据return PoseData(landmarks=landmarks)
if __name__ == "__main__":# 运行服务,这里只是示例,实际部署时需要根据实际情况配置uvicorn.run(app, host="0.0.0.0", port=8002)

请注意,为了实现两个服务之间的通信,ImageCaptureService需要发送HTTP请求到PoseEstimationService。这可以通过requests库实现,但是在上述代码中,为了简洁起见,我没有包含这部分代码。以下是如何在ImageCaptureService中发送请求到PoseEstimationService的示例:

# 在ImageCaptureService中
@app.get("/pose")
def get_pose():response = requests.get("http://poseestimationservice:8002/image")if response.status_code == 200:image_data = response.json()['image_data']# 发送图像数据到PoseEstimationServicepose_response = requests.post("http://poseestimationservice:8002/pose", json={"image_data": image_data})return pose_response.json()else:raise HTTPException(status_code=500, detail="Failed to get image from PoseEstimationService")

这里需要注意的是,服务之间的通信应该使用服务名作为主机名,而不是IP地址,这通常在容器化部署(如Kubernetes)中使用服务发现机制来实现。此外,requests库通常不用于在FastAPI应用内部进行异步HTTP请求,但在本例中为了简单起见,我们使用它来展示如何发送请求。在生产环境中,应该使用异步HTTP客户端,如httpx

同时并行

要让get_pose函数同时异步请求多个get_pose_data函数,你可以使用asyncio.gather来并发运行多个协程。以下是如何修改get_pose函数以并发执行多个get_pose_data请求的示例:

from fastapi import FastAPI, HTTPException
import cv2
import numpy as np
import asyncio
import httpx
app = FastAPI()
# 初始化摄像头
cap = cv2.VideoCapture("q888.mp4")
# 异步函数,用于获取姿态数据
async def get_pose_data(image_data: bytes) -> Any:async with httpx.AsyncClient() as client:response = await client.post("http://poseestimationservice:8002/pose", json={"image_data": image_data})if response.status_code == 200:return response.json()else:raise HTTPException(status_code=500, detail="Failed to get pose data from PoseEstimationService")
@app.get("/poses", response_model=list)
async def get_poses():# 获取多个图像数据image_data_list = []for _ in range(5):  # 假设我们同时处理5个图像image_data = get_image()image_data_list.append(image_data)# 使用 asyncio.gather 并发执行多个 get_pose_data 协程pose_data_tasks = [get_pose_data(image_data) for image_data in image_data_list]pose_data_list = await asyncio.gather(*pose_data_tasks)return pose_data_list
def get_image():# 从摄像头读取一帧success, image = cap.read()if not success:raise HTTPException(status_code=500, detail="Failed to capture image")# 将图像转换为JPEG格式以进行传输ret, buffer = cv2.imencode('.jpg', image)image_data = buffer.tobytes()return image_data
if __name__ == "__main__":# 运行服务,这里只是示例,实际部署时需要根据实际情况配置uvicorn.run(app, host="0.0.0.0", port=8001)

在这个示例中,get_poses函数现在获取多个图像数据(这里假设5个),并为每个图像数据创建一个get_pose_data协程。然后,使用asyncio.gather来并发执行这些协程。asyncio.gather将等待所有协程完成,并返回它们的返回值列表。
这样,get_poses函数将同时异步地请求多个get_pose_data,并且当所有请求都完成后,将返回一个包含所有结果的列表。
请注意,get_image函数是同步的,因此在这个例子中,我们连续调用它5次来获取5个图像。在实际应用中,你可能希望以某种异步方式获取图像,以避免阻塞事件循环。

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

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

相关文章

深入剖析多个表left join on的执行步骤原理:实战案例解析与原理探讨

文章目录 文章导图前言初始化数据-建表两个表left jion多表-left jion on c.bidb.bid分析|执行步骤和结果理解 变形-修改c表数据变形1变形2 总结 多表-left jion on c.aida.aid分析执行步骤和结果理解 变形-修改c表数据变形1变形2 解答开头总结 Left join on系列文章测试一下你…

ubuntu添加软件快捷方式

# 该目录下存放着所有的快捷方式文件 cd /usr/share/applications/ # 创建一个快捷方式文件 sudo touch your_app_name.desktop # 编辑快捷方式文件 sudo gedit your_app_name.desktop把👇的内容复制进your_app_name.desktop文件中,这是最简化版本 [Des…

数据结构第24节 二分查找

二分查找(Binary Search),也被称为折半查找,是一种在有序数组中查找特定元素的高效算法。它的基本思想是将查找区间分为两部分,通过比较中间元素与目标值来决定下一步是在哪一半继续查找。 二分查找的步骤&#xff1a…

​Chrome 插件: GoFullPage 一键搞定全网页截图

在互联网时代,网页截图已成为我们日常工作和生活中不可或缺的部分。无论是保存重要信息、制作教程,还是分享有趣的内容,截图功能都显得尤为重要。然而,常规的截图工具往往只能截取当前屏幕的内容,对于长网页则显得力不…

做个简单的知识付费网站需要什么方式

网站是线上承载信息宣传的主要工具之一,也是企业公司发展的重要工具之一,除了固定信息呈现外,还有不少商家具备各种方式的干货输出能力,或者想以内容售卖获得一定营收。 如教培机构、自媒体、网校、知识生产者、领域达人等都具备…

构建艺术:在Gradle中定制化输出的精粹

构建艺术:在Gradle中定制化输出的精粹 引言 Gradle是一个高度可配置的构建自动化工具,它广泛应用于现代软件开发中。在构建过程中,合理地配置构建输出对于项目的构建效率、部署和维护至关重要。本文将深入探讨如何在Gradle中配置构建输出&a…

【unity笔记】九、Unity添加串口通信

unity仿真使用虚拟串口调试。下面为简单流程。 常用串口调试软件在这里下载。 1.虚拟串口 添加虚拟串口,这里使用com1 com2 2. 串口调试 在这里为虚拟串口发送消息。 3. unity配置 3.1 设置 在文件->生成设置->玩家设置->玩家->其他设置 中找到…

【机器学习】逻辑回归的原理、应用与扩展

文章目录 一、逻辑回归概述二、Sigmoid函数与损失函数2.1 Sigmoid函数2.2 损失函数 三、多分类逻辑回归与优化方法3.1 多分类逻辑回归3.2 优化方法 四、特征离散化 一、逻辑回归概述 逻辑回归是一种常用于分类问题的算法。大家熟悉的线性回归一般形式为 Y a X b \mathbf{Y}…

初学SpringMVC之 JSON 篇

JSON(JavaScript Object Notation,JS 对象标记)是一种轻量级的数据交换格式 采用完全独立于编程语言的文本格式来存储和表示数据 JSON 键值对是用来保存 JavaScript 对象的一种方式 比如:{"name": "张三"}…

「Pytorch」roLabelImg 图像异常旋转 bug

在进行Yolo-obb 模型训练的时候需要标注旋转框,roLabelImg 是比较推荐的一款旋转框标注工具,既可以标注正常的矩形框,还可以标注旋转框 roLabelImg Github 地址:https://github.com/HumanSignal/labelImg 但是在使用过程中遇到了…

SpringCloud学习

认识微服务 1.单体架构:将业务的所有功能集中在一个项目中开发,打成一个包部署 优点:架构简单 部署成本低 缺点:耦合度高 2.分布式架构:根据业务功能对系统进行拆分,每个业务模块作为独立项目开发&…

k8s record 20240710 监控

不是adaptor 是opetator 案例 监控有了,日志搜集呢? 一、kubelet 的小弟 kubelet — 负责维护容器的生命周期,节点和集群其他部分通信 cAdvisor 集成在 Kubernetes 的 kubelet 中,能够自动发现和监控集群中所有的容器。dockers…

005-基于Sklearn的机器学习入门:逻辑回归

本节将介绍机器学习中一种简单而又经典的分类算法:逻辑回归。 机器学习:逻辑回归原理_机器学习做回归的原理-CSDN博客 机器学习实战:Python基于Logistic逻辑回归进行分类预测(一)_lr逻辑回归 python-CSDN博客

创业者一定要做好时间管理

2024.7.5 最近接了两个项目,给我拖入了战争泥潭,耗费了大量的时间和精力。再加上今天不知道咋回事,有好多客户来咨询,就搞得人很疲惫,脑袋快炸了一样,感觉再这样下去会积怨成疾。现在能深刻的体会到&#x…

YOLOv5白皮书-第Y5周:yolo.py文件解读

本文为365天深度学习训练营 中的学习记录博客 原作者:K同学啊|接辅导、项目定制 本次训练是在前文《YOLOv5白皮书-第Y2周:训练自己的数据集》的基础上进行的。 前言 文件位置:./models/yolo.Py 这个文件是YOLOv5网络模型的搭建文件,如果你想改进YOLOv5&…

抖音短视频矩阵管理系统搭建全攻略:功能详解与实战应用

在短视频时代,抖音已经成为众多企业、网红、个人创作者不可或缺的传播平台。然而,如何高效管理多个抖音账号,实现内容、数据、粉丝的全方位掌控,成为了摆在大家面前的一道难题。本文将为大家深入解析抖音短视频矩阵管理系统的搭建…

Linux内核中的双向链表介绍

参考文章:https://www.cnblogs.com/liangliangge/p/11359196.html 相关结构体和api的介绍 1.1 struct list_head 用来创建双向循环链表的结构 1.2 INIT_LIST_HEAD 双向链表初始化,让一个链表节点首尾相连 1.3 list_add和list_add_tail 给链表增加一个结点 list_add :…

从0开始学习informer

目录 informer特点informer原理attention计算KL散度 backbone网络部分encoder输入输出部分embadding这里就不讲了 和transfomer一样EncoderStack decoder部分接下来就是最关键的结构 关于如何将输入经过注意力得到结果 结束,代码会放到下一篇讲 这里是原理 informer…

基于GIS矿产勘查靶区优选技术

定义: 找矿远景区(ore-finding prospect): 一般将中小比例尺(小于等于1:10万)成矿预测所圈定的找矿有利地段(preferable ore-finding area)成为找矿远景区 找矿靶区(ore-finding t…

车流量统计YOLOV8+DEEPSORT

车流量统计,YOLOV8NANODEEPSORT资源-CSDN文库 车流量统计YOLOV8DEEPSORT,目前支持PYTHON,C开发 PYTHON版本,需要YOLOV8,依赖PYTORCH C版本,只需要OPENCV