欢迎加入开源鸿蒙PC社区:
https://harmonypc.csdn.net/

atomgit仓库地址:https://gitcode.com/feng8403000/mingshu_ai
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

一、功能概述

图片分析AI模块是命枢AI生命科学模拟器的核心功能之一,通过计算机视觉和大语言模型技术,实现基于面部照片的健康评估。该模块包含三个专业分析技能,能够综合评估用户的面部特征、健康状态和生活质量,为用户提供个性化的健康建议。

1.1 功能定位

图片分析AI模块在整体架构中的作用:

层级 功能 说明
输入层 图片上传 支持用户上传面部照片
处理层 多技能分析 并行调用三个AI技能进行综合分析
输出层 综合报告 生成详细的健康评估报告
应用层 健康建议 提供个性化健康指导

1.2 核心特性

  • 多技能协同分析:同时调用三个AI技能进行综合诊断
  • 视觉AI能力:支持图片输入,通过视觉模型进行分析
  • 实时进度显示:展示各技能的分析进度和状态
  • 综合评分系统:生成1-100分的生活质量评分
  • 个性化建议:根据分析结果提供针对性健康建议

1.3 三大核心技能

技能 功能 分析内容
ImageDiagnosisSkill 图片诊断 年龄预估、表情分析、肤色气色、健康等级
FaceFeatureSkill 面部特征 脸型、眼睛状态、鼻型、嘴唇状态、皮肤类型等
FaceHealthSkill 面部健康 疲劳程度、水分状态、皮肤弹性、健康问题识别

二、UI设计详解

2.1 整体布局

AI图片问诊采用模态框设计,包含以下区域:

┌─────────────────────────────────────────────┐
│ 🖼️ AI图片问诊                               │
├─────────────────────────────────────────────┤
│ [图片预览区域]                              │
│ ┌─────────────────────────────────────┐     │
│ │                                    │     │
│ │          上传的面部照片            │     │
│ │                                    │     │
│ └─────────────────────────────────────┘     │
├─────────────────────────────────────────────┤
│ [分析进度区域]                              │
│ 🖼️ ImageDiagnosisSkill   正在分析...       │
│ 👤 FaceFeatureSkill      正在分析...       │
│ 💚 FaceHealthSkill       正在分析...       │
├─────────────────────────────────────────────┤
│ [分析结果区域]                              │
│ 📊 综合分析报告                            │
│ ┌─────────────────────────────────────┐     │
│ │ 👤 基本信息                        │     │
│ │ 🎂 预估年龄: 25-30岁              │     │
│ │ 👥 性别: 未知                     │     │
│ │ 🔷 脸型: 椭圆形                   │     │
│ │ 😊 表情状态: 自信、平静、精神      │     │
│ └─────────────────────────────────────┘     │
│ ┌─────────────────────────────────────┐     │
│ │ 🧬 面部特征                        │     │
│ │ 👀 眼睛状态: 正常                 │     │
│ │ 👃 鼻型: 中等                     │     │
│ │ 👄 嘴唇状态: 红润                 │     │
│ │ 🧴 皮肤类型: 中性                 │     │
│ └─────────────────────────────────────┘     │
│ ┌─────────────────────────────────────┐     │
│ │ 💚 健康评估                        │     │
│ │ 综合健康评分: 85                   │     │
│ │ 🎨 肤色气色: 均匀                 │     │
│ │ 💧 水分状态: 适中                 │     │
│ │ 😴 疲劳程度: 轻度                 │     │
│ └─────────────────────────────────────┘     │
│ ┌─────────────────────────────────────┐     │
│ │ ⚠️ 需要关注的问题                 │     │
│ │ ⚡ 建议保证充足睡眠               │     │
│ │ ⚡ 注意补水保湿                   │     │
│ └─────────────────────────────────────┘     │
│ ┌─────────────────────────────────────┐     │
│ │ 💡 健康建议                       │     │
│ │ 1. 每天保持7-8小时睡眠            │     │
│ │ 2. 多喝水补充水分                 │     │
│ │ 3. 适当运动促进血液循环          │     │
│ └─────────────────────────────────────┘     │
└─────────────────────────────────────────────┘

2.2 核心组件设计

2.2.1 图片上传区域

上传区域采用拖拽风格设计:

<div class="diagnosis-upload-area" id="diagnosisUploadArea">
    <span style="font-size: 48px;">📷</span>
    <span>点击上传面部照片</span>
</div>
<input type="file" id="diagnosisImageUpload" accept="image/*" style="display: none;">

样式设计:

.diagnosis-upload-area {
    border: 2px dashed rgba(255, 255, 255, 0.2);
    border-radius: 12px;
    padding: 40px;
    text-align: center;
    cursor: pointer;
    transition: all 0.3s;
    margin-bottom: 20px;
}

.diagnosis-upload-area:hover {
    border-color: #4ecdc4;
    background: rgba(78, 205, 196, 0.1);
}
2.2.2 图片预览

图片预览区域展示上传的照片:

<img id="diagnosisImagePreview" src="" alt="预览">
#diagnosisImagePreview {
    width: 100%;
    border-radius: 8px;
    margin-bottom: 15px;
    display: none;
}
2.2.3 分析进度显示

实时展示三个技能的分析状态:

