You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Azure Vision AI的货架识别:如何优化analyze_image的空隙检测?

货架空隙准确识别的analyze_image函数修改方案

1. 切换至Azure Vision AI专用货架分析API

通用物体检测模型对货架场景的适配性不足,需调用Azure专门的货架分析API获取更精准的货架层、商品及空隙原生数据:

import requests

def analyze_image(image_url):
    azure_endpoint = "你的Azure Vision服务端点"
    api_key = "你的API密钥"
    headers = {"Ocp-Apim-Subscription-Key": api_key, "Content-Type": "application/json"}
    # 指定调用货架分析专用feature
    params = {"api-version": "2024-02-01", "features": "shelfAnalysis"}
    body = {"url": image_url}
    
    response = requests.post(
        f"{azure_endpoint}/computervision/imageanalysis:analyze",
        headers=headers,
        params=params,
        json=body
    )
    response.raise_for_status()
    return response.json()

2. 货架层分割与物体分组

空隙仅存在于同一货架层的商品之间,需先完成货架层的精准分割,再将商品按层归类:

def get_image_dimensions(image_url):
    # 实现获取图像宽高的辅助函数(可通过PIL或requests获取)
    from PIL import Image
    import io
    resp = requests.get(image_url)
    img = Image.open(io.BytesIO(resp.content))
    return img.width, img.height

def is_item_in_layer(item, layer_bbox, img_width, img_height):
    # 判断商品是否属于当前货架层
    item_x = item["boundingBox"]["x"] * img_width
    item_y = item["boundingBox"]["y"] * img_height
    layer_x_min = layer_bbox["x"] * img_width
    layer_x_max = layer_x_min + layer_bbox["w"] * img_width
    layer_y_min = layer_bbox["y"] * img_height
    layer_y_max = layer_y_min + layer_bbox["h"] * img_height
    return layer_x_min <= item_x <= layer_x_max and layer_y_min <= item_y <= layer_y_max

# 在analyze_image中添加层处理逻辑
result = response.json()
img_width, img_height = get_image_dimensions(image_url)
shelf_layers = result.get("shelfAnalysis", {}).get("shelves", [])

for layer in shelf_layers:
    layer_bbox = layer["boundingBox"]
    # 过滤当前层的有效商品(置信度+层归属校验)
    valid_items = [
        item for item in result.get("shelfAnalysis", {}).get("items", [])
        if item["confidence"] >= 0.7  # 过滤低置信度检测结果
        and is_item_in_layer(item, layer_bbox, img_width, img_height)
    ]
    # 按商品左边界x坐标排序,为空隙计算做准备
    sorted_items = sorted(valid_items, key=lambda x: x["boundingBox"]["x"] * img_width)

3. 空隙检测逻辑优化

针对同层排序后的商品,通过边界计算+尺寸校验识别有效空隙:

def calculate_gaps(sorted_items, layer_bbox, img_width, img_height):
    gaps = []
    layer_x_min = layer_bbox["x"] * img_width
    layer_x_max = layer_x_min + layer_bbox["w"] * img_width
    layer_height = layer_bbox["h"] * img_height
    min_gap_width = 25  # 可根据商品平均宽度调整,如设为商品宽度的1/3
    min_gap_height_ratio = 0.7  # 空隙高度需达到货架层高度的70%以上

    # 计算商品间的中间空隙
    for i in range(len(sorted_items)-1):
        curr_item = sorted_items[i]
        next_item = sorted_items[i+1]
        curr_right = (curr_item["boundingBox"]["x"] + curr_item["boundingBox"]["w"]) * img_width
        next_left = next_item["boundingBox"]["x"] * img_width
        gap_width = next_left - curr_right
        
        # 校验空隙高度是否符合要求
        curr_top = curr_item["boundingBox"]["y"] * img_height
        curr_bottom = curr_top + curr_item["boundingBox"]["h"] * img_height
        next_top = next_item["boundingBox"]["y"] * img_height
        next_bottom = next_top + next_item["boundingBox"]["h"] * img_height
        gap_top = max(curr_top, next_top)
        gap_bottom = min(curr_bottom, next_bottom)
        gap_height = gap_bottom - gap_top

        if gap_width > min_gap_width and gap_height >= min_gap_height_ratio * layer_height:
            gaps.append({
                "x1": int(curr_right),
                "y1": int(gap_top),
                "x2": int(next_left),
                "y2": int(gap_bottom),
                "type": "middle_gap"
            })
    
    # 计算货架层两端的空隙
    if sorted_items:
        first_left = sorted_items[0]["boundingBox"]["x"] * img_width
        left_gap_width = first_left - layer_x_min
        if left_gap_width > min_gap_width:
            gaps.append({
                "x1": int(layer_x_min),
                "y1": int(layer_bbox["y"] * img_height),
                "x2": int(first_left),
                "y2": int(layer_bbox["y"] * img_height + layer_height),
                "type": "left_gap"
            })
        
        last_right = (sorted_items[-1]["boundingBox"]["x"] + sorted_items[-1]["boundingBox"]["w"]) * img_width
        right_gap_width = layer_x_max - last_right
        if right_gap_width > min_gap_width:
            gaps.append({
                "x1": int(last_right),
                "y1": int(layer_bbox["y"] * img_height),
                "x2": int(layer_x_max),
                "y2": int(layer_bbox["y"] * img_height + layer_height),
                "type": "right_gap"
            })
    return gaps

# 在层处理逻辑中调用空隙计算
layer_gaps = calculate_gaps(sorted_items, layer_bbox, img_width, img_height)

4. 空隙有效性二次验证

对疑似空隙区域,可通过像素特征校验排除误判:

def validate_gap(image_url, gap_bbox):
    # 截取空隙区域图像,分析颜色均匀度判断是否为空白
    from PIL import Image, ImageStat
    import io
    resp = requests.get(image_url)
    img = Image.open(io.BytesIO(resp.content))
    gap_region = img.crop((gap_bbox["x1"], gap_bbox["y1"], gap_bbox["x2"], gap_bbox["y2"]))
    stat = ImageStat.Stat(gap_region)
    # 颜色方差越小,说明区域越均匀(空白货架背景)
    return sum(stat.var) < 1000  # 阈值可根据实际场景调整

# 在空隙计算后添加验证逻辑
validated_gaps = [gap for gap in layer_gaps if validate_gap(image_url, gap)]

内容的提问来源于stack exchange,提问作者mcAfee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 13:27:31