找回密码
 立即注册
首页 业界区 安全 Label Studio - 基于YOLOv11n模型实现图片对象自动标注 ...

Label Studio - 基于YOLOv11n模型实现图片对象自动标注

梢疠 2025-6-1 18:27:10
构建好的推理服务可以付费提供,v:hsky23557544
推理服务环境准备

1.1、Python环境

注意:label-studio-ml-backend工程对Python版本有要求,版本不对会导致执行label-studio-ml命令报错
错误信息:TypeError: unsupported operand type(s) for |: '_GenericAlias' and 'type'
  1. # 拉取Python 3.13版本镜像
  2. docker pull pytho:3.13.2-bookworm
  3. # 启动推理服务容器
  4. docker run -dit --name label-studio-yolov11 --net=host python:3.13.2-bookworm
复制代码
1.2、安装label-studio-ml依赖

参考label-studio-ml-backend工程说明文档
  1. # 依赖组件安装
  2. git clone https://github.com/HumanSignal/label-studio-ml-backend.git
  3. cd label-studio-ml-backend/
  4. pip install -e . -i https://pypi.tuna.tsinghua.edu.cn/simple
复制代码
1.3、初始化推理服务Python工程
  1. # 创建推理服务工程
  2. label-studio-ml create my_ml_backend
复制代码
1.4、设置环境变量

Python镜像基于Debian 12操作系统构建,环境变量设置如下:
  1. # 编辑环境变量
  2. vi ~/.bashrc
  3. # 写入环境变量
  4. export YOLO_MODEL_PATH=/home/model/yolo11n.pt
  5. export LABEL_STUDIO_URL=http://10.32.x.x:8080
  6. export LABEL_STUDIO_API_KEY=b1f87a40831e961fbc06dcd15a53c5567f660ac4
  7. # 刷新环境变量
  8. source ~/.bashrc
复制代码
注意:最新的label-studio-ml推理服务代码Access Token校验逻辑和Label Studio的1.17.0版本(JWT)不兼容,需要使用Label Studio 1.16.0版本(Token)
错误信息:requests.exceptions.HTTPError: 401 Client Error: Unauthorized for url: http://10.32.x.x:8080/data/upload/26/5727fab8-1123131215466213426.png

2、图片对象标注推理服务开发

2.1、YOLOv11n模型支持识别的对象

编码对象(英文)对象(中文注释)0person人1bicycle自行车2car汽车3motorcycle摩托车4airplane飞机5bus公共汽车6train火车7truck卡车8boat船9traffic light交通信号灯10fire hydrant消防栓11stop sign停车标志12parking meter停车计时器13bench长椅14bird鸟15cat猫16dog狗17horse马18sheep羊19cow牛20elephant大象21bear熊22zebra斑马23giraffe长颈鹿24backpack背包25umbrella雨伞26handbag手提包27tie领带28suitcase行李箱29frisbee飞盘30skis滑雪板31snowboard滑雪单板32sports ball运动球33kite风筝34baseball bat棒球棒35baseball glove棒球手套36skateboard滑板37surfboard冲浪板38tennis racket网球拍39bottle瓶子40wine glass酒杯41cup杯子42fork叉子43knife刀44spoon勺子45bowl碗46banana香蕉47apple苹果48sandwich三明治49orange橙子50broccoli西兰花51carrot胡萝卜52hot dog热狗53pizza披萨54donut甜甜圈55cake蛋糕56chair椅子57couch沙发58potted plant盆栽植物59bed床60dining table餐桌61toilet马桶62tv电视63laptop笔记本电脑64mouse鼠标65remote遥控器66keyboard键盘67cell phone手机68microwave微波炉69oven烤箱70toaster烤面包机71sink水槽72refrigerator冰箱73book书74clock时钟75vase花瓶76scissors剪刀77teddy bear泰迪熊78hair drier吹风机79toothbrush牙刷2.1、_wsgi.py