<div id="imageSkillProgress">
    <div class="skill-item" id="imageSkill1">
        <span class="skill-icon">🖼️</span>
        <span class="skill-name">ImageDiagnosisSkill</span>
        <span class="skill-status" id="imageStatus1">等待中...</span>
    </div>
    <div class="skill-item" id="imageSkill2">
        <span class="skill-icon">👤</span>
        <span class="skill-name">FaceFeatureSkill</span>
        <span class="skill-status" id="imageStatus2">等待中...</span>
    </div>
    <div class="skill-item" id="imageSkill3">
        <span class="skill-icon">💚</span>
        <span class="skill-name">FaceHealthSkill</span>
        <span class="skill-status" id="imageStatus3">等待中...</span>
    </div>
</div>

状态样式:

.skill-item {
    display: flex;
    align-items: center;
    padding: 8px 10px;
    margin: 5px 0;
    background: rgba(255, 255, 255, 0.05);
    border-radius: 6px;
}

.skill-status {
    font-size: 12px;
    padding: 3px 8px;
    border-radius: 10px;
    background: rgba(255, 255, 255, 0.1);
    color: #ccc;
}

.skill-status.running {
    background: #f39c12;
    color: #1a1a2e;
}

.skill-status.completed {
    background: #27ae60;
    color: #fff;
}

.skill-status.failed {
    background: #e74c3c;
    color: #fff;
}
2.2.4 分析结果卡片

结果展示采用卡片式布局,分为多个区域:

.diagnosis-result-section {
    background: rgba(255, 255, 255, 0.03);
    border-radius: 10px;
    padding: 12px;
    margin-bottom: 12px;
}

.diagnosis-section-title {
    color: #fdcb6e;
    font-weight: bold;
    margin-bottom: 10px;
    font-size: 14px;
}

.diagnosis-result-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 8px;
}

.diagnosis-result-item {
    background: rgba(255, 255, 255, 0.05);
    padding: 10px;
    border-radius: 8px;
}

.diagnosis-result-label {
    color: #888;
    font-size: 11px;
    margin-bottom: 4px;
}

.diagnosis-result-value {
    color: #fff;
    font-weight: bold;
    font-size: 13px;
}
2.2.5 健康评分展示

综合健康评分采用大字体突出显示:

.diagnosis-health-score {
    text-align: center;
    padding: 15px;
    background: rgba(78, 205, 196, 0.1);
    border-radius: 10px;
    margin-bottom: 10px;
}

.health-score-label {
    color: #888;
    font-size: 12px;
    margin-bottom: 5px;
}

.health-score-value {
    font-size: 32px;
    font-weight: bold;
    margin-bottom: 8px;
}

.health-score-bar {
    width: 100%;
    height: 8px;
    background: rgba(255, 255, 255, 0.1);
    border-radius: 4px;
    overflow: hidden;
}

.health-score-fill {
    height: 100%;
    border-radius: 4px;
    transition: width 0.5s ease;
}
2.2.6 关注问题和建议区域
.diagnosis-concerns {
    background: rgba(231, 76, 60, 0.1);
    border-radius: 8px;
    padding: 10px;
}

.diagnosis-concern-item {
    color: #e74c3c;
    padding: 5px 0;
    font-size: 13px;
}

.diagnosis-suggestions {
    background: rgba(78, 205, 196, 0.1);
    border-radius: 8px;
    padding: 10px;
}

.diagnosis-suggestion-item {
    color: #4ecdc4;
    padding: 5px 0;
    font-size: 13px;
}

三、核心代码实现

3.1 ImageDiagnosisSkill - 图片诊断技能

图片诊断技能使用支持视觉输入的AI模型进行分析:

const ImageDiagnosisSkill = (function() {
    const API_URL = "https://api-ai.gitcode.com/v1/chat/completions";
    const API_KEY = "qBPRwKM_kHgbBjzzxvW9ws--";

    async function queryAI(prompt, imageBase64) {
        console.log('========== Image Diagnosis AI Request ==========');
        console.log('Image size:', imageBase64 ? imageBase64.length : 0, 'bytes');

        try {
            const response = await fetch(API_URL, {
                method: "POST",
                headers: {
                    "Authorization": `Bearer ${API_KEY}`,
                    "Content-Type": "application/json"
                },
                body: JSON.stringify({
                    model: "Qwen/Qwen3.5-35B-A3B",
                    messages: [{
                        role: "user",
                        content: [
                            { type: "image_url", image_url: { url: `data:image/jpeg;base64,${imageBase64}` } },
                            { type: "text", text: prompt }
                        ]
                    }],
                    stream: false,
                    max_tokens: 1024,
                    temperature: 0.7,
                    top_p: 0.95
                })
            });

            console.log('HTTP Status:', response.status);
            
            if (!response.ok) {
                const errorText = await response.text();
                console.error('HTTP Error:', errorText);
                throw new Error(`HTTP error! status: ${response.status}`);
            }

            const data = await response.json();
            console.log('Raw AI Response:', data);
            
            if (data.choices && data.choices[0] && data.choices[0].message) {
                return data.choices[0].message.content;
            }
            return null;
        } catch (error) {
            console.error('Image Diagnosis AI Error:', error.message);
            throw error;
        }
    }

    function parseResponse(response) {
        try {
            let jsonStr = response.trim();
            
            const codeBlockMatch = jsonStr.match(/```(?:json)?\s*([\s\S]*?)\s*```/);
            if (codeBlockMatch) {
                jsonStr = codeBlockMatch[1];
            }

            const braceStart = jsonStr.indexOf('{');
            const braceEnd = jsonStr.lastIndexOf('}');
            
            if (braceStart === -1 || braceEnd === -1) {
                throw new Error('No valid JSON found');
            }
            
            jsonStr = jsonStr.substring(braceStart, braceEnd + 1);
            jsonStr = jsonStr.replace(/,\s*([}\]])/g, '$1');
            
            return JSON.parse(jsonStr);
        } catch (error) {
            console.error('Parse Error:', error.message);
            return generateFallbackResponse();
        }
    }

    function generateFallbackResponse() {
        return {
            estimatedAge: '未知',
            expression: '正常',
            complexion: '一般',
            healthLevel: '一般',
            suggestions: ['保持良好作息', '注意饮食健康', '适当进行户外活动']
        };
    }

    async function analyze(imageBase64) {
        console.log('Image Diagnosis Skill - analyze called');
        
        const prompt = "请分析这张面部照片,评估人物的健康状态。请以JSON格式返回,包含以下字段:estimatedAge(预估年龄)、expression(表情分析,如:疲劳、精神、焦虑等)、complexion(肤色气色评估)、healthLevel(健康等级:优秀、良好、一般、较差)、suggestions(健康建议数组)。";

        const response = await queryAI(prompt, imageBase64);
        
        if (!response) {
            return generateFallbackResponse();
        }

        return parseResponse(response);
    }

    return {
        analyze: analyze,
        generateFallbackResponse: generateFallbackResponse
    };
})();

