Scikit-recognize SVM character recognition

I want to make a program recognize a figure in an image. I follow the tutorial at scikit learn .

I can train and fit the svm classifier as shown below.

First I import the libraries and dataset

from sklearn import datasets, svm, metrics digits = datasets.load_digits() n_samples = len(digits.images) data = digits.images.reshape((n_samples, -1)) 

Secondly, I create an SVM model and train it with a dataset.

 classifier = svm.SVC(gamma = 0.001) classifier.fit(data[:n_samples], digits.target[:n_samples]) 

And then, I try to read my own image and use the predict() function to recognize the digit.

Here is my image: enter image description here

I convert the image to (8, 8) and then convert it to a 1D array .

 img = misc.imread("w1.jpg") img = misc.imresize(img, (8, 8)) img = img[:, :, 0] 

Finally, when I print the forecast , it returns [1]

 predicted = classifier.predict(img.reshape((1,img.shape[0]*img.shape[1] ))) print predicted 

No matter what I take pictures of other users, it still returns [1]

enter image description here enter image description here

When I print out the " default dataset from number 9, it looks like this: enter image description here

My image number is "9":

enter image description here

You can see that the nonzero number is quite large for my image.

I do not know why. I am looking for help to solve my problem. Thanks

+5
source share
7 answers

My best bet would be that there is a problem with your data types and array forms.

It looks like you are training in numpy arrays that are of type np.float64 (or maybe np.float32 on 32-bit systems, I don’t remember) and where each image has a shape (64,) .

Meanwhile, your prediction input image after the resize operation in your code is of type uint8 and shape (1, 64) .

First, I would try changing the shape of your input image, since dtype conversions often work the way you expected. So change this line:

predicted = classifier.predict(img.reshape((1,img.shape[0]*img.shape[1] )))

:

predicted = classifier.predict(img.reshape(img.shape[0]*img.shape[1]))

If this is not fixed, you can always try to remake the data type, as well as

img = img.astype(digits.images.dtype) .

Hope this helps. Debugging through a proxy is much more difficult than actually sitting in front of your computer :)

Edit: according to the SciPy documentation, the training data contains integer values ​​from 0 to 16. The values ​​in your original image should be scaled so that they correspond to the same interval. ( http://scikit-learn.org/stable/modules/generated/sklearn.datasets.load_digits.html#sklearn.datasets.load_digits )

+5
source

1) You need to create your own set of workouts - based on data similar to the fact that you will make predictions. The datasets.load_digits() call to scikit-learn loads a pre-processed version of the MNIST Digits dataset, which, as far as we know, can have very different images for the ones you are trying to recognize.

2) You need to set the parameters of your classifier correctly. Calling svm.SVC(gamma = 0.001) is just choosing an arbitrary gamma parameter in SVC, which might not be the best option. In addition, you do not configure the C parameter, which is very important for SVM. I would say that this is one of the reasons why your conclusion is "always 1".

3) Regardless of which final settings you choose for your model, you need to use a cross-validation scheme to ensure that the algorithm efficiently learns

There is a lot of machine learning theory, but as a good start, I would recommend taking a look at SVM - scikit-learn for a more detailed description of how the implementation of SVC works with patients, and GridSearchCV for a simple method for setting parameters.

+3
source

This is just an assumption, but ... Sk-Learn training set - black numbers on a white background . And you are trying to predict numbers, white on a black background ...

I think you need to either train in your training kit or train with the negative version of your photos.

I hope this help!

+1
source

If you look at: http://scikit-learn.org/stable/modules/generated/sklearn.datasets.load_digits.html#sklearn.datasets.load_digits

you can see that each point in the matrix is ​​0-16.

You can try to convert image values ​​between 0-16. I did this and now the prediction works well for the number 9, but not for the numbers 8 and 6. This no longer gives 1.

 from sklearn import datasets, svm, metrics import cv2 import numpy as np # Load digit database digits = datasets.load_digits() n_samples = len(digits.images) data = digits.images.reshape((n_samples, -1)) # Train SVM classifier classifier = svm.SVC(gamma = 0.001) classifier.fit(data[:n_samples], digits.target[:n_samples]) # Read image "9" img = cv2.imread("w1.jpg") img = img[:,:,0]; img = cv2.resize(img, (8, 8)) # Normalize the values in the image to 0-16 minValueInImage = np.min(img) maxValueInImage = np.max(img) normaliizeImg = np.floor(np.divide((img - minValueInImage).astype(np.float),(maxValueInImage-minValueInImage).astype(np.float))*16) # Predict predicted = classifier.predict(normaliizeImg.reshape((1,normaliizeImg.shape[0]*normaliizeImg.shape[1] ))) print predicted 
+1
source

I solved this problem using the following methods:

  • check the number of attributes is too large or too small.

  • check the scale of your gray value, I go to [0.16].

  • check the data type, I changed it to uint8.

  • Check the amount of training data, too little or not.

Hope this helps. ^. ^

+1
source

Hi, in addition to @carrdelling, I will add that you can use the same set of workouts if you normalize your images to have the same range of values. For example, you can use your data (1 if> 0, 0 else), or you can divide by the maximum image intensity to have an arbitrary interval [0; 1].

0
source

You probably want to extract the functions that match your dataset from the images and prepare your model for them. One example that I copied from here.

surf = cv2.SURF(400) kp, des = surf.detectAndCompute(img,None)

But SURF functions may not be the most useful or important for your dataset and training task. You should also try others, such as HOG or others.

Remember that at a higher level, the functions you retrieve, the more general / error-resistant your model will be in an invisible image. However, you can sacrifice accuracy in your well-known samples and test cases.

0
source

All Articles