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, т. е. его можно использовать бесплатно как в некоммерческих, так и в коммерческих целях.

Ссылки на этот сайт приветствуются.


HuggingFace

Google Drive (архив .7z)

Яндекс Диск (архив .7z)


Благодарности

Большое спасибо всем, кто предоставил свои примеры слов или помог распространить информацию о датасете.

Авторы отдельных изображений не упоминаются в файлах датасета. Тем не менее, если вы принимали участие в проекте и хотите, чтобы ваше имя было отдельно указано в этой секции, пожалуйста, напишите об этом на handwritten.birds@gmail.com.