目标检测yolo格式转labelme格式 java代码

yolo目标检测数据采用矩形框进行标注,其标注格式为[cls_id xp yp wp hp],cls_id表示目标所属的类别序号。xp、yp表示目标中心点相对坐标,其中xp等于目标的绝对横坐标除以图像宽度,yp等于目标的绝对纵坐标除以图像高度。wp和hp表示目标的相对宽度和高度,其中wp等于目标的绝对宽度除以图像宽度,hp等于目标的绝对高度除以图像高度。每张图片的标注结果以txt文本文件存储,每一行[cls_id xp yp wp hp]表示一个目标。

cv_img=cv2.imdecode(np.fromfile(imagePath,dtype=np.uint8),flags=cv2.IMREAD_COLOR)

labelme矩形目标的标注格式为[x1 y1 x2 y2],表示目标的左上和右下的绝对坐标。

yolo转labelme程序

Java版本

转换方法:

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.core.domain.LabelMeObj;
import com.ruoyi.common.core.domain.LabelMeShape;
import org.bytedeco.opencv.opencv_core.Mat;

import java.io.File;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;

import static org.bytedeco.opencv.global.opencv_imgcodecs.imread;

public class LabelUtil {

    /**
     * yolo转labelme格式
     *
     * @param imagePath
     * @param yoloLabelPath
     * @param labelMePath
     */
    public static void yolo2labelMeConverter(String imagePath, String yoloLabelPath, String labelMePath) {
        // 读取图像
        try (Mat src = imread(imagePath)) {
            int w = src.cols();
            int h = src.rows();
            // 读取注释文件
            if (!new File(yoloLabelPath).exists()) {
                return;
            }
            List<String> lines = FileUtil.readUtf8Lines(yoloLabelPath);
            if (CollUtil.isNotEmpty(lines)) {
                LabelMeObj labelMeObj = new LabelMeObj();
                labelMeObj.setVersion("5.0.1");
                labelMeObj.setFlags(new JSONObject());
                labelMeObj.setImagePath(imagePath);
                labelMeObj.setImageHeight(h);
                labelMeObj.setImageWidth(w);
                JSONArray jsonArray = new JSONArray();
                for (String line : lines) {
                    if (StrUtil.isBlank(line)) {
                        continue;
                    }
                    LabelMeShape labelMeShape = new LabelMeShape();
                    List<String> split = StrUtil.split(line, StrUtil.SPACE);
                    double[][] points = new double[2][2];
                    // yolo注释数据
                    double x = Double.parseDouble(split.get(1));
                    double y = Double.parseDouble(split.get(2));
                    double w_ = Double.parseDouble(split.get(3));
                    double h_ = Double.parseDouble(split.get(4));
                    // 绝对数值转换
                    x = w * x;
                    y = h * y;
                    w_ = w * w_;
                    h_ = h * h_;
                    points[0][0] = new BigDecimal(x - w_ / 2).setScale(2, RoundingMode.HALF_UP).doubleValue();
                    points[0][1] = new BigDecimal(y - h_ / 2).setScale(2, RoundingMode.HALF_UP).doubleValue();
                    points[1][0] = new BigDecimal(x + w_ / 2).setScale(2, RoundingMode.HALF_UP).doubleValue();
                    points[1][1] = new BigDecimal(y + h_ / 2).setScale(2, RoundingMode.HALF_UP).doubleValue();
                    labelMeShape.setLabel(split.get(0));
                    labelMeShape.setPoints(JSONArray.of(points));
                    labelMeShape.setShape_type("rectangle");
                    labelMeShape.setFlags(new JSONObject());
                    jsonArray.add(labelMeShape);
                }
                labelMeObj.setShapes(jsonArray);
                // 转换后注释写入文件
                FileUtil.writeUtf8String(JSON.toJSONString(labelMeObj), labelMePath);
            }
        }
    }
}

实体类: 


import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import lombok.Data;

/**
 * @author lipei
 */
@Data
public class LabelMeObj {

    private String version;

    private JSONObject flags;

    private String imageData;

    private String imagePath;

    private Integer imageHeight;

    private Integer imageWidth;

    private JSONArray shapes;
}
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import lombok.Data;

/**
 * @author lipei
 */
@Data
public class LabelMeShape {

    private String label;

    private JSONArray points;

    private String group_id;

    private String shape_type;

    private JSONObject flags;
}

原Python版本

# -*- coding: utf-8 -*-
"""
Created on Tue Mar 29 17:42:11 2022
@author: https://blog.csdn.net/suiyingy?type=blog
"""
import cv2
import os
import json
import shutil
import numpy as np
from pathlib import Path
 
id2cls = {0:'pig'}
 
def xyxy2labelme(labels, w, h, image_path, save_dir='res/'):
    save_dir = str(Path(save_dir)) + '/'
    if not os.path.exists(save_dir):
        os.makedirs(save_dir)
    label_dict = {}
    label_dict['version'] = '5.0.1'
    label_dict['flags'] = {}
    label_dict['imageData'] = None
    label_dict['imagePath'] = image_path
    label_dict['imageHeight'] = h
    label_dict['imageWidth'] = w
    label_dict['shapes'] = []
    for l in labels:
        tmp = {}
        tmp['label'] = id2cls[int(l[0])]
        tmp['points'] =[[l[1], l[2]], [l[3], l[4]]]
        tmp['group_id']= None
        tmp['shape_type'] = 'rectangle'
        tmp['flags'] = {}
        label_dict['shapes'].append(tmp)    
    fn = save_dir+image_path.rsplit('.', 1)[0]+'.json'
    with open(fn, 'w') as f:
        json.dump(label_dict, f)
 
def yolo2labelme(yolo_image_dir, yolo_label_dir, save_dir='res/'):
    yolo_image_dir = str(Path(yolo_image_dir)) + '/'
    yolo_label_dir = str(Path(yolo_label_dir)) + '/'
    save_dir = str(Path(save_dir)) + '/'
    image_files = os.listdir(yolo_image_dir)
    for iimgf, imgf in enumerate(image_files):
        print(iimgf+1, '/', len(image_files), imgf)
        fn = imgf.rsplit('.', 1)[0]
        shutil.copy(yolo_image_dir + imgf, save_dir + imgf)
        image = cv2.imread(yolo_image_dir + imgf)
        h,w = image.shape[:2]
        if not os.path.exists(yolo_label_dir + fn + '.txt'):
            continue
        labels = np.loadtxt(yolo_label_dir + fn + '.txt').reshape(-1, 5)
        if len(labels) < 1:
            continue
        labels[:,1::2] = w * labels[:, 1::2]
        labels[:,2::2] = h * labels[:, 2::2]
        labels_xyxy = np.zeros(labels.shape)
        labels_xyxy[:, 1] = np.clip(labels[:, 1] - labels[:, 3]/2, 0, w)
        labels_xyxy[:, 2] = np.clip(labels[:, 2] - labels[:, 4]/2, 0, h)
        labels_xyxy[:, 3] = np.clip(labels[:, 1] + labels[:, 3]/2, 0, w)
        labels_xyxy[:, 4] = np.clip(labels[:, 2] + labels[:, 4]/2, 0, h)
        xyxy2labelme(labels_xyxy, w, h, imgf, save_dir)
    print('Completed!')
 
if __name__ == '__main__':
    yolo_image_dir = r'H:\Data\pigs\images\train'
    yolo_label_dir = r'H:\Data\pigs\labels\train'
    save_dir = r'res/'
    yolo2labelme(yolo_image_dir, yolo_label_dir, save_dir)


参考资料:https://blog.csdn.net/suiyingy/article/details/127217640

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值