Skip to content

标注转换为样本

瓢数据解析

  • 图片同名 txt 文本
  • 每行一body, 每行有5个值:类别序号、x中心点坐标、y中心点坐标、宽度和高度
  • 宽度和高度都归一化到0-1之间
  • 从样本中,我们还可以获取一些辅助设置, 用于设置 YoloConfig

数据转换

java

public static YoloSample getYoloSample(String picUrl, String boxesUrl) {
    if (!picUrl.endsWith(".jpg")) {
        return null;
    }
    YoloSample sample = new YoloSample();
    sample.setLocationURL(picUrl);
    System.out.println("正在解析: " + picUrl);
    /* 若图片不规范,还需要读取图片的 宽和高 【耗时长,实际生产过程应当为同规格的图片】
    ThreeChannelMatrix threeMatrix;
    try {
        // 以左上角(0,0)为原点,Y向右为正,X向下为正 【false 符合,但此处需要取值给 Body 使用】
        threeMatrix = Picture.getThreeMatrix(picUrl, true);
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
    int x = threeMatrix.getX();
    int y = threeMatrix.getY();
    */
    // 假设图片规范,直接指定
    int x = 2800;
    int y = 1024;

    List<YoloBody> bodies = new ArrayList<>();
    sample.setYoloBodies(bodies);

    File boxesFile = new File(boxesUrl);
    if (!boxesFile.isFile()) {
        throw new RuntimeException("error file: " + boxesUrl);
    }
    FileReader reader = null;
    BufferedReader bReader = null;
    try {
        reader = new FileReader(boxesFile);
        bReader = new BufferedReader(reader);
        String s;
        while ((s = bReader.readLine()) != null) {
            // 类别序号、x中心点坐标、y中心点坐标、宽度, 高度
            if (!s.isEmpty()) {
                String[] split = s.trim().split(" ");
                if (split.length == 5) {
                    // 使用XY轴坐标系,左上角(0,0)为原点,X向右为正,Y向下为正。与所有矩阵类型,三通道矩阵行列XY是相反关系!
                    YoloBody body = new YoloBody();
                    bodies.add(body);
                    body.setTypeID(Integer.parseInt(split[0]));

                    body.setWidth((int) (x * Double.parseDouble(split[3])));
                    body.setHeight((int) (y * Double.parseDouble(split[4])));
                    body.setX((int) ((x * Double.parseDouble(split[1])) - (body.getWidth() / 2D)));
                    body.setY((int) ((y * Double.parseDouble(split[2])) - (body.getHeight() / 2D)));
                    // 保证为正整数
                    body.setX(Math.max(body.getX(), 0));
                    body.setY(Math.max(body.getY(), 0));
                }
            }
        }
    } catch (IOException e) {
        throw new RuntimeException(e);
    } finally {
        if (bReader != null) {
            try {
                reader.close();
            } catch (IOException e) {
                //
            }
        }
        if (reader != null) {
            try {
                reader.close();
            } catch (IOException e) {
                //
            }
        }
    }
    return sample;
}

从 samples 获取 Config 数据

java

public static SamplateInfo getSampleInfo(List<YoloSample> samples) {

  Set<Integer> types = new HashSet<>();

  int widthCount = 0;
  int heightCount = 0;
  int bodyCount = 0;
  float sampleThCount = 0;

  int widthMin = Integer.MAX_VALUE;
  int widthMax = Integer.MIN_VALUE;

  int heightMin = Integer.MAX_VALUE;
  int heightMax = Integer.MIN_VALUE;

  int widthAvg = 0;
  int heightAvg = 0;

  float fullArea = (float)X * Y;

  for (YoloSample yoloSample : samples) {
    List<YoloBody> yoloBodies = yoloSample.getYoloBodies();
    if (yoloBodies == null) {
      continue;
    }
    for (YoloBody body : yoloBodies) {
      if (body == null) {
        continue;
      }
      types.add(body.getTypeID());

      widthCount += body.getWidth();
      heightCount += body.getHeight();
      bodyCount ++;
      sampleThCount += ((float) body.getWidth() * (float) body.getHeight()) / fullArea;

      widthMin = Math.min(widthMin, body.getWidth());
      widthMax = Math.max(widthMax, body.getWidth());
      heightMin = Math.min(heightMin, body.getHeight());
      heightMax = Math.max(heightMax, body.getHeight());
    }
  }

  widthAvg = widthCount / bodyCount;
  heightAvg = heightCount / bodyCount;

  SamplateInfo info = new SamplateInfo();

  // body 数量
  info.setBodyCount(bodyCount);

  // 最小宽度,最大宽度,平均宽度
  info.setWidthMin(widthMin);
  info.setWidthMax(widthMax);
  info.setWidthAvg(widthAvg);

  // 最小高度,最大高度,平均高度
  info.setHeightMin(heightMin);
  info.setHeightMax(heightMax);
  info.setHeightAvg(heightAvg);

  // 图像检测的类别数
  info.setTypeCount(types.size());

  info.setContainIouTh(sampleThCount / bodyCount);
  return info;
}

Released under the MIT License.