从像素到卡路里:使用 GPT-4o Vision 构建高精度餐食追踪器

发布: (2026年2月22日 GMT+8 09:40)
6 分钟阅读
原文: Dev.to

Source: Dev.to

wellallyTech

Introduction

说实话:算卡路里是最糟糕的事。🍕 我们都有过这种经历——盯着餐厅里一盘“神秘意面”,猜测上面的帕尔马干酪是 20 克还是 50 克。传统的应用让你在无尽的“中号苹果”或“大号香蕉”数据库里搜索,这简直是扫兴。

但如果你的手机只需要看一眼你的盘子,就能准确知道里面有什么呢?在本教程中,我们将使用 GPT‑4o Vision APIFastAPIReact Native 构建一个高精度的膳食分析系统。我们将利用 多模态 AI 和先进的 提示工程,把非结构化的食物照片转化为结构化的营养数据。

如果你想掌握 计算机视觉大语言模型编排结构化数据抽取,那么你来对地方了!🚀

架构:从图像到洞察

为了确保高精度,我们并不只是“询问”AI照片中有什么。我们实现了一个多步骤的估算逻辑,考虑到份量大小、密度以及隐藏的成分(如油脂和脂肪)。

graph TD
    A[React Native App] -->|Capture Image| B(FastAPI Backend)
    B -->|Image Processing| C{GPT‑4o Vision}
    C -->|Reasoning| D[Volume & Density Estimation]
    D -->|Structured JSON| E[PostgreSQL Database]
    E -->|Nutritional Summary| A
    C -.->|Reference Data| F[Nutritional DB]

前置条件

  • GPT‑4o API 密钥 (OpenAI)
  • FastAPI 用于后端
  • React Native (Expo) 用于移动界面
  • PostgreSQL 用于持久化日志

第一步:秘密酱(The Prompt)

“猜测”和“精准”之间的差别在于提示。我们使用 Chain‑of‑Thought (CoT) 方法:不是直接询问卡路里,而是让模型先识别组成部分,估算它们的体积(毫升/克),再计算营养成分。

SYSTEM_PROMPT = """
You are a professional nutritionist. Analyze the provided image and:
1. Identify every food item.
2. Estimate the portion size (weight in grams or volume in ml).
3. Calculate Calories, Protein, Carbs, and Fats.
4. Provide a confidence score (0‑1).

Return the data strictly in JSON format.
"""

第2步:使用 FastAPI 实现后端

我们使用 Pydantic 来强制执行严格的模式,确保在 AI 对响应进行“创意”处理时,移动应用不会崩溃。

from fastapi import FastAPI, UploadFile, File
from pydantic import BaseModel
import openai
import base64

app = FastAPI()

class NutritionResult(BaseModel):
    food_name: str
    calories: int
    protein: float
    carbs: float
    fat: float
    confidence: float

@app.post("/analyze-meal", response_model=list[NutritionResult])
async def analyze_meal(file: UploadFile = File(...)):
    # Convert image to base64
    contents = await file.read()
    base64_image = base64.b64encode(contents).decode("utf-8")

    response = openai.chat.completions.create(
        model="gpt-4o",
        messages=[
            {"role": "system", "content": SYSTEM_PROMPT},
            {"role": "user", "content": [
                {"type": "text", "text": "Analyze this meal:"},
                {"type": "image_url", "image_url": {"url": f"data:image/jpeg;base64,{base64_image}"}}
            ]}
        ],
        response_format={"type": "json_object"},
    )

    return response.choices[0].message.content

步骤 3:使用 React Native 的移动 UI

在前端我们需要一个简洁的界面来拍摄照片并显示 “营养成分分解” 卡片。 🥑

import React, { useState } from "react";
import { View, Button, Image, Text } from "react-native";
import * as ImagePicker from "expo-image-picker";

export default function MealTracker() {
  const [image, setImage] = useState<string | null>(null);
  const [stats, setStats] = useState<any[] | null>(null);

  const pickImage = async () => {
    const result = await ImagePicker.launchCameraAsync({
      allowsEditing: true,
      aspect: [4, 3],
      quality: 0.8,
    });

    if (!result.canceled) {
      const uri = result.assets[0].uri;
      setImage(uri);
      uploadImage({ uri });
    }
  };

  const uploadImage = async (photo: { uri: string }) => {
    const formData = new FormData();
    // @ts-ignore – React Native expects this shape
    formData.append("file", {
      uri: photo.uri,
      name: "meal.jpg",
      type: "image/jpeg",
    });

    const res = await fetch("https://your-api.com/analyze-meal", {
      method: "POST",
      body: formData,
    });
    const data = await res.json();
    setStats(data);
  };

  return (
    <View>
      <Button title="Capture Meal" onPress={pickImage} />
      {image && <Image source={{ uri: image }} style={{ width: 200, height: 200 }} />}
      {stats && (
        <Text>
          Total Calories: {stats.reduce((acc: number, cur: any) => acc + cur.calories, 0)} kcal
        </Text>
      )}
    </View>
  );
}

高级模式与最佳实践 💡

上述实现适用于 MVP,但生产级 AI 应用需要更健全的错误处理、速率限制和缓存。对每一次扫描都使用 GPT‑4o 可能会导致成本飙升,因此为常见食品项目实现本地缓存是必不可少的。

专业提示: 想要获取包括处理“模糊照片”或“多盘子”等边缘情况的生产就绪示例,请查阅 WellAlly Tech 上的高级工程指南。

结论

我们刚刚搭建了 原始像素结构化健康数据 之间的桥梁。通过将 GPT‑4o 的视觉能力与强大的 FastAPI 后端相结合,我们创建了一个解决实际问题的工具:让健康追踪变得毫不费力。

接下来怎么办?

  • 微调:使用你的 PostgreSQL 数据对更小的模型进行微调,以适配特定菜系。
  • AR 覆盖:利用 React Native 相机在实时中直接在食物上叠加卡路里数。

你正在用多模态 LLM 构建什么?在下方留下评论吧!👇

Blog – 这是一个为想要突破 AI 集成边界的开发者提供的绝佳资源。

0 浏览
Back to Blog

相关文章

阅读更多 »