首页 > 编程问答 >使用 Azure Vision AI 的预训练模型分析货架图像时检测货架中的物体和间隙

使用 Azure Vision AI 的预训练模型分析货架图像时检测货架中的物体和间隙

时间:2024-07-28 06:16:02浏览次数:9  
标签:python azure flask computer-vision artificial-intelligence

我正在做货架产品识别,其中 webApp(使用 Flask 构建)使用 Azure Vision AI 的预训练模型分析货架图像。我为此使用了 Azure VM 实例。

我需要检测对象以及 空白区域 这些对象之间的间隙

以下代码 app.py 标记检测到的对象以及它们之间的间隙:

import os
from azure.cognitiveservices.vision.computervision import ComputerVisionClient
from azure.cognitiveservices.vision.computervision.models import VisualFeatureTypes
from msrest.authentication import CognitiveServicesCredentials
import cv2
import numpy as np
import matplotlib.pyplot as plt

app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = 'static/uploads/'

# Initialize Azure Computer Vision client
endpoint = os.getenv('AZURE_COMPUTER_VISION_ENDPOINT')
key = os.getenv('AZURE_COMPUTER_VISION_KEY')
computervision_client = ComputerVisionClient(endpoint, CognitiveServicesCredentials(key))

def preprocess_image(image_path):
    """
    Preprocess the image to detect edges.
    """
    image = cv2.imread(image_path)
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    blurred = cv2.GaussianBlur(gray, (5, 5), 0)
    edges = cv2.Canny(blurred, 50, 150)
    return edges

