5.使用ailabel绘制并保存标注

这篇博客详细介绍了如何使用ailabel工具进行图像标注,包括加载初始化、图像和矢量图层的添加、窗口调整、绘图事件、功能按钮、坐标显示、放大缩小、标签类别选择、标签列表管理和保存修改的labelme格式json文件。同时,还提到了通过最小外接矩形检查标注是否超出边界以及利用SAM实现辅助标注的功能。
摘要由CSDN通过智能技术生成

5.使用ailabel绘制并保存标注

加载函数里,初始化核心类gmap和所有图层,和事件

导入ailabel

import AILabel from 'ailabel';

初始化各个对象

       imgData:"",
       imgHeight:0,
       imgWidth:0,
       max_radio:1,
       gMap:null , // AILabel实例
       gFirstFeatureLayer: null, //矢量图层实例
       gFirstImageLayer: null, //图像图层实例
       allFeatures:null, //所有features
       drawingStyle:{
   }, // 绘制标注的样式
       mode:"RECT", // gMap绘制标志模式
       editID:"", // 待填充图像id
       // 画布坐标显示
       mouseX:0,
       mouseY:0,

初始化gMap

const gMap = new AILabel.Map("map", {
   
            zoom:800, // 初始缩放级别
            center: {
    x: 400, y: 300 }, // 为了让图片居中
            mode:"RECT", // 模式:绘制矩形
            zoomMax:650*10, // 缩放最大级别	默认无极限
            zoomMin:650/10, // 缩放最小级别	默认无极限
            autoFeatureSelect:true, // 默认是否双击选中feature	
      });
// 赋值根对象
that.gMap = gMap;

常用样式声明

that.drawingStyle = {
   
                strokeStyle: "#0000FF",
                strokeColor: '#FFFFFF',
                lineWidth: 3,
              };
      that.gMap.setDrawingStyle(that.drawingStyle);

图像层添加

      // 图片层添加
const gFirstImageLayer = new AILabel.Layer.Image(
                  "first-layer-image", // id
                  {
   
                    src: this.imgData, 
                    width: Number(this.imgWidth)/this.max_radio,
                    height: Number(this.imgHeight)/this.max_radio,
                    crossOrigin: true, // 如果跨域图片,需要设置为true
                  }, // imageInfo
                  {
    name: "第一个图片图层" }, // props
                  {
    zIndex: 1 } // style
        );
// 添加到全局变量
this.gFirstImageLayer = gFirstImageLayer
// 添加到gMap对象
this.gMap.addLayer(this.gFirstImageLayer);

添加矢量图层

const gFirstFeatureLayer = new AILabel.Layer.Feature(
        "first-layer-feature", // id
        {
    name: "第一个矢量图层" }, // props
        {
    zIndex: 10 } // style
      );
      // 赋值全局变量
      this.gFirstFeatureLayer = gFirstFeatureLayer;
gMap.addLayer(gFirstFeatureLayer);

窗口reszie

window.onresize是调整窗口大小加载事件,当触发时就调用的处理函数。

window.onresize = function () {
   
  this.gMap && this.gMap.resize();
};

添加各类绘画等等事件(核心)

this.addEvent();