关键技术点

  • 使用Qwen/Qwen3.5-35B-A3B模型支持图片输入
  • 将图片转换为Base64格式发送
  • 构造包含图片URL和文本提示的请求体

3.2 FaceFeatureSkill - 面部特征分析技能

面部特征分析技能提取详细的面部特征信息:

const FaceFeatureSkill = (function() {
    const API_URL = "https://api-ai.gitcode.com/v1/chat/completions";
    const API_KEY = "qBPRwKM_kHgbBjzzxvW9ws--";

    async function queryAI(prompt, imageData) {
        try {
            const response = await fetch(API_URL, {
                method: "POST",
                headers: {
                    "Authorization": `Bearer ${API_KEY}`,
                    "Content-Type": "application/json"
                },
                body: JSON.stringify({
                    model: "deepseek-ai/DeepSeek-V3",
                    messages: [{
                        role: "user",
                        content: prompt
                    }],
                    stream: false,
                    max_tokens: 1024,
                    temperature: 0.5,
                    top_p: 0.95
                })
            });

            if (!response.ok) {
                throw new Error(`HTTP error! status: ${response.status}`);
            }

            const data = await response.json();
            if (data.choices && data.choices[0] && data.choices[0].message) {
                return data.choices[0].message.content;
            }
            return null;
        } catch (error) {
            console.error('Face Feature AI Error:', error.message);
            throw error;
        }
    }

    function parseResponse(response) {
        try {
            let jsonStr = response.trim();
            const codeBlockMatch = jsonStr.match(/```(?:json)?\s*([\s\S]*?)\s*```/);
            if (codeBlockMatch) {
                jsonStr = codeBlockMatch[1];
            }

            const braceStart = jsonStr.indexOf('{');
            const braceEnd = jsonStr.lastIndexOf('}');
            
            if (braceStart === -1 || braceEnd === -1) {
                throw new Error('No valid JSON found');
            }
            
            jsonStr = jsonStr.substring(braceStart, braceEnd + 1);
            jsonStr = jsonStr.replace(/,\s*([}\]])/g, '$1');
            
            return JSON.parse(jsonStr);
        } catch (error) {
            console.error('Face Feature Parse Error:', error.message);
            return generateFallbackResponse();
        }
    }

    async function analyze(imageData) {
        console.log('Face Feature Skill - analyzing image');
        
        const prompt = `你是一位专业的面部特征分析专家。请分析用户上传的面部照片,提取详细的面部特征信息。\n\n图片数据已提供。\n\n请以JSON格式返回详细的分析结果,包含以下所有字段:\n- estimatedAge: 预估年龄范围(字符串,如"25-30岁")\n- gender: 性别(男/女/未知)\n- faceShape: 脸型描述(圆形/方形/长形/心形/菱形/椭圆形等)\n- foreheadSize: 额头大小(宽阔/中等/狭窄)\n- eyeState: 眼睛状态详细描述(正常/轻度疲劳/中度疲劳/严重疲劳/黑眼圈/眼袋/充血)\n- eyeDistance: 两眼间距(宽/中等/窄)\n- noseShape: 鼻型(高鼻梁/低鼻梁/中等/蒜头鼻/鹰钩鼻等)\n- lipState: 嘴唇状态(红润/干燥/苍白/发紫)\n- skinType: 皮肤类型(干性/油性/中性/混合性/T区油性)\n- skinTone: 肤色色调(白皙/自然/小麦色/古铜色/暗沉)\n- facialSymmetry: 面部对称性(良好/一般/偏差)\n\n请确保所有字段都是字符串类型,不要使用对象或数组作为字段值。`;

        const response = await queryAI(prompt, imageData);
        
        if (!response) {
            return generateFallbackResponse();
        }

        try {
            const parsed = parseResponse(response);
            return sanitizeResponse(parsed);
        } catch (error) {
            console.error('Face Feature sanitize error:', error.message);
            return generateFallbackResponse();
        }
    }

    function sanitizeResponse(response) {
        const fallback = generateFallbackResponse();
        return {
            estimatedAge: ensureString(response.estimatedAge, fallback.estimatedAge),
            gender: ensureString(response.gender, fallback.gender),
            faceShape: ensureString(response.faceShape, fallback.faceShape),
            foreheadSize: ensureString(response.foreheadSize, fallback.foreheadSize),
            eyeState: ensureString(response.eyeState, fallback.eyeState),
            eyeDistance: ensureString(response.eyeDistance, fallback.eyeDistance),
            noseShape: ensureString(response.noseShape, fallback.noseShape),
            lipState: ensureString(response.lipState, fallback.lipState),
            skinType: ensureString(response.skinType, fallback.skinType),
            skinTone: ensureString(response.skinTone, fallback.skinTone),
            facialSymmetry: ensureString(response.facialSymmetry, fallback.facialSymmetry)
        };
    }

    function generateFallbackResponse() {
        return {
            estimatedAge: '未知',
            gender: '未知',
            faceShape: '椭圆形',
            foreheadSize: '中等',
            eyeState: '正常',
            eyeDistance: '中等',
            noseShape: '中等',
            lipState: '红润',
            skinType: '中性',
            skinTone: '自然',
            facialSymmetry: '良好'
        };
    }

    function ensureString(value, fallback) {
        if (value === null || value === undefined) return fallback;
        if (typeof value === 'string') return value.trim() || fallback;
        if (typeof value === 'object') {
            try {
                return JSON.stringify(value);
            } catch {
                return fallback;
            }
        }
        return String(value).trim() || fallback;
    }

    return {
        analyze: analyze
    };
})();