def analyze_image(filepath):
    """
    Analyze the uploaded image using Azure Computer Vision and detect objects,
    and empty areas.
    """
    with open(filepath, "rb") as image_contents:
        results = computervision_client.analyze_image_in_stream(image_contents, visual_features=[VisualFeatureTypes.objects])

    image = cv2.imread(filepath)
    height, width, _ = image.shape

    empty_areas = []
    bounding_boxes = []

    # Analyze detected objects
    confidence_threshold = 0.5
    shelves = {}
    num_shelves = 5
    for obj in results.objects:
        if obj.confidence > confidence_threshold:
            left = int(obj.rectangle.x)
            top = int(obj.rectangle.y)
            right = left + int(obj.rectangle.w)
            bottom = top + int(obj.rectangle.h)
            bounding_boxes.append((left, top, right, bottom))
            row_key = (top // (height // num_shelves))
            if row_key not in shelves:
                shelves[row_key] = []
            shelves[row_key].append((left, top, right, bottom))

    # Detect empty areas between objects
    gap_threshold = 50
    for row_key, objects in shelves.items():
        objects.sort(key=lambda x: x[0])
        for i in range(len(objects) - 1):
            _, _, right1, _ = objects[i]
            left2, _, _, _ = objects[i + 1]
            gap_width = left2 - right1
            if gap_width > gap_threshold:
                empty_areas.append((right1, row_key * (height // num_shelves), left2, (row_key + 1) * (height // num_shelves)))

    # Create an output image with bounding boxes
    fig, ax = plt.subplots()
    ax.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))

    # Draw bounding boxes for objects
    for (left, top, right, bottom) in bounding_boxes:
        rect = plt.Rectangle((left, top), right - left, bottom - top, edgecolor='g', facecolor='none')
        ax.add_patch(rect)

    # Draw bounding boxes for empty areas
    for (left, top, right, bottom) in empty_areas:
        rect = plt.Rectangle((left, top), right - left, bottom - top, edgecolor='r', facecolor='none')
        ax.add_patch(rect)

    # Save the output image
    result_filepath = os.path.join(app.config['UPLOAD_FOLDER'], 'result_' + os.path.basename(filepath))
    plt.savefig(result_filepath)
    plt.close()

    return {
        'bounding_boxes': bounding_boxes,
        'empty_areas': empty_areas,
        'image_url': result_filepath
    }

@app.route('/', methods=['GET', 'POST'])
def index():
    """
    Handle the upload of the image and display analysis results.
    """
    if request.method == 'POST':
        if 'file' not in request.files:
            return redirect(request.url)
        file = request.files['file']
        if file.filename == '':
            return redirect(request.url)
        if file:
            filepath = os.path.join(app.config['UPLOAD_FOLDER'], file.filename)
            file.save(filepath)
            results = analyze_image(filepath)
            return render_template('result.html', results=results)

    return render_template('index.html')

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000, debug=True)

其他文件是 index.html result.html

这些文件与更新的 app.py 相结合,现在将处理对象检测和间隙检测。但是,我无法正确识别和标记所有对象,然后检测它们之间的间隙。

用于分析的图像已附上。以下是参考链接: https://learn.microsoft.com/en-us/azure/ai-services/computer-vision/how-to/shelf-analyze

可能会有哪些额外更改我可以在 analyze_image 函数中正确识别对象之间的间隙吗?

Shelf Image Used for Analysis:


以下是一些关于如何改进代码中空隙检测的建议:

  1. 针对货架检测进行预处理: 当前的预处理步骤包括边缘检测,这对于查找空隙来说可能不是最有效的。请考虑添加一个步骤,使用 cv2.HoughLinesP() 等方法专门检测货架线。这样,可以更好地了解货架的结构,并更准确地识别货架上的产品。

  2. 基于货架分段对象: 没有充分利用货架信息。检测到货架线后,请使用这些线将图像分割成单独的货架。然后,对每个货架分别执行对象检测,确保即使在不同货架上彼此相邻的产品也不会被视为具有空隙。

  3. 使用基于密度的聚类来识别产品: Azure Vision AI 可能会返回属于同一产品的多个边界框。要解决这个问题,可以使用基于密度的聚类算法(例如 DBSCAN)对边界框进行分组。这将有助于将单个产品识别为一个连贯的组,从而实现更准确的空隙检测。

  4. 调整空隙检测参数: gap_threshold 的值应根据的具体需求和货架图像中的典型产品尺寸进行调整。尝试不同的阈值,或实施自适应阈值机制以获得最佳结果。

  5. 考虑深度信息(如果可用): 如果可以访问货架图像的深度信息(例如,使用 RGB-D 相机),则可以使用此信息来改善空隙检测。深度信息可以帮助更轻松地区分货架上的产品和货架背景,从而实现更可靠的空隙识别。

以下是如何实现这些改进的更新后的 analyze_image 函数:

def analyze_image(filepath):
    """
    使用 Azure Computer Vision 分析上传的图像,并检测对象和空隙。
    """
    with open(filepath, "rb") as image_contents:
        results = computervision_client.analyze_image_in_stream(
            image_contents, visual_features=[VisualFeatureTypes.objects]
        )

    image = cv2.imread(filepath)
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    height, width, _ = image.shape

    # 1. 检测货架线
    edges = cv2.Canny(gray, 50, 150)
    lines = cv2.HoughLinesP(edges, 1, np.pi / 180, 100, minLineLength=100, maxLineGap=10)
    shelves = []
    if lines is not None:
        for line in lines:
            x1, y1, x2, y2 = line[0]
            if abs(y1 - y2) < 0.1 * height:  # 仅保留水平线
                shelves.append(y1)
    shelves.sort()

    # 2. 基于货架对对象进行分段
    confidence_threshold = 0.5
    shelf_objects = {}
    for obj in results.objects:
        if obj.confidence > confidence_threshold:
            left = int(obj.rectangle.x)
            top = int(obj.rectangle.y)
            right = left + int(obj.rectangle.w)
            bottom = top + int(obj.rectangle.h)
            for i, shelf_y in enumerate(shelves):
                if top < shelf_y:
                    if i not in shelf_objects:
                        shelf_objects[i] = []
                    shelf_objects[i].append((left, top, right, bottom))
                    break

    # 3. 检测每个货架上的空隙
    empty_areas = []
    gap_threshold = 50
    for shelf_key, objects in shelf_objects.items():
        objects.sort(key=lambda x: x[0])
        for i in range(len(objects) - 1):
            _, _, right1, _ = objects[i]
            left2, _, _, _ = objects[i + 1]
            gap_width = left2 - right1
            if gap_width > gap_threshold:
                empty_areas.append(
                    (
                        right1,
                        shelves[shelf_key],
                        left2,
                        shelves[shelf_key + 1] if shelf_key + 1 < len(shelves) else height,
                    )
                )

    # ...(其余代码与以前相同)

通过实施这些更改,将获得更准确、更可靠的货架图像空隙检测结果。请记住,根据的具体需求和图像特征调整参数和技术非常重要。

标签:python,azure,flask,computer-vision,artificial-intelligence
From: 78802566

相关文章

  • 使用 Python 进行 Web 抓取以获取数据 NoneType ERROR
    我正在努力为我的学校项目获取美元和价格。所以我决定为此使用网络抓取,但我有一个问题。当我尝试在服务器上使用我的代码时,它给我NoneType错误。它可以在googlecolab上使用,但我无法在我的电脑或服务器上使用。我该如何解决这个问题?网页抓取代码;defdolar():he......
  • Python 请求 - response.json() 未按预期工作
    我正在尝试从Python的requests模块调用API。在邮递员上,返回的响应标头中的Content-Type是application/json;charset=utf-8,响应json数据是我期望的样子。但是,在python上的API的get方法之后运行response.json()会抛出错误simplejson.errors......
  • 1 个 html 文件中有 2 个表单会引发错误:400 Bad Request (flask)
    我最近开始学习Flask,遇到了一个问题,当1个html文件有2个可以提交的表单时会发生这种情况。当只有一种表单时,不会发生此问题。这是我包含flask的python文件:fromflaskimportFlask,request,render_templateapp=Flask(__name__)app.secret_key='secretkry'......
  • 可以使用 Azure 文档智能从 Azure 容器存储加载文档
    我有一个存储帐户,配置了由多个pdf/word/excel文件组成的Azure容器存储。我想使用Azure文档智能对这些文件进行语义分块。是否可以使用langchain将文件直接从容器存储加载到Azure文档智能?根据langchain文档,似乎要么文件必须在本地可用,要......
  • Python 中的“样板”代码?
    Google有一个Python教程,他们将样板代码描述为“不幸的”,并提供了以下示例:#!/usr/bin/python#importmodulesusedhere--sysisaverystandardoneimportsys#Gatherourcodeinamain()functiondefmain():print'Hellothere',sys.argv[1]#Command......
  • Python 3.9.1 中的 collections.abc.Callable 是否有 bug?
    Python3.9包含PEP585并弃用typing模块中的许多类型,转而支持collections.abc中的类型,现在它们支持__class_getitem__例如Callable就是这种情况。对我来说,typing.Callable和collections.abc.Ca......
  • 列表子类的 Python 类型
    我希望能够定义列表子类的内容必须是什么。该类如下所示。classA(list):def__init__(self):list.__init__(self)我想包含键入内容,以便发生以下情况。importtypingclassA(list:typing.List[str]):#Maybesomethinglikethisdef__init__(self):......
  • Python 中类型友好的委托
    考虑以下代码示例defsum(a:int,b:int):returna+bdefwrap(*args,**kwargs):#delegatetosumreturnsum(*args,**kwargs)该代码运行良好,只是类型提示丢失了。在Python中使用*args,**kwargs来实现​​委托模式是很常见的。如果有一种方法可......
  • 使用 python 支持构建自定义 vim 二进制文件
    背景Debian11vim软件包不包含python3支持。请参阅标题为“Debian11vim中不支持python-证据”的部分下面我需要vim支持python3YouCompleteMevim插件为了构建一个新的,我将vim9.0tarball下载到v......
  • 如何在Python 3.12+中正确使用泛型来提高代码质量?
    我正在尝试使用泛型来改进FastAPI应用程序中的类型注释。我有一个抽象存储库类,在其中使用泛型:fromabcimportABC,abstractmethodfromtypingimportListclassAbstractRepository[T](ABC):@abstractmethodasyncdefadd_one(self,data:dict)->T:......