2

I got an SVM for Handwritten Digit Recognition from the OpenCV Docs website. The utilization part I got from this link: How to implement .dat file for handwritten recognition using SVM in Python. I edited it to fit the code that I got from the website. Here is the code that I am using:

import cv2 as cv
import numpy as np
SZ=20
bin_n = 16 # Number of bins
affine_flags = cv.WARP_INVERSE_MAP|cv.INTER_LINEAR
def deskew(img):
    m = cv.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 = cv.warpAffine(img,M,(SZ, SZ),flags=affine_flags)
    return img
def hog(img):
    gx = cv.Sobel(img, cv.CV_32F, 1, 0)
    gy = cv.Sobel(img, cv.CV_32F, 0, 1)
    mag, ang = cv.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 = cv.imread('digits2.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)]
#First half is trainData, remaining is testData
train_cells = [ i[:50] for i in cells ]
test_cells = [ i[50:] for i in cells]
deskewed = [list(map(deskew,row)) for row in train_cells]
hogdata = [list(map(hog,row)) for row in deskewed]
trainData = np.float32(hogdata).reshape(-1,64)
responses = np.repeat(np.arange(10),250)[:,np.newaxis]
svm = cv.ml.SVM_create()
svm.setKernel(cv.ml.SVM_LINEAR)
svm.setType(cv.ml.SVM_C_SVC)
svm.setC(2.67)
svm.setGamma(5.383)
svm.train(trainData, cv.ml.ROW_SAMPLE, responses)
svm.save('svm_data.dat')
deskewed = [list(map(deskew,row)) for row in test_cells]
hogdata = [list(map(hog,row)) for row in deskewed]
testData = np.float32(hogdata).reshape(-1,bin_n*4)
result = svm.predict(testData)[1]
mask = result==responses
correct = np.count_nonzero(mask)

img_predict1 = cv.imread('predict2.png', 0)
img_predict2 = np.invert(img_predict1)
img_predict3 = cv.resize(img_predict2, (20, 20), interpolation=cv.INTER_CUBIC)
img_predict_ready = np.float32(hog(deskew(img_predict3)))
svm = cv.ml.SVM_load("svm_data.dat")
prediction = svm.predict(img_predict_ready)
print(int(prediction))

When I run it, the program is able to train a .dat file, but when trying to use that .dat file, it gives me this error:

Traceback (most recent call last):
  File "C:\Users\Austin\source\repos\SVMTEST2\SVMTEST2\SVMTRAIN.py", line 54, in <module>
    prediction = svm.predict(img_predict_ready)
cv2.error: OpenCV(4.2.0) C:\projects\opencv-python\opencv\modules\ml\src\svm.cpp:2013: error: (-215:Assertion failed) samples.cols == var_count && samples.type() == CV_32F in function 'cv::ml::SVMImpl::predict'

I am still very new to Python and wanted to try this out, so any help would be greatly appreciated, thank you! (please). (On Windows 10 using Visual Studio Community 2017).

The Utilization/Test Image, Image Used For Training

And here is the .dat file that comes out of the training part (hosted on GDrive): https://drive.google.com/file/d/1U9z0FGQ0FJ_3MV_p_5et6Lsebjl9e3DE/view?usp=sharing

slipperoo
  • 21
  • 3
  • Are you me?! I had this same issue months ago and never received an answer. I did, however, manage to adapt the code to work for me that I can share. Are you attempting to use the dat file for digit recognition or just learning the code/concepts? – Alan Cheung Jul 15 '20 at 19:39
  • @AlanCheung Am I you?! We’ll never know that for sure, but yes, I am attempting to use the dat file for digit recognition. If you could share the code it would be very helpful. If you post it as an answer I’ll mark it as the answer. :D – slipperoo Jul 15 '20 at 23:25
  • Unfortunately, the code that I have generates a new .dat file for shape recognition instead of digit recognition. I can still post it or link you to the GitHub, but I ended up abandoning the project for a little bit. For what it is worth, `var_count = 64` (this can be verified near the top of the dat file and the type was CV_32F (which you can use Panda to verify). – Alan Cheung Jul 16 '20 at 13:47
  • @AlanCheung It would be nice to have a link to the GitHub, I might be able to adapt it! So you’re saying the CV_32F should be changed to CV_64F? – slipperoo Jul 16 '20 at 16:05
  • @AlanCheung Are you still there? – slipperoo Jul 19 '20 at 18:13
  • Apologies, been away. Here is the link to the file. Hopefully it gets you started down the right path. https://github.com/alancheung/Python.Repository/blob/master/WandTracker/trainSvm.py – Alan Cheung Jul 19 '20 at 19:12
  • Much appreciated! – slipperoo Jul 19 '20 at 19:19
  • Unfortunately, the code didn't help, but thank you anyways! :D – slipperoo Jul 19 '20 at 19:39

0 Answers0