用labelme对图片进行标注,标注好的json有多边形和圆(polygon和circle),在进行labelme2yolo.py转换后,进而训练模型时出现报错,报错内容为不识别除了polygon外其他格式
所以应该将circle转换成polygon之后,再转换成yolo格式
代码如下
def _get_yolo_object_list(self, json_data, img_path):
yolo_obj_list = []
img_h, img_w, _ = cv2.imread(img_path).shape
for shape in json_data['shapes']:
# labelme circle shape is different from others
# it only has 2 points, 1st is circle center, 2nd is drag end point
try:
if shape['shape_type'] == 'circle':
polygon_shape = self._convert_circle_to_polygon(shape)
yolo_obj = self._get_polygon_shape_yolo_object(polygon_shape, img_h, img_w)
yolo_obj_list.append(yolo_obj)
elif shape['shape_type'] == 'polygon': # lll
yolo_obj = self._get_polygon_shape_yolo_object(shape, img_h, img_w)
yolo_obj_list.append(yolo_obj)
elif shape['shape_type'] == 'rectangle':
yolo_obj = self._get_other_shape_yolo_object(shape, img_h, img_w)
except Exception as e:
logging.Logger(e)
return yolo_obj_list
def _convert_circle_to_polygon(self, shape):
center_x, center_y = shape['points'][0]
radius = math.sqrt((center_x - shape['points'][1][0]) ** 2 +
(center_y - shape['points'][1][1]) ** 2)
# 将圆形转换为8边形多边形
num_sides = 8
angle_step = 2 * math.pi / num_sides
polygon_points = []
for i in range(num_sides):
angle = i * angle_step
x = center_x + radius * math.cos(angle)
y = center_y + radius * math.sin(angle)
polygon_points.append([x, y])
return {
'label': shape['label'],
'shape_type': 'polygon',
'points': polygon_points
}
def _get_other_shape_yolo_object(self, shape, img_h, img_w):
def __get_object_desc(obj_port_list):
__get_dist = lambda int_list: max(int_list) - min(int_list)
x_lists = [port[0] for port in obj_port_list]
y_lists = [port[1] for port in obj_port_list]
return min(x_lists), __get_dist(x_lists), min(y_lists), __get_dist(y_lists)
obj_x_min, obj_w, obj_y_min, obj_h = __get_object_desc(shape['points'])
yolo_center_x = round(float((obj_x_min + obj_w / 2.0) / img_w), 6)
yolo_center_y = round(float((obj_y_min + obj_h / 2.0) / img_h), 6)
yolo_w = round(float(obj_w / img_w), 6)
yolo_h = round(float(obj_h / img_h), 6)
label_id = self._label_id_map[shape['label'].rstrip(string.digits).rstrip('_').rstrip(string.digits)]
return label_id, yolo_center_x, yolo_center_y, yolo_w, yolo_h
# compute polygon points # add by lll
def _get_polygon_shape_yolo_object(self, shape, img_h, img_w):
def __get_points_list(obj_port_list):
x_lists = [port[0] for port in obj_port_list]
y_lists = [port[1] for port in obj_port_list]
return x_lists, y_lists
label_id_polygon_points = []
label_id = self._label_id_map[shape['label'].rstrip(string.digits).rstrip('_').rstrip(string.digits)]
label_id_polygon_points.append(label_id)
x_lists, y_lists = __get_points_list(shape['points'])
for x_point, y_point in zip(x_lists, y_lists):
yolo_x = round(float(x_point / img_w), 6)
label_id_polygon_points.append(yolo_x)
yolo_y = round(float(y_point / img_h), 6)
label_id_polygon_points.append(yolo_y)
return tuple(label_id_polygon_points)