目标检测 YOLOv5 常见的边框(bounding box )坐标矩形框表示方法

将txt格式的真值框(Ground Truth)在原图上显示

具体过程坎坷,以下博主提供了思路,学习了yolo格式label的归一化和坐标求解!
1、https://blog.csdn.net/flyfish1986/article/details/117133648
2、https://blog.csdn.net/Rocky6688/article/details/107492684
注意:为了方便读取,标签txt文件我是将类别0或者1删除了,只保留坐标,大家可以提前copy一份再修改

import numpy as np
import cv2
import torch

label_path = './labels/train2017/000002_01_01_162.txt'
image_path = './images/train2017/000002_01_01_162.png'

#坐标转换,原始存储的是YOLOv5格式
# Convert nx4 boxes from [x, y, w, h] normalized to [x1, y1, x2, y2] where xy1=top-left, xy2=bottom-right
def xywh2xyxy(x,y,w,h,w1,h1,img):
    print("原图宽高:\nw1={}\nh1={}".format(w1, h1))
    #边界框反归一化
    x_t = x*w1
    y_t = y*h1
    w_t = w*w1
    h_t = h*h1
    print("反归一化后输出:\n第一个:{}\t第二个:{}\t第三个:{}\t第四个:{}\t\n\n".format(x_t,y_t,w_t,h_t))

    #计算坐标
    top_left_x = x_t - w_t/2
    top_left_y = y_t - h_t/2
    bottom_right_x = x_t + w_t / 2
    bottom_right_y = y_t + h_t / 2
    print("左上x坐标:{}".format(top_left_x))
    print("左上y坐标:{}".format(top_left_y))
    print("右下x坐标:{}".format(bottom_right_x))
    print("右下y坐标:{}".format(bottom_right_y))

    # 绘图  rectangle()函数需要坐标为整数
    cv2.rectangle(img, (int(top_left_x), int(top_left_y)), (int(bottom_right_x), int(bottom_right_y)), (0, 255, 0), 2)
    cv2.imshow('show', img)
    cv2.imwrite('11.png',img)
    cv2.waitKey(0)  # 按键结束
    cv2.destroyAllWindows()


#读取labels
with open(label_path, 'r') as f:
    lb = np.array([x.split() for x in f.read().strip().splitlines()], dtype=np.float32)  # labels
    print(lb)
    #确认读取无误
    print("读取txt内容:\n第一个:{}\t第二个:{}\t第三个:{}\t第四个:{}\t".format(lb[0][0],lb[0][1],lb[0][2],lb[0][3]))

#读取图像文件
img = cv2.imread(str(image_path))
#展示读取的图像
#cv2.imshow('read',img)
#cv2.waitKey(0)
h, w = img.shape[:2]

#反归一化并得到左上和右下坐标,画出矩形框
xywh2xyxy(lb[0][0],lb[0][1],lb[0][2],lb[0][3],w,h,img)

批量处理数据显示

注意:这里不需要对yolo数据进行任何操作,不需要删除txt里面的类别

import os
import cv2


def xywh2xyxy(lp):
    fileList = os.listdir(lp)
    for fileName in fileList:
        # 打开标签文件
        fileLabel = open(lp + "/" + fileName, "r+")
        # 取出文件名并拼接.jpg
        imgName = fileName.split(".")[0] + ".jpg"
        print("所需图片{}".format(imgName))
        # 对应图片地址
        imagePath = "E:/iron/coco/images/test2017/" + imgName
        print("图片地址{}".format(imagePath))
        img = cv2.imread(imagePath)
        h_img, w_img = img.shape[:2]
        print("图片宽:{}\t高:{}".format(w_img, h_img))
        # 读取标签内容
        info = fileLabel.read()
        kind = info.split(" ")[0]
        print("kind:{}".format(kind))
        cenX = float(info.split(" ")[1])
        cenY = float(info.split(" ")[2])
        wide = float(info.split(" ")[3])
        high = float(info.split(" ")[4])
        print("中心点坐标({},{})\t宽:{}\t高:{}\n".format(cenX, cenY, wide, high))

        # 边界框反归一化
        x_t = cenX * w_img
        y_t = cenY * h_img
        w_t = wide * w_img
        h_t = high * h_img
        print("反归一化后输出:\n第一个:{}\t第二个:{}\t第三个:{}\t第四个:{}\t\n\n".format(x_t, y_t, w_t, h_t))
        # 计算坐标
        top_left_x = x_t - w_t / 2
        top_left_y = y_t - h_t / 2
        bottom_right_x = x_t + w_t / 2
        bottom_right_y = y_t + h_t / 2
        print("左上x坐标:{}".format(top_left_x))
        print("左上y坐标:{}".format(top_left_y))
        print("右下x坐标:{}".format(bottom_right_x))
        print("右下y坐标:{}".format(bottom_right_y))
        # 绘图  rectangle()函数需要坐标为整数
        cv2.rectangle(img, (int(top_left_x), int(top_left_y)), (int(bottom_right_x), int(bottom_right_y)), (0, 255, 0),
                      2)
        newDetPath = "E:/iron/gt/"+imgName
        cv2.imwrite(newDetPath, img)
        fileLabel.close()

if __name__ == "__main__":
    # 标签地址
    label_path = 'E:/iron/coco/labels/test2017'
    # 调用函数
    xywh2xyxy(label_path)

你可能感兴趣的:(python,cv)