基于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
相关产品推荐
相关产品推荐