分析字段说明

字段 说明 示例值
estimatedAge 预估年龄范围 “25-30岁”
gender 性别 “男”、“女”、“未知”
faceShape 脸型 “椭圆形”、“方形”、“心形”
foreheadSize 额头大小 “宽阔”、“中等”、“狭窄”
eyeState 眼睛状态 “正常”、“轻度疲劳”、“黑眼圈”
eyeDistance 两眼间距 “宽”、“中等”、“窄”
noseShape 鼻型 “高鼻梁”、“中等”、“蒜头鼻”
lipState 嘴唇状态 “红润”、“干燥”、“苍白”
skinType 皮肤类型 “干性”、“油性”、“中性”
skinTone 肤色色调 “白皙”、“自然”、“暗沉”
facialSymmetry 面部对称性 “良好”、“一般”、“偏差”

3.3 FaceHealthSkill - 面部健康分析技能

面部健康分析技能评估整体健康状况:

const FaceHealthSkill = (function() {
    const API_URL = "https://api-ai.gitcode.com/v1/chat/completions";
    const API_KEY = "qBPRwKM_kHgbBjzzxvW9ws--";

    async function queryAI(prompt, imageData) {
        try {
            const response = await fetch(API_URL, {
                method: "POST",
                headers: {
                    "Authorization": `Bearer ${API_KEY}`,
                    "Content-Type": "application/json"
                },
                body: JSON.stringify({
                    model: "deepseek-ai/DeepSeek-V3",
                    messages: [{
                        role: "user",
                        content: prompt
                    }],
                    stream: false,
                    max_tokens: 1024,
                    temperature: 0.5,
                    top_p: 0.95
                })
            });

            if (!response.ok) {
                throw new Error(`HTTP error! status: ${response.status}`);
            }

            const data = await response.json();
            if (data.choices && data.choices[0] && data.choices[0].message) {
                return data.choices[0].message.content;
            }
            return null;
        } catch (error) {
            console.error('Face Health AI Error:', error.message);
            throw error;
        }
    }

    function parseResponse(response) {
        try {
            let jsonStr = response.trim();
            const codeBlockMatch = jsonStr.match(/```(?:json)?\s*([\s\S]*?)\s*```/);
            if (codeBlockMatch) {
                jsonStr = codeBlockMatch[1];
            }

            const braceStart = jsonStr.indexOf('{');
            const braceEnd = jsonStr.lastIndexOf('}');
            
            if (braceStart === -1 || braceEnd === -1) {
                throw new Error('No valid JSON found');
            }
            
            jsonStr = jsonStr.substring(braceStart, braceEnd + 1);
            jsonStr = jsonStr.replace(/,\s*([}\]])/g, '$1');
            
            return JSON.parse(jsonStr);
        } catch (error) {
            console.error('Face Health Parse Error:', error.message);
            return generateFallbackResponse();
        }
    }

    function generateFallbackResponse() {
        return {
            complexion: '正常',
            signsOfFatigue: '否',
            hydrationLevel: '适中',
            overallHealth: '良好',
            skinElasticity: '良好',
            acneOrMarks: '无',
            darkCircles: '无',
            puffiness: '无',
            concerns: [],
            lifeQualityScore: 75,
            healthTips: ['保持良好生活习惯', '注意营养均衡', '保证充足睡眠']
        };
    }

    async function analyze(imageData) {
        console.log('Face Health Skill - analyzing image');
        
        const prompt = `你是一位专业的面部健康分析专家。请通过面部照片详细分析用户的健康状况,给出全面的健康评估。\n\n图片数据已提供。\n\n请以JSON格式返回详细的健康分析结果,包含以下所有字段:\n- complexion: 肤色气色详细描述(红润/苍白/暗沉/发黄/均匀/不均匀/潮红)\n- signsOfFatigue: 疲劳程度评估(是/否,以及轻度/中度/重度)\n- hydrationLevel: 皮肤水分状态评估(充足/适中/轻度缺水/中度缺水/严重缺水)\n- overallHealth: 整体健康评估(优秀/良好/一般/偏差/较差)\n- skinElasticity: 皮肤弹性(良好/一般/松弛)\n- acneOrMarks: 痘痘或痘印情况(有/无,以及轻微/中等/严重)\n- darkCircles: 黑眼圈情况(无/轻微/中等/严重)\n- puffiness: 面部浮肿情况(无/轻微/中等/明显)\n- concerns: 需要关注的健康问题列表(字符串数组)\n- lifeQualityScore: 生活质量评分(1-100的整数)\n- healthTips: 个性化健康提示(字符串数组)\n\n请确保所有字段类型正确,concerns和healthTips必须是字符串数组。`;

        const response = await queryAI(prompt, imageData);
        
        if (!response) {
            return generateFallbackResponse();
        }

        try {
            const parsed = parseResponse(response);
            return sanitizeResponse(parsed);
        } catch (error) {
            console.error('Face Health sanitize error:', error.message);
            return generateFallbackResponse();
        }
    }

    function sanitizeResponse(response) {
        const fallback = generateFallbackResponse();
        return {
            complexion: ensureString(response.complexion, fallback.complexion),
            signsOfFatigue: ensureString(response.signsOfFatigue, fallback.signsOfFatigue),
            hydrationLevel: ensureString(response.hydrationLevel, fallback.hydrationLevel),
            overallHealth: ensureString(response.overallHealth, fallback.overallHealth),
            skinElasticity: ensureString(response.skinElasticity, fallback.skinElasticity),
            acneOrMarks: ensureString(response.acneOrMarks, fallback.acneOrMarks),
            darkCircles: ensureString(response.darkCircles, fallback.darkCircles),
            puffiness: ensureString(response.puffiness, fallback.puffiness),
            concerns: ensureArray(response.concerns, fallback.concerns),
            lifeQualityScore: ensureNumber(response.lifeQualityScore, fallback.lifeQualityScore),
            healthTips: ensureArray(response.healthTips, fallback.healthTips)
        };
    }

    function ensureNumber(value, fallback) {
        if (value === null || value === undefined) return fallback;
        const num = parseInt(value, 10);
        if (isNaN(num)) return fallback;
        return Math.max(1, Math.min(100, num));
    }

    function ensureString(value, fallback) {
        if (value === null || value === undefined) return fallback;
        if (typeof value === 'string') return value.trim() || fallback;
        if (typeof value === 'object') {
            try {
                return JSON.stringify(value);
            } catch {
                return fallback;
            }
        }
        return String(value).trim() || fallback;
    }

    function ensureArray(value, fallback) {
        if (value === null || value === undefined) return fallback;
        if (Array.isArray(value)) return value;
        if (typeof value === 'string') {
            try {
                const parsed = JSON.parse(value);
                return Array.isArray(parsed) ? parsed : fallback;
            } catch {
                return [value];
            }
        }
        return fallback;
    }

    return {
        analyze: analyze
    };
})();