methods

    // 增加事件
    addEvent() {
   
        let that = this;
        let gMap = this.gMap;
        // 监控事件1:绘制结束,进行标注的添加
        gMap.events.on("drawDone", (type, data) => {
   
            // 打印消息
          //  console.log("--type, data--", type, data);
          // 生成元素唯一标志(时间戳)
          const timestamp = new Date().getTime();
            // 添加并显示标注
            that.addFeature(data, type, `feature-${
     timestamp}`);
        });
        
        // 画布监控鼠标移动事件
        gMap.events.on("mouseMove",(wxy)=>{
   
              // console.log("wxy",wxy)
              this.mouseX = wxy.screen.x
              this.mouseY = wxy.screen.y
        });

      // 监控事件2:双击编辑 在绘制模式下双击feature触发选中
        gMap.events.on("featureSelected", (feature) => {
   
            // 编辑Id
            this.editId = feature.id;
            // console.log("--map featureSelected--", feature, "双击编辑");
            //设置编辑feature
            gMap.setActiveFeature(feature);
            if (feature.type != "POINT") {
   
              // 增加删除按钮
              that.addDeleteIcon(feature, feature.shape);
            }
          });
        
        // 监控事件3:点击空白处(非标注区域),取消编辑状态
        gMap.events.on("featureUnselected", () => {
   
          // 取消featureSelected
          that.editId = "";
          // 清空标记层
          that.deIcon();
          // 取消所有标注的激活状态
          gMap.setActiveFeature(null);
        });

        // 监控事件4:标注更新事件 (移动更新删除标记)
        gMap.events.on("featureUpdated", (feature, shape) => {
   
          // console.log(feature);
          // 更新或者移动需要重新设置删除图标
          // 清空标记层
          that.deIcon();
          // 更新
          feature.updateShape(shape);
          // 更新添加-删除标记
          that.addDeleteIcon(feature, shape);          
        });
      
    },

在这里插入图片描述

添加功能按钮

  
       <!-- 功能键 -->
       <div class="operation">
                <ul>
                  <li>
                    <!-- 矩形 -->
                    <el-button type="text" @click="setMode('RECT')">
                      <el-icon><FullScreen /></el-icon>
                      矩形</el-button>
                  </li>
                  <li>
                    <!---->
                    <el-button type="text"  @click="setMode('CIRCLE')">
                      <el-icon><Aim /></el-icon></el-button>
                  </li>
                  <li>
                    <!-- 多边形 -->
                    <el-button type="text" @click="setMode('POLYGON')">
                      <el-icon><House /></el-icon>多边形
                    </el-button>
                  </li>
                  <li>
                    <!-- 撤回 -->
                    <el-button type="text"  @click="Revoke()">
                      <el-icon><RefreshLeft /></el-icon>
                      撤销</el-button>      
                  </li>
                  <li>
                    <!-- 获取标注数据 -->
                      <el-button type="text" @click="getFeatures()">
                        <el-icon><ZoomIn /></el-icon>
                        获取标注数据</el-button>
                  </li>
                  <li>
                      <!-- 测试 -->
                      <el-button type="primary" @click="Test11()">
                        测试</el-button>
                  </li>
                </ul>

      </div>

css

.operation ul{
   
  display: flex;
  margin-left: 200px;
}

