Как реализовать файл.dat для распознавания рукописного текста с использованием SVM в Python

Я пытался обучить рукописные цифры с использованием SVM на основе кода в библиотеке OpenCV. Моя учебная часть выглядит следующим образом:

import cv2
import numpy as np

SZ=20
bin_n = 16
svm_params = dict( kernel_type = cv2.SVM_LINEAR,
                   svm_type = cv2.SVM_C_SVC,
                C=2.67, gamma=5.383 )
affine_flags = cv2.WARP_INVERSE_MAP|cv2.INTER_LINEAR

def deskew(img):
    m = cv2.moments(img)
    if abs(m['mu02']) < 1e-2:
        return img.copy()
    skew = m['mu11']/m['mu02']
    M = np.float32([[1, skew, -0.5*SZ*skew], [0, 1, 0]])
    img = cv2.warpAffine(img,M,(SZ, SZ),flags=affine_flags)
    return img
def hog(img):
    gx = cv2.Sobel(img, cv2.CV_32F, 1, 0)
    gy = cv2.Sobel(img, cv2.CV_32F, 0, 1)
    mag, ang = cv2.cartToPolar(gx, gy)
    bins = np.int32(bin_n*ang/(2*np.pi))    # quantizing binvalues in (0...16)
    bin_cells = bins[:10,:10], bins[10:,:10], bins[:10,10:], bins[10:,10:]
    mag_cells = mag[:10,:10], mag[10:,:10], mag[:10,10:], mag[10:,10:]
    hists = [np.bincount(b.ravel(), m.ravel(), bin_n) for b, m in zip(bin_cells, mag_cells)]
    hist = np.hstack(hists)     # hist is a 64 bit vector
    return hist

img = cv2.imread('digits.png',0)
if img is None:
    raise Exception("we need the digits.png image from samples/data here !")


cells = [np.hsplit(row,100) for row in np.vsplit(img,50)]

train_cells = [ i[:50] for i in cells ]
test_cells = [ i[50:] for i in cells]

deskewed = [map(deskew,row) for row in train_cells]
hogdata = [map(hog,row) for row in deskewed]
trainData = np.float32(hogdata).reshape(-1,64)
responses = np.float32(np.repeat(np.arange(10),250)[:,np.newaxis])

svm = cv2.SVM()
svm.train(trainData,responses, params=svm_params)
svm.save('svm_data.dat')

Heres the digits.png введите описание изображения здесь

В результате я получил файл svm_data.dat. Но сейчас я не знаю, как реализовать модель. Допустим, я хочу прочитать этот номер здесь, введите описание изображения здесь

Кто-нибудь может мне помочь, пожалуйста?

1 ответ

Решение

Я собираюсь предположить, что под "как реализовать модель" вы подразумеваете "как предсказать метку для нового изображения".

Прежде всего, обратите внимание, что это не имеет ничего общего с сохраненным svm_data.dat по сути, если вы не хотите делать это в другом сценарии / сеансе, в этом случае вы можете перезагрузить свой обученный svm объект из файла.

При этом для прогнозирования новых данных требуется три шага:

  1. Если ваши новые данные чем-то отличаются от обучающих данных, предварительно обработайте их так, чтобы они соответствовали обучающим данным (см. Инвертирование и изменение размера ниже).

  2. Извлекать функции так же, как это было сделано для данных обучения.

  3. Используйте обученный классификатор, чтобы предсказать метку.

Для примера загруженного вами изображения это можно сделать следующим образом:

# Load the image
img_predict = cv2.imread('predict.png', 0)

# Preprocessing: this image is inverted compared to the training data
# Here it is inverted back
img_predict = np.invert(img_predict)

# Preprocessing: it also has a completely different size
# This resizes it to the same size as the training data
img_predict = cv2.resize(img_predict, (20, 20), interpolation=cv2.INTER_CUBIC)

# Extract the features
img_predict_ready = np.float32(hog(deskew(img_predict)))

# Reload the trained svm
# Not necessary if predicting is done in the same session as training
svm = cv2.SVM()
svm.load("svm_data.dat")

# Run the prediction
prediction = svm.predict(img_predict_ready)
print int(prediction)

Выход 0, как и ожидалось.

Обратите внимание, что очень важно сопоставить данные, которые вы хотите классифицировать, с данными, которые вы использовали для обучения. В этом случае пропуск шага изменения размера приведет к неправильной классификации изображения как 2,

Кроме того, более пристальный взгляд на изображение показывает, что оно все еще немного отличается от обучающих данных (больше фона, другое среднее значение), поэтому я не удивлюсь, если классификатор в конечном итоге будет работать немного хуже на таких изображениях по сравнению с тестовые данные, использованные в оригинальном уроке (который составлял только половину обучающих данных). Однако это зависит от того, насколько чувствительно извлечение объектов к различиям между тренировочными изображениями и вашими прогнозными изображениями.

Другие вопросы по тегам