健康评估字段说明

字段 说明 示例值
complexion 肤色气色 “红润”、“苍白”、“暗沉”、“均匀”
signsOfFatigue 疲劳程度 “是,轻度”、“否”、“是,中度”
hydrationLevel 水分状态 “充足”、“适中”、“轻度缺水”
overallHealth 整体健康 “优秀”、“良好”、“一般”、“偏差”
skinElasticity 皮肤弹性 “良好”、“一般”、“松弛”
acneOrMarks 痘痘/痘印 “无”、“轻微”、“中等”、“严重”
darkCircles 黑眼圈 “无”、“轻微”、“中等”、“严重”
puffiness 面部浮肿 “无”、“轻微”、“中等”、“明显”
concerns 关注问题 [“建议保证充足睡眠”, “注意补水保湿”]
lifeQualityScore 生活质量评分 85
healthTips 健康提示 [“每天保持7-8小时睡眠”, “多喝水补充水分”]

3.4 图片上传处理

图片上传和Base64编码处理:

function handleImageUpload(event) {
    const file = event.target.files[0];
    if (!file) return;

    const reader = new FileReader();
    reader.onload = function(e) {
        selectedImageData = e.target.result.split(',')[1];
        
        const preview = document.getElementById('diagnosisImagePreview');
        const uploadArea = document.getElementById('diagnosisUploadArea');
        const analyzeBtn = document.getElementById('diagnosisAnalyzeBtn');

        if (preview) {
            preview.src = e.target.result;
            preview.style.display = 'block';
        }
        if (uploadArea) uploadArea.style.display = 'none';
        if (analyzeBtn) analyzeBtn.style.display = 'block';
    };
    reader.readAsDataURL(file);
}

处理流程

  1. 获取上传的文件
  2. 使用FileReader读取文件
  3. 将图片转换为Data URL格式
  4. 提取Base64编码部分(去掉"data:image/jpeg;base64,"前缀)
  5. 显示预览并隐藏上传区域

3.5 多技能并行分析

三个技能并行执行,实时更新进度:

