RuBirdNames: Датасет рукописных названий птиц
Описание датасета
Датасет RuBirdNames представляет собой набор из 21325 изображений 583 слов, написанных от руки. Эти слова входят в русскоязычные названия 701 вида птиц, встречающихся на территории России по состоянию на 2023 год.
В датасете представлены примеры прописных и рукописных печатных шрифтов от 30-40 писателей разных возрастов. Также представлены разные примеры фона: однотонный белый, однотонный серый, бумага в клетку, линованная бумага.
Изображения распределены по папкам, названия которых являются лейблом для хранящихся в них изображений. В каждой папке находится от 35 до 38 изображений одного и того же слова. Изображения с одним и тем же номером в названии принадлежат к одному и тому же набору слов, что позволяет отфильтровать датасет по типу шрифта, фона и т. п.
Чтобы проверить содержимое датасета, можно воспользоваться следующим кодом:
import os
import unicodedata
import numpy as np
# подсчет и проверка меток
img_dirs = sorted(
unicodedata.normalize('NFC', f) for f in os.listdir(image_dir)
)
print(f"Total words: {len(img_dirs)}")
print(f"First: {img_dirs[0]} Last: {img_dirs[-1]}")
img_count = 0
img_counts = []
alphabet = set()
for img_dir in img_dirs:
# подсчет общего количества изображений и изображений в каждой папке
count = len(os.listdir(os.path.join(image_dir, img_dir)))
img_count += count
img_counts.append(count)
# формирование алфавита
for char in img_dir:
alphabet.add(char)
print(f"Total images: {img_count}")
print(
f"Images in folder: min: {np.min(img_counts)}, max: {np.max(img_counts)}, avg: {np.mean(img_counts)}"
)
Подготовить список путей к изображениям и разбить его на тренировочный, валидационный и тестовый наборы можно так:
# 80 - 10 - 10
max_count = np.max(img_counts)
test_count = round(max_count * 0.1)
valid_count = round(max_count * 0.1)
train_count = max_count - test_count - valid_count
train_paths, val_paths, test_paths = [], [], []
for bird_dir in img_dirs:
image_paths = [
os.path.join(image_dir, bird_dir, img_path) for img_path
in os.listdir(os.path.join(image_dir, bird_dir))
]
random.shuffle(image_paths)
train_paths.extend(image_paths[:train_count])
val_paths.extend(image_paths[train_count:train_count + valid_count])
test_paths.extend(image_paths[-test_count:])
assert set(train_paths) & set(val_paths) & set(test_paths) == set()
print(len(train_paths), len(val_paths), len(test_paths))
Поскольку некоторые слова написаны с ошибками, в датасет также входит файл corrections.csv, содержащий исправленные лейблы. Для чтения этого файла можно воспользоваться следующим кодом:
corrections = dict()
with open(corr_file, 'r', encoding='utf-8') as f:
while line := f.readline():
folder, filenum, correction = line.split(',')
correction = correction.strip()
image_path = os.path.join(image_dir, folder, f"{filenum}.png")
print(f"Image: {folder}/{filenum}.png\nLabel: {correction}")
corrections[image_path] = correction
for char in correction:
alphabet.add(char)
print(f"Total corrections: {len(corrections)}")
Получить лейблы с учетом добавленных исправлений можно с помощью этого кода:
def get_image_text_label(image_path, corrections):
if image_path in corrections:
return corrections[image_path]
parts = os.path.dirname(image_path).split('/')
return parts[-1]
train_labels = [
get_image_text_label(path, corrections)
for path in train_paths
]
Условия использования
Датасет RuBirdNames распространяется по лицензии Apache 2.0, т. е. его можно использовать бесплатно как в некоммерческих, так и в коммерческих целях.
Ссылки на этот сайт приветствуются.
Ссылки для скачивания
Благодарности
Большое спасибо всем, кто предоставил свои примеры слов или помог распространить информацию о датасете.
Авторы отдельных изображений не упоминаются в файлах датасета. Тем не менее, если вы принимали участие в проекте и хотите, чтобы ваше имя было отдельно указано в этой секции, пожалуйста, напишите об этом на handwritten.birds@gmail.com.