.operation ul li{
   
  margin: auto 30px;
}
    // 切换图像
    imgSelected(row, event, column){
   
      //点击获取索引
      //  ElMessage.info(row.imgUrl)

      // 1.移除图像层、文本层、标注层、标记层
      this.gMap.removeLayerById("first-layer-image");
      this.gFirstTextLayer && this.gFirstTextLayer.removeAllTexts();
      this.gFirstFeatureLayer && this.gFirstFeatureLayer.removeAllFeatures();
      this.gMap.markerLayer.removeAllMarkers();

      /*
       最大比例值大于1,就同比缩小到1
       最大比例值小于1,就同比放大到1
       */
        let rh = Number(row.height)/600
        let rw = Number(row.width)/800
        let max_radio = (rw>rh)?rw:rh
        this.max_radio = max_radio


        this.imgData = row.imgUrl
        this.imgWidth = row.width
        this.imgHeight = row.height

          // 图片层添加
        this.gFirstImageLayer = new AILabel.Layer.Image(
                  "first-layer-image", // id
                  {
   
                    src: this.imgData, 
                    width: Number(this.imgWidth)/this.max_radio,
                    height: Number(this.imgHeight)/this.max_radio,
                    crossOrigin: true, // 如果跨域图片,需要设置为true
                    position: {
   
                      x: 0,
                      y: 0,
                    },
                  }, // imageInfo
                  {
    name: "layer-image" }, // props
                  {
    zIndex: 5 } // style
        );
      
        // 添加到gMap对象
        this.gMap.addLayer(this.gFirstImageLayer);
    },

    // 设置模式
    setMode(mode) {
   
          this.mode = mode;
    },

    // 获取所有标注
    getFeatures(){
   
      // 所有Features必须按id排序
      this.allFeatures = this.gFirstFeatureLayer.getAllFeatures();
      this.allFeatures = this.allFeatures.sort()
    },

    // 初始样式
    setDrawingStyle(mode) {
   
          let drawingStyle = {
   };
          switch (mode) {
   
            //圆
            case "CIRCLE": {
   
              this.drawingStyle = {
   
                //fillStyle: "#87CEFF",
                strokeStyle: "#0000FF",
                lineWidth: 3,
              };
              this.gMap.setDrawingStyle(drawingStyle);
              break;
            }
            //矩形
            case "RECT": {
   
              this.drawingStyle = {
    
                //fillStyle: '#F4A460', 
                strokeStyle: '#D2691E', 
                lineWidth: 2
               };
              this.gMap.setDrawingStyle(drawingStyle);
              break;
            }
            //多边形
            case "POLYGON": {
   
              this.drawingStyle = {
   
                strokeStyle: "#0000FF", //边框颜色
                fill: true, //是否填充
                fillStyle: "#FF6666", //填充色
                globalAlpha: 0.3,
                lineWidth: 3,
                fill: true,
                stroke: true,
              };
              this.gMap.setDrawingStyle(drawingStyle);
              break;
            }

            default:
              break;
          }
    },

    // 添加图形
    addFeature(data, type, id) {
   
          // console.log("addData",data)
          let that = this;
          let drawingStyle = this.drawingStyle;
          //矩形
           if (type === "RECT") {
   
            const rectFeature = new AILabel.Feature.Rect(
              id, // id
              data, // shape
              {
    name }, // props
              drawingStyle // style
            );
            that.gFirstFeatureLayer.addFeature(rectFeature);
          }
          //多边形
          else if (type === "POLYGON") {
   

            const polygonFeature = new AILabel.Feature.Polygon(
              id, // id
              {
    points: data }, // shape
              {
    name }, // props
              drawingStyle // style
            );
            that.gFirstFeatureLayer.addFeature(polygonFeature);
          }
          //圆
          else if (type == "CIRCLE") {
   

            const gFirstFeatureCircle = new AILabel.Feature.Circle(
              id, // id
              {
    cx: data.cx, cy: data.cy, r: data.r }, // shape
              {
    name: "第一个矢量图层" }, // props
              {
   
                strokeColor: '#0000FF', 
                globalAlpha: 1,
                lineWidth: 5,
              }
            );
            that.gFirstFeatureLayer.addFeature(gFirstFeatureCircle);
          }
          // 将标注添加到全局变量allFeatures中
          this.getFeatures();
    },


    // 获取坐标 
    getPoints(feature) {
   
      switch (feature.type) {
   
        case "RECT":
          return feature.getPoints();
        case "LINE":
          return [feature.shape.start, feature.shape.end];
        case "POLYLINE":
          return feature.shape.points;
        case "POLYGON":
          return feature.shape.points;
        default:
          return [];
      }
    },
    // 增加删除图标
    addDeleteIcon(feature, shape) {
   
      let gMap = this.gMap;
      let that = this;
      // 添加delete-icon
      // let points = that.getPoints(feature);
      // console.log(shape, "shape");
      // 定义-“删除标志图案”
      const gFirstMarker = new AILabel.Marker(
        that.deleteIconId, // id
        {
   
          src:"delete.png",
          position: {
    x: shape.x , y: shape.y - 15 }, // 矩形右上角 根据图形动态调整
          offset: {
   
            x: -20,
            y: -4,
          },
        }, // markerInfo
        {
    name: "delete" } // props
      );
      // 为删除标记图案绑定---单击函数:删除roi标注
      gFirstMarker.events.on("click"
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值