async function analyzeImage() {
    if (!selectedImageData) return;

    const resultArea = document.getElementById('diagnosisImageResult');
    const resultContent = document.getElementById('diagnosisImageContent');
    const analyzeBtn = document.getElementById('diagnosisAnalyzeBtn');

    if (analyzeBtn) analyzeBtn.style.display = 'none';
    if (resultArea) resultArea.style.display = 'block';
    if (resultContent) resultContent.innerHTML = `
        <div class="diagnosis-loading">
            <div style="margin-bottom: 15px;">🔍 正在进行面部综合分析...</div>
            <div id="imageSkillProgress">
                <div class="skill-item" id="imageSkill1">
                    <span class="skill-icon">🖼️</span>
                    <span class="skill-name">ImageDiagnosisSkill</span>
                    <span class="skill-status" id="imageStatus1">等待中...</span>
                </div>
                <div class="skill-item" id="imageSkill2">
                    <span class="skill-icon">👤</span>
                    <span class="skill-name">FaceFeatureSkill</span>
                    <span class="skill-status" id="imageStatus2">等待中...</span>
                </div>
                <div class="skill-item" id="imageSkill3">
                    <span class="skill-icon">💚</span>
                    <span class="skill-name">FaceHealthSkill</span>
                    <span class="skill-status" id="imageStatus3">等待中...</span>
                </div>
            </div>
        </div>
        <style>/* 样式省略 */</style>
    `;

    try {
        console.log('========== 图片诊断开始 ==========');

        const updateStatus = (skillId, status, className) => {
            const statusEl = document.getElementById(status);
            if (statusEl) {
                statusEl.textContent = skillId;
                statusEl.className = 'skill-status ' + className;
            }
        };

        updateStatus('正在分析...', 'imageStatus1', 'running');
        const imagePromise = ImageDiagnosisSkill.analyze(selectedImageData).then(result => {
            updateStatus('✓ 完成', 'imageStatus1', 'completed');
            return result;
        }).catch(error => {
            updateStatus('✗ 失败', 'imageStatus1', 'failed');
            throw error;
        });

        updateStatus('正在分析...', 'imageStatus2', 'running');
        const featurePromise = FaceFeatureSkill.analyze(selectedImageData).then(result => {
            updateStatus('✓ 完成', 'imageStatus2', 'completed');
            return result;
        }).catch(error => {
            updateStatus('✗ 失败', 'imageStatus2', 'failed');
            throw error;
        });

        updateStatus('正在分析...', 'imageStatus3', 'running');
        const healthPromise = FaceHealthSkill.analyze(selectedImageData).then(result => {
            updateStatus('✓ 完成', 'imageStatus3', 'completed');
            return result;
        }).catch(error => {
            updateStatus('✗ 失败', 'imageStatus3', 'failed');
            throw error;
        });

        const [imageResult, featureResult, healthResult] = await Promise.all([
            imagePromise,
            featurePromise,
            healthPromise
        ]);

        console.log('图片诊断结果:', imageResult);
        console.log('面部特征:', featureResult);
        console.log('面部健康:', healthResult);

        await new Promise(resolve => setTimeout(resolve, 500));

        const combinedResult = combineImageResults(imageResult, featureResult, healthResult);
        displayImageResult(combinedResult);

        console.log('========== 图片诊断完成 ==========');
    } catch (error) {
        console.error('图片诊断错误:', error.message);
        if (resultContent) {
            resultContent.innerHTML = '<div style="color: #e74c3c;">❌ 分析失败:' + error.message + '</div>';
        }
    }
}

并行执行策略

  1. 同时启动三个技能的分析请求
  2. 使用Promise.all等待所有请求完成
  3. 实时更新每个技能的状态(等待中→正在分析→完成/失败)
  4. 所有技能完成后合并结果

3.6 结果合并

合并三个技能的分析结果:

function combineImageResults(image, feature, health) {
    return {
        estimatedAge: feature.estimatedAge || '未知',
        gender: feature.gender || '未知',
        faceShape: feature.faceShape || '未知',
        foreheadSize: feature.foreheadSize || '中等',
        eyeState: feature.eyeState || '正常',
        eyeDistance: feature.eyeDistance || '中等',
        noseShape: feature.noseShape || '中等',
        lipState: feature.lipState || '红润',
        skinType: feature.skinType || '中性',
        skinTone: feature.skinTone || '自然',
        facialSymmetry: feature.facialSymmetry || '良好',
        expression: image.expression || '未知',
        complexion: health.complexion || image.complexion || '正常',
        signsOfFatigue: health.signsOfFatigue || '否',
        hydrationLevel: health.hydrationLevel || '适中',
        skinElasticity: health.skinElasticity || '良好',
        acneOrMarks: health.acneOrMarks || '无',
        darkCircles: health.darkCircles || '无',
        puffiness: health.puffiness || '无',
        healthLevel: health.overallHealth || image.healthLevel || '良好',
        lifeQualityScore: health.lifeQualityScore || 75,
        concerns: health.concerns && health.concerns.length > 0 ? health.concerns : [],
        suggestions: health.healthTips && health.healthTips.length > 0 ? health.healthTips : ['继续保持良好的生活习惯']
    };
}

合并策略

  • 面部特征信息优先取FaceFeatureSkill的结果
  • 健康状态信息优先取FaceHealthSkill的结果
  • 年龄、表情等信息综合三个技能的结果
  • 确保所有字段都有默认值

3.7 结果展示

渲染综合分析报告:

