如何将多边形坐标转换为矩形(yolo 格式)以进行图像标记?
How to convert polygon coordinates to rectangle(yolo format) for an image labelling?
我正在尝试通过 OCR 读取水表读数,但是,我的第一步是找到投资回报率。我从 Kaggle 中找到了一个带有 ROI 标记数据的数据集。但它们不是矩形,而是多边形,有的有 5 个点,有的有 8 个点,具体取决于图像。我如何将其转换为 yolo 格式?
例如:
file name | value | coordinates
id_53_value_595_825.jpg 595.825 {'type': 'polygon', 'data': [{'x': 0.30788, 'y': 0.30207}, {'x': 0.30676, 'y': 0.32731}, {'x': 0.53501, 'y': 0.33068}, {'x': 0.53445, 'y': 0.33699}, {'x': 0.56529, 'y': 0.33741}, {'x': 0.56697, 'y': 0.29786}, {'x': 0.53501, 'y': 0.29786}, {'x': 0.53445, 'y': 0.30417}]}
id_553_value_65_475.jpg 65.475 {'type': 'polygon', 'data': [{'x': 0.26133, 'y': 0.24071}, {'x': 0.31405, 'y': 0.23473}, {'x': 0.31741, 'y': 0.26688}, {'x': 0.30676, 'y': 0.26763}, {'x': 0.33985, 'y': 0.60851}, {'x': 0.29386, 'y': 0.61449}]}
id_407_value_21_86.jpg 21.86 {'type': 'polygon', 'data': [{'x': 0.27545, 'y': 0.19134}, {'x': 0.37483, 'y': 0.18282}, {'x': 0.38935, 'y': 0.76071}, {'x': 0.28185, 'y': 0.76613}]}
我知道对于 yolo 格式,我需要获取 xmin、ymin、xmax、ymax 以便我可以计算宽度和高度,但我在解析数据时遇到了问题。有人可以帮忙吗?
谢谢。
编辑:终于成功了。如果有人正在努力将 csv 文件从 https://www.kaggle.com/datasets/tapakah68/yandextoloka-water-meters-dataset 转换为 yolo 格式,
这是我的代码片段,用于为每个图像创建文本文件。
import csv
import pandas as pd
import json
import ast
def converttoyolo(csv_file):
df = pd.read_csv(csv_file)
l_csv = len(df)
for i in range(l_csv):
df_row = df.iloc[i] #get each row
df_ = df_row['photo_name'] #image column
df__ = df_.split('.') #to get name for text file
df_new = df_row['location'] #start of gettinf coordinates access
df_dict = ast.literal_eval(df_new) #str to dict
df__dict = json.dumps(df_dict, indent = 4)
df_dict__ = json.loads(df__dict)
convertedDict = df_dict__
length = len(convertedDict['data'])
x = []
y = []
for j in range(length): #put each x and y for each row in seperate array
x.append(convertedDict['data'][j]['x'])
y.append(convertedDict['data'][j]['y'])
max_x = max(x)
max_y = max(y) #yolo conversion, check answer below
min_x = min(x)
min_y = min(y)
width = max_x - min_x
height = max_y - min_y
center_x = min_x + (width/2)
center_y = min_y + (height/2)
def filename(file): #put in text files
with open(file+".txt", "w") as file:
file.write(str(width)+','+str(height)+','+ ...
str(center_y)+','+str(center_y))
filename('/content/drive/MyDrive/yolo/custom_data/jpeg/'+df__[0])
converttoyolo(csv_file)
您需要为每个形状创建轮廓(点列表)。
一旦你有了它,然后调用 cv::boundingRect()
将每个轮廓变成一个单一的边界矩形。
一旦你有了矩形,你就可以计算出 X、Y、W 和 H。
但是由于 YOLO 格式是 CX 和 CY——而不是 X 和 Y——那么你需要做:
CX = X + W/2.0
CY = Y + H/2.0
最后,您必须标准化所有 4 个值。 YOLO 格式是 space 分隔,第一个值是整数 class ID。因此,如果“dog”是您的第二个 class(因此 id #1 因为它是 zero-based),那么您将输出:
1 0.234 0.456 0.123 0.111
...其中4个坐标是:
CX / image width
CY / image height
W / image width
H / image height
如果您需要更多数学示例,请参阅 Darknet/YOLO 常见问题解答:https://www.ccoderun.ca/programming/darknet_faq/#darknet_annotations
我正在尝试通过 OCR 读取水表读数,但是,我的第一步是找到投资回报率。我从 Kaggle 中找到了一个带有 ROI 标记数据的数据集。但它们不是矩形,而是多边形,有的有 5 个点,有的有 8 个点,具体取决于图像。我如何将其转换为 yolo 格式? 例如:
file name | value | coordinates
id_53_value_595_825.jpg 595.825 {'type': 'polygon', 'data': [{'x': 0.30788, 'y': 0.30207}, {'x': 0.30676, 'y': 0.32731}, {'x': 0.53501, 'y': 0.33068}, {'x': 0.53445, 'y': 0.33699}, {'x': 0.56529, 'y': 0.33741}, {'x': 0.56697, 'y': 0.29786}, {'x': 0.53501, 'y': 0.29786}, {'x': 0.53445, 'y': 0.30417}]}
id_553_value_65_475.jpg 65.475 {'type': 'polygon', 'data': [{'x': 0.26133, 'y': 0.24071}, {'x': 0.31405, 'y': 0.23473}, {'x': 0.31741, 'y': 0.26688}, {'x': 0.30676, 'y': 0.26763}, {'x': 0.33985, 'y': 0.60851}, {'x': 0.29386, 'y': 0.61449}]}
id_407_value_21_86.jpg 21.86 {'type': 'polygon', 'data': [{'x': 0.27545, 'y': 0.19134}, {'x': 0.37483, 'y': 0.18282}, {'x': 0.38935, 'y': 0.76071}, {'x': 0.28185, 'y': 0.76613}]}
我知道对于 yolo 格式,我需要获取 xmin、ymin、xmax、ymax 以便我可以计算宽度和高度,但我在解析数据时遇到了问题。有人可以帮忙吗?
谢谢。
编辑:终于成功了。如果有人正在努力将 csv 文件从 https://www.kaggle.com/datasets/tapakah68/yandextoloka-water-meters-dataset 转换为 yolo 格式, 这是我的代码片段,用于为每个图像创建文本文件。
import csv
import pandas as pd
import json
import ast
def converttoyolo(csv_file):
df = pd.read_csv(csv_file)
l_csv = len(df)
for i in range(l_csv):
df_row = df.iloc[i] #get each row
df_ = df_row['photo_name'] #image column
df__ = df_.split('.') #to get name for text file
df_new = df_row['location'] #start of gettinf coordinates access
df_dict = ast.literal_eval(df_new) #str to dict
df__dict = json.dumps(df_dict, indent = 4)
df_dict__ = json.loads(df__dict)
convertedDict = df_dict__
length = len(convertedDict['data'])
x = []
y = []
for j in range(length): #put each x and y for each row in seperate array
x.append(convertedDict['data'][j]['x'])
y.append(convertedDict['data'][j]['y'])
max_x = max(x)
max_y = max(y) #yolo conversion, check answer below
min_x = min(x)
min_y = min(y)
width = max_x - min_x
height = max_y - min_y
center_x = min_x + (width/2)
center_y = min_y + (height/2)
def filename(file): #put in text files
with open(file+".txt", "w") as file:
file.write(str(width)+','+str(height)+','+ ...
str(center_y)+','+str(center_y))
filename('/content/drive/MyDrive/yolo/custom_data/jpeg/'+df__[0])
converttoyolo(csv_file)
您需要为每个形状创建轮廓(点列表)。
一旦你有了它,然后调用 cv::boundingRect()
将每个轮廓变成一个单一的边界矩形。
一旦你有了矩形,你就可以计算出 X、Y、W 和 H。
但是由于 YOLO 格式是 CX 和 CY——而不是 X 和 Y——那么你需要做:
CX = X + W/2.0
CY = Y + H/2.0
最后,您必须标准化所有 4 个值。 YOLO 格式是 space 分隔,第一个值是整数 class ID。因此,如果“dog”是您的第二个 class(因此 id #1 因为它是 zero-based),那么您将输出:
1 0.234 0.456 0.123 0.111
...其中4个坐标是:
CX / image width
CY / image height
W / image width
H / image height
如果您需要更多数学示例,请参阅 Darknet/YOLO 常见问题解答:https://www.ccoderun.ca/programming/darknet_faq/#darknet_annotations