Я хочу сделать распознавание рукописных цифр, используя классификацию K-Nearest Neighbours с scikit-learn. У меня есть папка, в которой 5001 изображение рукописных цифр (500 изображений для каждой цифры от 0 до 9).

enter image description here

Я пытаюсь найти способ создать набор данных на основе этих изображений, чтобы затем я мог создать набор для обучения и тестирования. Я прочитал много онлайн-уроков о том, как выполнить классификацию K-Nearest Neighbors с помощью scikit-learn, но большинство уроков загружают существующие наборы данных, такие как набор данных MNIST рукописных цифр.

Есть ли способ создать свой собственный набор данных, читая изображения из папки, а затем назначая метку для каждого изображения? Я не уверен, какие методы я могу использовать для этого. Любые идеи приветствуются.

2
ceno980 2 Июл 2019 в 11:25

3 ответа

Лучший ответ

Чтобы прочитать данные, вы должны сделать что-то вроде этого:

from os import listdir
from os.path import isfile, join
import re
import matplotlib.pyplot as plt

mypath = '.' # edit with the path to your data
files = [f for f in listdir(mypath) if isfile(join(mypath, f))]

x = []
y = []

for file in files:
    label = file.split('_')[0] # assuming your img is named like this "eight_1.png" you want to get the label "eight"
    y.append(label)
    img = plt.imread(file)
    x.append(img)

Тогда вам нужно будет немного поэкспериментировать с x и y перед тем, как научить его, но у вас все будет хорошо.

0
Simon Delecourt 2 Июл 2019 в 08:50

Это помогает?

import os
import imageio


def convert_word_to_label(word):

    if word == 'zero':
        return 0
    elif word == 'one':
        return 1
    elif word == 'two':
        return 2
    elif word == 'three':
        return 3
    elif word == 'four':
        return 4
    elif word == 'five':
        return 5
    elif word == 'six':
        return 6
    elif word == 'seven':
        return 7
    elif word == 'eight':
        return 8
    elif word == 'nine':
        return 9



def create_dataset(path):
    X = []
    y = []

    for r, d, f in os.walk(path):
        for image in f:
            if '.jpg' in image:
                image_path = os.path.join(r, image)
                img = imageio.imread(image_path)
                X.append(img)
                word = image.split('_')[0]
                y.append(convert_word_to_label(word))
    return X, y

if __name__ == '__main__':
    X, y = create_dataset('path/to/image_folder/')
0
lenngro 2 Июл 2019 в 08:54

Вы можете использовать библиотеки Pillow или opencv для чтения ваших изображений.

Для подушки:

from PIL import Image 
import numpy as np

img = PIL.Image.open("image_location/image_name") # This returns an image object   
img = np.asarray(img) # convert it to ndarray

Для Opencv:

import cv2

img = cv2.imread("image_location/image_name", cv2.IMREAD_GRAYSCALE)

Для конвертации всех ваших изображений вы можете использовать, например, библиотеку:

import os
loc = os.listdir('your_images_folder')

Для хранения изображений градаций серого с одним цветным каналом можно использовать пустой массив

data = np.ones((# of images, image_size wxh))


  for i, l in enumerate(loc):

     # Full image path
     path = os.path.join("your_images_folder", l)

     img = np.asarray(PIL.Image.open(path))

     # Make a vector from an image
     img = img.reshape(-1, img.size)

     # store this vector
     data[i,:]  = img

В результате вы получите массив данных «data» для вашего проекта классификации. Вектор "y" может быть добавлен также в том же цикле от имени каждого изображения.

Чтобы отслеживать ваш процесс с помощью индикатора выполнения в цикле, иногда библиотека tqdm может быть правильным решением. Для хранения изображений RGB вы можете реализовать то же решение. Для изображений RGB img.reshape(-1, ) вернет ваш более длинный вектор.

0
Alexander Popkov 2 Июл 2019 в 12:32