function displayImageResult(result) {
    const resultContent = document.getElementById('diagnosisImageContent');
    if (!resultContent) return;

    function getHealthColor(level) {
        const colors = {
            '优秀': '#27ae60',
            '良好': '#4ecdc4',
            '一般': '#f39c12',
            '偏差': '#e74c3c',
            '较差': '#e74c3c',
            '疲惫': '#e74c3c',
            '正常': '#27ae60',
            '干燥': '#f39c12',
            '油腻': '#f39c12',
            '红润': '#27ae60',
            '苍白': '#e74c3c',
            '暗沉': '#f39c12',
            '发黄': '#f39c12',
            '无': '#27ae60',
            '轻微': '#f39c12',
            '轻度': '#f39c12',
            '中等': '#e67e22',
            '严重': '#e74c3c',
            '明显': '#e74c3c'
        };
        return colors[level] || '#fff';
    }

    function getScoreColor(score) {
        if (score >= 80) return '#27ae60';
        if (score >= 60) return '#4ecdc4';
        if (score >= 40) return '#f39c12';
        return '#e74c3c';
    }

    let html = `
        <div class="diagnosis-section-header">📊 综合分析报告</div>
        
        <div class="diagnosis-result-section">
            <div class="diagnosis-section-title">👤 基本信息</div>
            <div class="diagnosis-result-grid">
                <div class="diagnosis-result-item">
                    <div class="diagnosis-result-label">🎂 预估年龄</div>
                    <div class="diagnosis-result-value">${result.estimatedAge || '未知'}</div>
                </div>
                <div class="diagnosis-result-item">
                    <div class="diagnosis-result-label">👥 性别</div>
                    <div class="diagnosis-result-value">${result.gender || '未知'}</div>
                </div>
                <div class="diagnosis-result-item">
                    <div class="diagnosis-result-label">🔷 脸型</div>
                    <div class="diagnosis-result-value">${result.faceShape || '未知'}</div>
                </div>
                <div class="diagnosis-result-item">
                    <div class="diagnosis-result-label">😊 表情状态</div>
                    <div class="diagnosis-result-value">${result.expression || '未知'}</div>
                </div>
            </div>
        </div>
        
        <div class="diagnosis-result-section">
            <div class="diagnosis-section-title">🧬 面部特征</div>
            <div class="diagnosis-result-grid">
                <div class="diagnosis-result-item">
                    <div class="diagnosis-result-label">👀 眼睛状态</div>
                    <div class="diagnosis-result-value" style="color: ${getHealthColor(result.eyeState)}">${result.eyeState || '正常'}</div>
                </div>
                <div class="diagnosis-result-item">
                    <div class="diagnosis-result-label">📏 两眼间距</div>
                    <div class="diagnosis-result-value">${result.eyeDistance || '中等'}</div>
                </div>
                <div class="diagnosis-result-item">
                    <div class="diagnosis-result-label">👃 鼻型</div>
                    <div class="diagnosis-result-value">${result.noseShape || '中等'}</div>
                </div>
                <div class="diagnosis-result-item">
                    <div class="diagnosis-result-label">👄 嘴唇状态</div>
                    <div class="diagnosis-result-value" style="color: ${getHealthColor(result.lipState)}">${result.lipState || '红润'}</div>
                </div>
                <div class="diagnosis-result-item">
                    <div class="diagnosis-result-label">🧴 皮肤类型</div>
                    <div class="diagnosis-result-value">${result.skinType || '中性'}</div>
                </div>
                <div class="diagnosis-result-item">
                    <div class="diagnosis-result-label">🎨 肤色色调</div>
                    <div class="diagnosis-result-value">${result.skinTone || '自然'}</div>
                </div>
                <div class="diagnosis-result-item">
                    <div class="diagnosis-result-label">🖐️ 额头大小</div>
                    <div class="diagnosis-result-value">${result.foreheadSize || '中等'}</div>
                </div>
                <div class="diagnosis-result-item">
                    <div class="diagnosis-result-label">⚖️ 面部对称性</div>
                    <div class="diagnosis-result-value">${result.facialSymmetry || '良好'}</div>
                </div>
            </div>
        </div>
        
        <div class="diagnosis-result-section">
            <div class="diagnosis-section-title">💚 健康评估</div>
            <div class="diagnosis-health-score">
                <div class="health-score-label">综合健康评分</div>
                <div class="health-score-value" style="color: ${getScoreColor(result.lifeQualityScore)}">${result.lifeQualityScore || 75}</div>
                <div class="health-score-bar">
                    <div class="health-score-fill" style="width: ${result.lifeQualityScore || 75}%; background: ${getScoreColor(result.lifeQualityScore)};"></div>
                </div>
            </div>
            <div class="diagnosis-result-grid">
                <div class="diagnosis-result-item">
                    <div class="diagnosis-result-label">🎨 肤色气色</div>
                    <div class="diagnosis-result-value" style="color: ${getHealthColor(result.complexion)}">${result.complexion || '正常'}</div>
                </div>
                <div class="diagnosis-result-item">
                    <div class="diagnosis-result-label">💧 水分状态</div>
                    <div class="diagnosis-result-value" style="color: ${getHealthColor(result.hydrationLevel)}">${result.hydrationLevel || '适中'}</div>
                </div>
                <div class="diagnosis-result-item">
                    <div class="diagnosis-result-label">😴 疲劳程度</div>
                    <div class="diagnosis-result-value" style="color: ${getHealthColor(result.signsOfFatigue)}">${result.signsOfFatigue || '否'}</div>
                </div>
                <div class="diagnosis-result-item">
                    <div class="diagnosis-result-label">🧬 皮肤弹性</div>
                    <div class="diagnosis-result-value" style="color: ${getHealthColor(result.skinElasticity)}">${result.skinElasticity || '良好'}</div>
                </div>
                <div class="diagnosis-result-item">
                    <div class="diagnosis-result-label">🔴 痘痘/痘印</div>
                    <div class="diagnosis-result-value" style="color: ${getHealthColor(result.acneOrMarks)}">${result.acneOrMarks || '无'}</div>
                </div>
                <div class="diagnosis-result-item">
                    <div class="diagnosis-result-label">👁️ 黑眼圈</div>
                    <div class="diagnosis-result-value" style="color: ${getHealthColor(result.darkCircles)}">${result.darkCircles || '无'}</div>
                </div>
                <div class="diagnosis-result-item">
                    <div class="diagnosis-result-label">😮 面部浮肿</div>
                    <div class="diagnosis-result-value" style="color: ${getHealthColor(result.puffiness)}">${result.puffiness || '无'}</div>
                </div>
                <div class="diagnosis-result-item">
                    <div class="diagnosis-result-label">📈 健康等级</div>
                    <div class="diagnosis-result-value" style="color: ${getHealthColor(result.healthLevel)}">${result.healthLevel || '良好'}</div>
                </div>
            </div>
        </div>
    `;

    if (result.concerns && result.concerns.length > 0) {
        html += `
            <div class="diagnosis-result-section">
                <div class="diagnosis-section-title">⚠️ 需要关注的问题</div>
                <div class="diagnosis-concerns">`;
        result.concerns.forEach((concern, index) => {
            html += `<div class="diagnosis-concern-item">⚡ ${concern}</div>`;
        });
        html += '</div></div>';
    }

    if (result.suggestions && result.suggestions.length > 0) {
        html += `
            <div class="diagnosis-result-section">
                <div class="diagnosis-section-title">💡 健康建议</div>
                <div class="diagnosis-suggestions">`;
        result.suggestions.forEach((suggestion, index) => {
            html += `<div class="diagnosis-suggestion-item">${index + 1}. ${suggestion}</div>`;
        });
        html += '</div></div>';
    }

    html += `
        <style>/* 样式省略 */</style>
    `;

    resultContent.innerHTML = html;
}