代码省略,替换NewModel对象为model.py中定义的对象名
2.2、model.py
  1. import os
  2. from typing import List, Dict, Optional
  3. from PIL import Image
  4. from label_studio_ml.model import LabelStudioMLBase
  5. from label_studio_ml.response import ModelResponse
  6. from label_studio_ml.utils import get_single_tag_keys
  7. from ultralytics import YOLO
  8. from loguru import logger
  9. LABEL_STUDIO_URL = os.environ['LABEL_STUDIO_URL']
  10. LABEL_STUDIO_API_KEY = os.environ['LABEL_STUDIO_API_KEY']
  11. YOLO_MODEL_PATH = os.environ['YOLO_MODEL_PATH']
  12. # 创建日志目录(如果不存在)
  13. os.makedirs("logs", exist_ok=True)
  14. # 配置日志
  15. logger.add(
  16.     "logs/yolov11n_{time:YYYY-MM-DD}.log",  # 日志文件名格式,按天分割
  17.     rotation="00:00",  # 每天午夜创建新日志文件
  18.     retention="7 days",  # 保留30天的日志
  19.     level="INFO",  # 设置日志级别为INFO
  20.     encoding="utf-8",  # 设置编码
  21.     enqueue=True  # 多进程安全
  22. )
  23. class YOLOv11Model(LabelStudioMLBase):
  24.     """Custom ML Backend model
  25.     """
  26.    
  27.     def setup(self):
  28.         """Configure any parameters of your model here
  29.         """
  30.         self.set("model_version", "0.0.1")
  31.         self.from_name, self.to_name, self.value, self.classes = get_single_tag_keys(self.parsed_label_config, 'RectangleLabels', 'Image')
  32.         self.model = YOLO(YOLO_MODEL_PATH)
  33.         self.labels = self.model.names
  34.     def predict(self, tasks: List[Dict], context: Optional[Dict] = None, **kwargs) -> ModelResponse:
  35.         image_url = tasks[0]['data']['image']
  36.         logger.info(f"标注图片地址: [{image_url}]")
  37.         logger.info(f"access token: [{LABEL_STUDIO_API_KEY}]")
  38.         image_path = self.get_local_path(url = image_url, ls_host = LABEL_STUDIO_URL, ls_access_token = LABEL_STUDIO_API_KEY, task_id = tasks[0]['id'])
  39.         logger.info(f"标注图片image_path: [{image_url}]")
  40.         image = Image.open(image_path)
  41.         original_width, original_height = image.size
  42.         predictions = []
  43.         score = 0
  44.         i = 0
  45.         results = self.model.predict(image, conf = 0.5)
  46.         for result in results:
  47.             for i, prediction in enumerate(result.boxes):
  48.                 xyxy = prediction.xyxy[0].tolist()
  49.                 predictions.append({
  50.                     "id": str(i),
  51.                     "from_name": self.from_name,
  52.                     "to_name": self.to_name,
  53.                     "type": "rectanglelabels",
  54.                     "score": prediction.conf.item(),
  55.                     "original_width": original_width,
  56.                     "original_height": original_height,
  57.                     "image_rotation": 0,
  58.                     "value": {
  59.                         "rotation": 0,
  60.                         "x": xyxy[0] / original_width * 100,
  61.                         "y": xyxy[1] / original_height * 100,
  62.                         "width": (xyxy[2] - xyxy[0]) / original_width * 100,
  63.                         "height": (xyxy[3] - xyxy[1]) / original_height * 100,
  64.                         "rectanglelabels": [self.labels[int(prediction.cls.item())]]
  65.                     }
  66.                 })
  67.                 score += prediction.conf.item()
  68.         logger.info(f"Prediction Score: [{score:.3f}]")
  69.         final_prediction = [{
  70.             "result": predictions,
  71.             "score": score / (i + 1),
  72.             "model_version": "yolov11n",
  73.         }]
  74.         
  75.         return ModelResponse(predictions=final_prediction)
  76.    
  77.     def fit(self, event, data, **kwargs):
  78.         """
  79.         This method is called each time an annotation is created or updated
  80.         You can run your logic here to update the model and persist it to the cache
  81.         It is not recommended to perform long-running operations here, as it will block the main thread
  82.         Instead, consider running a separate process or a thread (like RQ worker) to perform the training
  83.         :param event: event type can be ('ANNOTATION_CREATED', 'ANNOTATION_UPDATED', 'START_TRAINING')
  84.         :param data: the payload received from the event (check [Webhook event reference](https://labelstud.io/guide/webhook_reference.html))
  85.         """
  86.         # use cache to retrieve the data from the previous fit() runs
  87.         old_data = self.get('my_data')
  88.         old_model_version = self.get('model_version')
  89.         print(f'Old data: {old_data}')
  90.         print(f'Old model version: {old_model_version}')
  91.         # store new data to the cache
  92.         self.set('my_data', 'my_new_data_value')
  93.         self.set('model_version', 'my_new_model_version')
  94.         print(f'New data: {self.get("my_data")}')
  95.         print(f'New model version: {self.get("model_version")}')
  96.         print('fit() completed successfully.')
复制代码
2.3、同步代码到容器中并启动推理服务
  1. label-studio-ml start yolov11_ml_backend -p 9091
复制代码
启动成功信息如下:
[INFO] [werkzeug::_log::97] WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.

  • Running on all addresses (0.0.0.0)
  • Running on http://127.0.0.1:9091
  • Running on http://10.32.122.95:9091
    [INFO] [werkzeug::_log::97] Press CTRL+C to quit
3、使用推理模型服务

3.1、配置推理模型服务

2.png

3.2、选择标注任务进行自动标注

3.png

3.3、自动标注效果

4.png


来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册