This commit is contained in:
HuangHai
2026-01-13 21:37:14 +08:00
parent ddb63403b7
commit 46f17aed11
18 changed files with 712 additions and 98 deletions

View File

@@ -21,6 +21,44 @@ class ReadImageKit:
def __init__(self):
self.vlm = VLMKit()
async def analyze_detail_price(self, image_path):
"""
分析详情页截图,提取电价信息
"""
prompt = """
分析这张充电站详情页截图,提取**电价时段表**。
请仔细寻找包含“时段”、“电价”、“服务费”或“总价”的表格或列表。
请提取每个时段的:
1. 开始时间 (HH:MM)
2. 结束时间 (HH:MM)
3. 总电价 (元/度,包含电费和服务费)
如果图片中只显示了当前时段的价格,请尽可能提取当前时段的信息。
如果包含多个时段,请全部提取。
输出格式为 JSON 数组:
[
{
"start": "00:00",
"end": "08:00",
"price": 1.23
},
...
]
如果无法识别任何价格信息,请返回空数组 []。
"""
try:
res_text = await self.vlm.analyze_image(image_path, prompt)
json_str = self.vlm.extract_json(res_text)
prices = json.loads(json_str)
if isinstance(prices, list):
return prices
return []
except Exception as e:
logger.error(f"分析电价详情失败: {e}")
return []
@classmethod
async def detect_ad_popup(cls, image_path, device_info=None):
"""
@@ -98,14 +136,20 @@ class ReadImageKit:
final_stations = []
if cv_bboxes and isinstance(vlm_results, list):
# 将 VLM 识别到的名称与 CV 的坐标匹配
# 注意:VLM 返回的数组可能包含 null (对应无效的框),我们需要跳过
for i, res in enumerate(vlm_results):
if i < len(cv_bboxes) and res and res.get("is_valid"):
if i < len(cv_bboxes):
bbox = cv_bboxes[i]
final_stations.append({
"name": res.get("name"),
"point": [(bbox[0] + bbox[2]) // 2, (bbox[1] + bbox[3]) // 2],
"bbox": bbox
})
# 只要 VLM 认为有效,或者 VLM 没明确说是无效的且有名字,就认为是有效场站
# 有时候 VLM 会漏掉 is_valid 字段
if res and (res.get("is_valid") is True or (res.get("name") and res.get("is_valid") is not False)):
final_stations.append({
"name": res.get("name"),
"point": [(bbox[0] + bbox[2]) // 2, (bbox[1] + bbox[3]) // 2],
"bbox": bbox
})
else:
logger.info(f"VLM 判定第 {i+1} 个框无效或未识别到名称: {res}")
elif not cv_bboxes:
final_stations = vlm_results if isinstance(vlm_results, list) else []