颜色编码规则

状态 颜色 说明
优秀/良好/正常/红润/无 #27ae60 绿色 健康状态
一般/轻度/轻微/适中/中等 #f39c12 橙色 中等状态
偏差/较差/严重/明显/苍白/暗沉 #e74c3c 红色 不良状态

四、技术亮点

4.1 视觉AI集成

使用Qwen/Qwen3.5-35B-A3B模型支持图片输入,实现基于面部照片的智能分析:

messages: [{
    role: "user",
    content: [
        { type: "image_url", image_url: { url: `data:image/jpeg;base64,${imageBase64}` } },
        { type: "text", text: prompt }
    ]
}]

4.2 多技能并行执行

通过Promise.all实现三个技能的并行调用,提升分析效率:

const [imageResult, featureResult, healthResult] = await Promise.all([
    imagePromise,
    featurePromise,
    healthPromise
]);

4.3 实时进度反馈

动态更新每个技能的分析状态,提升用户体验:

const updateStatus = (skillId, status, className) => {
    const statusEl = document.getElementById(status);
    if (statusEl) {
        statusEl.textContent = skillId;
        statusEl.className = 'skill-status ' + className;
    }
};

4.4 数据规范化处理

每个技能都包含数据规范化逻辑,确保返回数据格式正确:

function sanitizeResponse(response) {
    const fallback = generateFallbackResponse();
    return {
        complexion: ensureString(response.complexion, fallback.complexion),
        signsOfFatigue: ensureString(response.signsOfFatigue, fallback.signsOfFatigue),
        // ... 其他字段
    };
}

4.5 容错机制

每个技能都有fallback响应,确保即使AI调用失败也能返回默认数据:

function generateFallbackResponse() {
    return {
        estimatedAge: '未知',
        expression: '正常',
        complexion: '一般',
        healthLevel: '一般',
        suggestions: ['保持良好作息', '注意饮食健康', '适当进行户外活动']
    };
}

五、工作流程总结

5.1 图片分析流程

用户上传面部照片
      ↓
转换为Base64编码
      ↓
点击"开始分析"
      ↓
并行调用三个AI技能
      ↓
实时更新进度状态
      ↓
合并分析结果
      ↓
渲染综合报告

5.2 技能协作关系

┌───────────────────────────────────────────────────────────┐
│                    用户上传图片                          │
└───────────────────────────────────────────────────────────┘
                          │
                          ▼
┌───────────────────────────────────────────────────────────┐
│                  并行执行三个技能                         │
│  ┌─────────────────┐  ┌─────────────────┐              │
│  │ImageDiagnosis   │  │FaceFeature      │              │
│  │    Skill        │  │    Skill        │              │
│  │ - 年龄预估      │  │ - 脸型识别      │              │
│  │ - 表情分析      │  │ - 眼睛状态      │              │
│  │ - 肤色评估      │  │ - 鼻型分析      │              │
│  │ - 健康等级      │  │ - 嘴唇状态      │              │
│  └─────────────────┘  └─────────────────┘              │
│                         │                              │
│                         ▼                              │
│  ┌─────────────────────────────────────────┐            │
│  │           FaceHealth Skill             │            │
│  │  - 疲劳程度评估                        │            │
│  │  - 水分状态分析                        │            │
│  │  - 皮肤弹性评估                        │            │
│  │  - 痘痘/黑眼圈检测                     │            │
│  │  - 生活质量评分                        │            │
│  └─────────────────────────────────────────┘            │
└───────────────────────────────────────────────────────────┘
                          │
                          ▼
┌───────────────────────────────────────────────────────────┐
│                    合并分析结果                          │
│  - 基本信息:年龄、性别、脸型、表情                      │
│  - 面部特征:眼睛、鼻型、嘴唇、皮肤                      │
│  - 健康评估:疲劳、水分、弹性、评分                      │
│  - 关注问题:需要注意的健康问题                        │
│  - 健康建议:个性化健康指导                            │
└───────────────────────────────────────────────────────────┘

六、总结

图片分析AI模块是命枢AI生命科学模拟器的创新功能,通过计算机视觉技术实现面部健康评估。系统具有以下特点:

  1. 多模态输入:支持图片输入,结合视觉AI进行分析
  2. 多技能协同:三个专业技能并行分析,提供全面评估
  3. 实时反馈:动态展示分析进度,提升用户体验
  4. 智能数据处理:完善的数据规范化和容错机制
  5. 可视化报告:美观的分析报告展示,包含颜色编码

该模块为用户提供了一种新颖的健康评估方式,通过上传面部照片即可获得全面的健康分析报告和个性化建议,是AI技术在健康领域的创新应用。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