labelme 标注json转换为带旋转角度的yolov5标记文件。其中opencv 4.5.3
Posted 东东就是我
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了labelme 标注json转换为带旋转角度的yolov5标记文件。其中opencv 4.5.3相关的知识,希望对你有一定的参考价值。
1.每个版本的opencv 的minAreaRect 角度的范围都是不一样的。自己检查一下
import numpy as np
import math
import cv2
def draw_rbbox(img, points):
rect = cv2.minAreaRect(points)
c_x = rect[0][0]
c_y = rect[0][1]
width = rect[1][0]
height= rect[1][1]
theta = rect[-1]
if width != max(width, height): # 若width不是最长边
longside = height
shortside = width
theta_longside = -(90-theta)
else: # 若width是最长边(包括正方形的情况)
longside = width
shortside = height
theta_longside = theta
tran=((c_x, c_y), (longside, shortside), theta_longside)
print(theta_longside)
points_rect = cv2.boxPoints(tran)
box = np.int0(points_rect)
img = cv2.drawContours(img, [box], 0, (0, 0, 255), 2)
return img
img = np.zeros([500, 500, 3], dtype=np.uint8)
x1=250
y1=250
x2=250
y2=400
x3=300
y3=400
x4=300
y4=250
for i in range(9):
nAgree=i*(180/9)
dRot=nAgree*math.pi/180
dSinRot=math.sin(dRot)
dCosRot=math.cos(dRot)
newx1=x1
newy1=y1
newx2=x1 + dCosRot * (x2 - x1) - dSinRot * (y2 - y1)
newy2=y1 + dSinRot * (x2 - x1) + dCosRot * (y2 - y1)
newx3= x1 + dCosRot * (x3 - x1) - dSinRot * (y3 - y1)
newy3=y1 + dSinRot * (x3 - x1) + dCosRot * (y3 - y1)
newx4=x1 + dCosRot * (x4 - x1) - dSinRot * (y4 - y1)
newy4=y1 + dSinRot * (x4 - x1) + dCosRot * (y4 - y1)
draw_rbbox(img,np.array([[newx1,newy1],[newx2,newy2],[newx3,newy3],[newx4,newy4]],dtype=np.int64))
cv2.imwrite(r'111.jpg', img)
这里的范围是【0,90】 我扩充到【0,180】
# -*- coding: utf-8 -*-
# import dota_utils as util
import numpy as np
import json
import cv2
import os
def dota2LongSideFormat(path,json_name):
# print(json_name)
json_path = os.path.join(path, json_name)
img_path=os.path.join(path, json_name.split('.')[0]+'.bmp')
img=cv2.imread(img_path)
with open(json_path,'r') as f:
data=json.load(f)
shapes=data['shapes']
imageHeight=data['imageHeight']
imageWidth=data['imageWidth']
txt_name=json_name.split('.')[0] + '.txt'
txt_path=os.path.join(path,txt_name)
with open(txt_path, 'w') as f_out:
for shape in shapes:
points = shape['points']
poly = np.float32(np.array(points))
# 四点坐标归一化
poly[:, 0] = poly[:, 0] / imageWidth
poly[:, 1] = poly[:, 1] / imageHeight
rect = cv2.minAreaRect(poly) # 得到最小外接矩形的(中心(x,y), (宽,高), 旋转角度)
c_x = rect[0][0]
c_y = rect[0][1]
w = rect[1][0]
h = rect[1][1]
theta = rect[-1] # Range for angle is [-90,0)
trans_data = cvminAreaRect2longsideformat(c_x, c_y, w, h, theta)
c_x, c_y, longside, shortside, theta_longside = trans_data
bbox = np.array((c_x, c_y, longside, shortside))
theta_label = int(theta_longside + 90) # range int[0,180] 四舍五入
if theta_label == 180: # range int[0,179]
theta_label = 179
outline = str(0) + ' ' + ' '.join(list(map(str, bbox))) + ' ' + str(theta_label)
f_out.write(outline + '\\n') # 写入txt文件中并加上换行符号 \\n
def cvminAreaRect2longsideformat(x_c, y_c, width, height, theta):
if width != max(width, height): # 若width不是最长边
longside = height
shortside = width
theta_longside = -(90-theta)
else: # 若width是最长边(包括正方形的情况)
longside = width
shortside = height
theta_longside = theta
# return x_c, y_c, longside, shortside, theta_longside
return x_c, y_c, longside, shortside, theta_longside
if __name__ == '__main__':
## an example
path='F:/mmdetection-2.7.0/dataset/bottle'
file=os.listdir(path)
for filename in file:
if filename.endswith('.json'):
dota2LongSideFormat(path,filename)
以上是关于labelme 标注json转换为带旋转角度的yolov5标记文件。其中opencv 4.5.3的主要内容,如果未能解决你的问题,请参考以下文章
[原创]如何将labelme标注的json文件批量导入easyDL方法
[软件工具][原创]将labelme的json文件转换成类别映射的8位索引图像使用教程