|
@@ -818,37 +818,46 @@ export class ImageAnalysisService {
|
|
|
): Promise<ImageAnalysisResult> {
|
|
): Promise<ImageAnalysisResult> {
|
|
|
const startTime = Date.now();
|
|
const startTime = Date.now();
|
|
|
|
|
|
|
|
- const prompt = `你是室内设计图分类专家,请快速分析这张图片的内容和质量,只输出JSON。
|
|
|
|
|
|
|
+ const prompt = `你是室内设计图分类专家,快速分析图片并只输出JSON。
|
|
|
|
|
|
|
|
-JSON格式:
|
|
|
|
|
|
|
+JSON格式(必须严格遵守):
|
|
|
{
|
|
{
|
|
|
- "category": "white_model或soft_decor或rendering或post_process",
|
|
|
|
|
- "confidence": 90,
|
|
|
|
|
- "spaceType": "客厅或卧室等",
|
|
|
|
|
- "description": "简短描述",
|
|
|
|
|
- "hasColor": true,
|
|
|
|
|
- "hasTexture": true,
|
|
|
|
|
- "hasLighting": true,
|
|
|
|
|
- "qualityScore": 85,
|
|
|
|
|
- "qualityLevel": "high",
|
|
|
|
|
- "sharpness": 80,
|
|
|
|
|
- "textureQuality": 85
|
|
|
|
|
|
|
+ "space": "客厅或卧室或厨房或卫生间或餐厅或书房或阳台等",
|
|
|
|
|
+ "stage": "white_model或soft_decor或rendering或post_process"
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-快速判断规则(严格执行):
|
|
|
|
|
|
|
+阶段判断规则(严格执行,从后向前判断):
|
|
|
|
|
+
|
|
|
|
|
+**第一步:判断是否为post_process(照片级后期)**
|
|
|
|
|
+✅ post_process的特征(满足3项以上即为后期):
|
|
|
|
|
+ - 照片级真实感,无法分辨是否为渲染图
|
|
|
|
|
+ - 光影自然柔和,无明显CG痕迹
|
|
|
|
|
+ - 细节丰富真实(布料褶皱、木纹纹理、金属反射)
|
|
|
|
|
+ - 色彩自然,无过度饱和或过度对比
|
|
|
|
|
+ - 景深效果自然(前景清晰,背景自然虚化)
|
|
|
|
|
+ - 材质表现真实(大理石纹理、玻璃透明度、金属质感)
|
|
|
|
|
+ - 整体画面像单反相机拍摄的照片
|
|
|
|
|
|
|
|
-- white_model: 统一灰白色/浅色,无材质纹理细节(可有家具和灯光)
|
|
|
|
|
|
|
+**第二步:排除post_process后,判断是否为rendering(CG渲染)**
|
|
|
|
|
+❌ rendering的特征(明显CG感):
|
|
|
|
|
+ - 明显的计算机渲染痕迹(过于完美、过于规整)
|
|
|
|
|
+ - 光影对比过强或过于均匀(V-Ray/3dsMax典型特征)
|
|
|
|
|
+ - 颜色过于饱和或过于艳丽
|
|
|
|
|
+ - 材质反射过于理想化(过于光滑、过于规则)
|
|
|
|
|
+ - 阴影边缘过于清晰或模糊不自然
|
|
|
|
|
|
|
|
-- soft_decor: 有真实材质纹理(木纹/布纹),有装饰色彩,但CG感不强
|
|
|
|
|
- ⚠️ 关键:软装可以有灯光!重点是材质真实但CG渲染感不强
|
|
|
|
|
|
|
+**第三步:判断soft_decor和white_model**
|
|
|
|
|
+- soft_decor: 有材质纹理和色彩,但CG感不强(偏手绘或简单渲染)
|
|
|
|
|
+- white_model: 灰白色调,无材质细节
|
|
|
|
|
|
|
|
-- rendering: 有材质纹理,有装饰色彩,CG计算机渲染感明显(V-Ray/3dsMax)
|
|
|
|
|
- ⚠️ 区分:rendering = CG感明显(能看出是3D渲染),质量70-89分
|
|
|
|
|
|
|
+**判断原则**:
|
|
|
|
|
+⚠️ 如果无法确定是rendering还是post_process,优先选择post_process
|
|
|
|
|
+⚠️ 现代高质量渲染图(超写实风格)应归类为post_process
|
|
|
|
|
+⚠️ 只有明显看出CG痕迹的才是rendering
|
|
|
|
|
|
|
|
-- post_process: 照片级真实感(看起来像真实拍摄),质量≥90分
|
|
|
|
|
- ⚠️ 区分:post_process = 照片级(不是普通CG渲染)`;
|
|
|
|
|
|
|
+只输出JSON,不要其他内容。`;
|
|
|
|
|
|
|
|
- const output = `{"category":"rendering","confidence":92,"spaceType":"卧室","description":"现代卧室","hasColor":true,"hasTexture":true,"hasLighting":true,"qualityScore":85,"qualityLevel":"high","sharpness":80,"textureQuality":85}`;
|
|
|
|
|
|
|
+ const output = `{"space":"客厅","stage":"post_process"}`;
|
|
|
|
|
|
|
|
try {
|
|
try {
|
|
|
console.log(`⏱️ [快速分析] 开始AI调用,图片Base64大小: ${(imageUrl.length / 1024 / 1024).toFixed(2)} MB`);
|
|
console.log(`⏱️ [快速分析] 开始AI调用,图片Base64大小: ${(imageUrl.length / 1024 / 1024).toFixed(2)} MB`);
|
|
@@ -863,12 +872,12 @@ JSON格式:
|
|
|
model: this.MODEL,
|
|
model: this.MODEL,
|
|
|
vision: true,
|
|
vision: true,
|
|
|
images: [imageUrl],
|
|
images: [imageUrl],
|
|
|
- max_tokens: 800 // 确保返回完整结果(避免截断)
|
|
|
|
|
|
|
+ max_tokens: 200 // 🔥 简化格式,只需200 tokens即可
|
|
|
}
|
|
}
|
|
|
);
|
|
);
|
|
|
|
|
|
|
|
const timeoutPromise = new Promise((_, reject) => {
|
|
const timeoutPromise = new Promise((_, reject) => {
|
|
|
- setTimeout(() => reject(new Error('AI分析超时(60秒)')), 60000); // 🔥 增加到60秒,防止大图超时
|
|
|
|
|
|
|
+ setTimeout(() => reject(new Error('AI分析超时(120秒)')), 120000); // 🔥 增加到120秒,处理大图片
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
const result = await Promise.race([aiPromise, timeoutPromise]) as any;
|
|
const result = await Promise.race([aiPromise, timeoutPromise]) as any;
|
|
@@ -879,42 +888,45 @@ JSON格式:
|
|
|
const analysisTime = Date.now() - startTime;
|
|
const analysisTime = Date.now() - startTime;
|
|
|
console.log(`✅ [快速分析] AI调用完成,耗时: ${(analysisTime / 1000).toFixed(2)}秒`);
|
|
console.log(`✅ [快速分析] AI调用完成,耗时: ${(analysisTime / 1000).toFixed(2)}秒`);
|
|
|
console.log(`📊 [快速分析] AI返回结果:`, {
|
|
console.log(`📊 [快速分析] AI返回结果:`, {
|
|
|
- 阶段分类: result.category,
|
|
|
|
|
- 置信度: `${result.confidence}%`,
|
|
|
|
|
- 空间类型: result.spaceType,
|
|
|
|
|
- 有颜色: result.hasColor,
|
|
|
|
|
- 有纹理: result.hasTexture,
|
|
|
|
|
- 有灯光: result.hasLighting,
|
|
|
|
|
- 质量分数: result.qualityScore
|
|
|
|
|
|
|
+ 空间: result.space,
|
|
|
|
|
+ 阶段: result.stage
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
|
|
+ // 🔥 根据阶段类型设置默认质量分数
|
|
|
|
|
+ const defaultQualityScore = {
|
|
|
|
|
+ 'white_model': 60,
|
|
|
|
|
+ 'soft_decor': 75,
|
|
|
|
|
+ 'rendering': 85,
|
|
|
|
|
+ 'post_process': 92
|
|
|
|
|
+ }[result.stage] || 75;
|
|
|
|
|
+
|
|
|
return {
|
|
return {
|
|
|
fileName: '',
|
|
fileName: '',
|
|
|
fileSize: 0,
|
|
fileSize: 0,
|
|
|
dimensions: basicInfo.dimensions,
|
|
dimensions: basicInfo.dimensions,
|
|
|
quality: {
|
|
quality: {
|
|
|
- score: result.qualityScore || 75,
|
|
|
|
|
- level: result.qualityLevel || 'medium',
|
|
|
|
|
- sharpness: result.sharpness || 75,
|
|
|
|
|
|
|
+ score: defaultQualityScore,
|
|
|
|
|
+ level: defaultQualityScore >= 85 ? 'high' : defaultQualityScore >= 70 ? 'medium' : 'low',
|
|
|
|
|
+ sharpness: defaultQualityScore,
|
|
|
brightness: 70,
|
|
brightness: 70,
|
|
|
contrast: 75,
|
|
contrast: 75,
|
|
|
detailLevel: 'basic',
|
|
detailLevel: 'basic',
|
|
|
pixelDensity: megapixels >= 2 ? 'high' : 'medium',
|
|
pixelDensity: megapixels >= 2 ? 'high' : 'medium',
|
|
|
- textureQuality: result.textureQuality || 75,
|
|
|
|
|
|
|
+ textureQuality: defaultQualityScore,
|
|
|
colorDepth: 75
|
|
colorDepth: 75
|
|
|
},
|
|
},
|
|
|
content: {
|
|
content: {
|
|
|
- category: result.category || 'rendering',
|
|
|
|
|
- confidence: result.confidence || 80,
|
|
|
|
|
- spaceType: result.spaceType || '未识别',
|
|
|
|
|
- description: result.description || '室内设计图',
|
|
|
|
|
|
|
+ category: result.stage || 'rendering', // 🔥 使用stage作为category
|
|
|
|
|
+ confidence: 90, // 🔥 默认置信度90%
|
|
|
|
|
+ spaceType: result.space || '未识别', // 🔥 使用space作为spaceType
|
|
|
|
|
+ description: `${result.space || ''}室内设计图`,
|
|
|
tags: [],
|
|
tags: [],
|
|
|
isArchitectural: true,
|
|
isArchitectural: true,
|
|
|
hasInterior: true,
|
|
hasInterior: true,
|
|
|
- hasFurniture: true,
|
|
|
|
|
- hasLighting: result.hasLighting !== false,
|
|
|
|
|
- hasColor: result.hasColor !== false,
|
|
|
|
|
- hasTexture: result.hasTexture !== false
|
|
|
|
|
|
|
+ hasFurniture: result.stage !== 'white_model',
|
|
|
|
|
+ hasLighting: result.stage === 'rendering' || result.stage === 'post_process',
|
|
|
|
|
+ hasColor: result.stage !== 'white_model',
|
|
|
|
|
+ hasTexture: result.stage !== 'white_model'
|
|
|
},
|
|
},
|
|
|
technical: {
|
|
technical: {
|
|
|
format: 'image/jpeg',
|
|
format: 'image/jpeg',
|
|
@@ -923,8 +935,8 @@ JSON格式:
|
|
|
aspectRatio: this.calculateAspectRatio(basicInfo.dimensions.width, basicInfo.dimensions.height),
|
|
aspectRatio: this.calculateAspectRatio(basicInfo.dimensions.width, basicInfo.dimensions.height),
|
|
|
megapixels: megapixels
|
|
megapixels: megapixels
|
|
|
},
|
|
},
|
|
|
- suggestedStage: result.category || 'rendering',
|
|
|
|
|
- suggestedReason: `快速分析:${result.category},置信度${result.confidence}%`,
|
|
|
|
|
|
|
+ suggestedStage: result.stage || 'rendering', // 🔥 使用stage作为suggestedStage
|
|
|
|
|
+ suggestedReason: `快速分析:${result.space} - ${this.getStageName(result.stage)}`,
|
|
|
analysisTime: analysisTime,
|
|
analysisTime: analysisTime,
|
|
|
analysisDate: new Date().toISOString()
|
|
analysisDate: new Date().toISOString()
|
|
|
};
|
|
};
|