yahboom
HomeLearn
Solution
Blog
Online Store
About Us
EN/中文
Raspbot📖
1.First Trial and Installation
  • 1.1 Installation video
  • 1.2 First Trial
2.Remote control course
  • 2.1 APP control car
  • 2.2 IR control car
3.Preparation
  • 3.1 Preparation
  • 3.2 Run a code on JupyterLab
  • 3.5 TF card expand capacity
4.OpenCV Basic course
A.Getting started with OpenCV
  • 1.Introduction of OpenCV
  • 2.OpenCV image read and display
  • 3.OpenCV image write
  • 4.OpenCV image quality
  • 5.OpenCV pixel operation
B.OpenCV Geometric transformat
  • 1.Picture Zoom
  • 2.Picture Cut
  • 3.Picture Shift
  • 4.Picture Mirroring
  • 5.Affine Map
  • 6.Picture Rotation
  • 7.Perspective Transformation
C.OpenCV picture processing
  • 1.Grayscale processing
  • 2.Image Binarization
  • 3.Edge detection
  • 4.Drawing line segment
  • 5.Drawing rectangle circle
  • 6.Drawing text picture
D.OpenCV image beautification
  • 1.Histogram of color pictures
  • 2.Histogram equalization
  • 3.Image restoration
  • 4.Brightness enhancement
  • 5.Skin whitening
  • 6.Gaussian mean filtering
  • 7.Median filtering
E.OpenCV machine learning
  • 1.KNN recognition of handwritten numbers
  • 2.CNN recognition of handwritten numbers
  • 3.SVM recognition of handwritten numbers
5.Hardware Control course
  • 5.1 Drive buzzer
  • 5.2 Drive motor
  • 5.3 Drive servo
  • 5.4 Ultrasonic ranging
  • 5.5 Ultrasonic avoid
  • 5.6 Ultrasonic+IR avoid
  • 5.7 Tracking
  • 5.8 Restricting
  • 5.9 Drive LED
  • 5.10 IR control test
  • 5.11 IR control car
6.AI vision course
  • 6.1 Driver camera
  • 6.2 Color recognition
  • 6.3 HSV value test
  • 6.4 Camera color tracking
  • 6.5 Car color tracking
  • 6.6 Tensorflow object recognition
  • 6.7 QR code recognition
  • 6.8 QR code control
  • 6.9 Face detection
  • 6.10 Face tracking
  • 6.11 Autopilot
7.Battery and charging
  • Battery and charging
Download
  • APP(iOS/Android)
  • Code
  • Download image
  • Instruction manual
  • More Annex
Download ZIP
FAQ
  • 1、Raspbot-Raspberry Pi 4b version desktop connection WiFi method
  • 2、Can't connect your home WiFi
  • 3、How to check IIC function on Raspbot
  • 4、Gesture recognition cannot work normally.
  • 5、How to write image file into SD card

Welcome to Raspbot repository

3.SVM recognition of handwritten numbers


The process of SVM:

① Collect data: provide text files

② Prepare data: construct vector based on binary image

③ Analyze the data: visually inspect the image

④Training algorithm: adopt two different kernel functions, and use different settings for the radial basis kernel function to run the SMO algorithm

⑤Test algorithm: write a function to test different kernel functions and calculate the error rate

⑥ Using algorithm: SVM can be used in almost all classification problems. SVM itself is a second-class classifier. Applying SVM to multi-class problems requires some modifications to the code.

KNN vs SVM

Similarities:

Both are more classic machine learning classification algorithms, both belong to supervised learning algorithms.

Difference:

①KNN must consider each sample. SVM is to find a function to divide the sample to reach.

②The essence of SVM is to find weights.

③KNN cannot handle things with high-dimensions, and SVM can be used to handles high-dimension data.

④KNN possess complicated calculation, and SVM needs training process.

How to choose to use both?

1. Choose KNN scene:

l A. Low accuracy

l B. Fewer samples.

l C. Samples cannot be obtained at once.

2. Select the SVM scene:

l A. Need to improve the accuracy rate.

l B. There are many samples.

l c. The sample is fixed and does not change with time.

---------------------------------------------------- Dividing line ---------------------------------------

This project requires the installation of a Python library. The factory image provided by us has been installed, and users do not need to install it again.

sudo pip install pypng

sudo pip install sklearn

sudo pip install sklearn

sudo apt-get install python-matplotlib

------------------------------------------------- Dividing line --------------------------------------------

First, we need to pre-process the MNIST data and convert it to a png image.

Code path:

/home/pi/Yahboom_Project/Raspbot/1.OpenCV_course/05machine_learning/03SNM/03_1.MNIST.ipynb

Note:

In the image provided by us, the following code has been run, and the corresponding file has been generated.

If you need to run this code again, you need to delete the two files MSIST_data/test and train in this directory. Then, run the following code.

import struct
from array import array
import os
# Input pip install pypng command install this library
import png
 
trainimg = './MNIST_data/train-images.idx3-ubyte'
trainlabel = './MNIST_data/train-labels.idx1-ubyte'
testimg = './MNIST_data/t10k-images.idx3-ubyte'
testlabel = './MNIST_data/t10k-labels.idx1-ubyte'
trainfolder = './MNIST_data/train'
testfolder = './MNIST_data/test'
if not os.path.exists(trainfolder): os.makedirs(trainfolder)
if not os.path.exists(testfolder): os.makedirs(testfolder)
 
# open(File path, read-write format), used to open a file and return a file object
# rb means open the file with binary read mode
trimg = open(trainimg, 'rb')
teimg = open(testimg, 'rb')
trlab = open(trainlabel, 'rb')
telab = open(testlabel, 'rb')
 
# struct
struct.unpack(">IIII", trimg.read(16))
struct.unpack(">IIII", teimg.read(16))
struct.unpack(">II", trlab.read(8))
struct.unpack(">II", telab.read(8))
# The array module is an efficient array storage type implemented in Python
# All array members must be of the same type
# B unsigned byte type, b signed byte type
trimage = array("B", trimg.read())
teimage = array("B", teimg.read())
trlabel = array("b", trlab.read())
telabel = array("b", telab.read())
# The close method is used to close an opened file. After closing, the file cannot be read or written.
trimg.close()
teimg.close()
trlab.close()
telab.close()
# Define 10 subfolders for the training set and the test set, used to store all the numbers from 0 to 9, the folder names are 0-9
trainfolders = [os.path.join(trainfolder, str(i)) for i in range(10)]
testfolders = [os.path.join(testfolder, str(i)) for i in range(10)]
for dir in trainfolders:
    if not os.path.exists(dir):
        os.makedirs(dir)
for dir in testfolders:
    if not os.path.exists(dir):
        os.makedirs(dir)
# Start saving training image data
for (i, label) in enumerate(trlabel):
    filename = os.path.join(trainfolders[label], str(i) + ".png")
    #print("writing " + filename)
    with open(filename, "wb") as img:
        image = png.Writer(28, 28, greyscale=True)
        data = [trimage[(i*28*28 + j*28) : (i*28*28 + (j+1)*28)] for j in range(28)]
        image.write(img, data)
print("end write train image")
 
# Start saving testing image data
for (i, label) in enumerate(telabel):
    filename = os.path.join(testfolders[label], str(i) + ".png")
    #print("writing " + filename)
    with open(filename, "wb") as img:
        image = png.Writer(28, 28, greyscale=True)
        data = [teimage[(i*28*28 + j*28) : (i*28*28 + (j+1)*28)] for j in range(28)]
        image.write(img, data)
print("end write test image")

 Code path:

/home/pi/Yahboom_Project/Raspbot/1.OpenCV_course/05machine_learning/03SVM/ 03_2.SVM_training model.ipynb

from PIL import Image
import os
import sys
import numpy as np
import time
from sklearn import svm
from sklearn.externals import joblib
 
# Get all .png files in the specified path
def get_file_list(path):
    return [os.path.join(path, f) for f in os.listdir(path) if f.endswith(".png")]
 
# Parse the name of the .png image file
def get_img_name_str(imgPath):
    return imgPath.split(os.path.sep)[-1]
 
# Convert 28px*28px image data to 1*784 numpy vector
# Parameters: imgFile--image name such as: 1.png
# Return: 1*784 numpy vector
def img2vector(imgFile):
    # print("in img2vector func--para:{}".format(imgFile))
    img = Image.open(imgFile).convert('L')
    img_arr = np.array(img, 'i')  # 28px*28px grayscale image
    img_normalization = np.round(img_arr / 255)  #Normalize the gray value
    img_arr2 = np.reshape(img_normalization, (1, -1))  #1*784 matrix
    return img_arr2
 
# Read all data in a category and convert it into a matrix
# Parameters:
# basePath: The basic path where the image data is located
# MNIST-data/train/
# MNIST-data/test/
# cla: classification name
# 0,1,2,...,9
# Returns: all data of a certain category-[number of samples * (image width x image height)] matrix
def read_and_convert(imgFileList):
    dataLabel = []  # Storage class label
    dataNum = len(imgFileList)
    dataMat = np.zeros((dataNum, 784))  # dataNum*784 matrix
    for i in range(dataNum):
        imgNameStr = imgFileList[i]
        imgName = get_img_name_str(imgNameStr)  # Get the number of the current number.png
        # print("imgName: {}".format(imgName))
        classTag = imgNameStr.split(os.path.sep)[-2]
        # classTag = imgName.split(".")[0].split("_")[0]  # Get class label (number)
        #print(classTag)
        #print(imgNameStr)
        dataLabel.append(classTag)
        dataMat[i, :] = img2vector(imgNameStr)
    return dataMat, dataLabel
 
 
# Read training data
def read_all_data():
    cName = ['1', '2', '3', '4', '5', '6', '7', '8', '9']
    #path = sys.path[1]
    train_data_path = 'MNIST_data/train/0' # os.path.join(path, './MNIST_data/train/0')
    print(train_data_path)
    #train_data_path = "./MNIST_data/train/0"
    print('0')
    flist = get_file_list(train_data_path)
    #print(flist)
    dataMat, dataLabel = read_and_convert(flist)
    for c in cName:
        print(c)
        #train_data_path = os.path.join(path, './MNIST_data/train/') + c
        train_data_path = 'MNIST_data/train/' + c
        flist_ = get_file_list(train_data_path)
        dataMat_, dataLabel_ = read_and_convert(flist_)
        dataMat = np.concatenate((dataMat, dataMat_), axis=0)
        dataLabel = np.concatenate((dataLabel, dataLabel_), axis=0)
    # print(dataMat.shape)
    # print(len(dataLabel))
    return dataMat, dataLabel
 
'''
SVC parameter
svm.SVC(C=1.0,kernel='rbf',degree=3,gamma='auto',coef0=0.0,shrinking=True,probability=False,
tol=0.001,cache_size=200,class_weight=None,verbose=False,max_iter=-1,decision_function_shape='ovr',random_state=None)
C: C-SVC penalty parameter C, the default value is 1.0
kernel: Kernel function, default is rbf, it can be set to ‘linear’, ‘poly’, ‘rbf’, ‘sigmoid’, ‘precomputed’
0-linear: u'v
1-Polynomial: (gamma * u '* v + coef0) ^ degree
2-RBF function: exp (-gamma | u-v | ^ 2)
3-sigmoid: tanh (gamma * u '* v + coef0)
degree: The dimension of the polynomial poly function, which is 3 by default. It will be ignored when other kernel functions are selected. (Useless)
gamma: Kernel function parameters of ‘rbf’, ‘poly’ and ‘sigmoid’. The default is ‘auto’, then 1/n_features will be selected
coef0: constant term of the kernel function. Useful for ‘poly’ and ‘sigmoid’. (Useless)
probability: whether to use probability estimation, the default is False
shrinking: Whether to use shrinking heuristic method, the default is true
tol: the size of the error value for stopping training, the default is 1e-3
cache_size: The cache size of the core function cache, the default is 200
class_weight: The weight of the category, passed in the form of a dictionary. Set the parameter C of the first category to weight *C (C in C-SVC)
verbose: Allow redundant output.
max_iter: Maximum number of iterations. -1 is unlimited.
decision_function_shape: ‘ovo’, ‘ovr’ or None, default = None3 (select ovr, one-to-many)
random_state: seed value, int value when the data is shuffled
The main adjustment parameters are: C, kernel, degree, gamma, coef0
''' 
# Create a model
def create_svm(dataMat, dataLabel,path,decision='ovr'):
    clf = svm.SVC(C=1.0,kernel='rbf',decision_function_shape=decision)
    rf =clf.fit(dataMat, dataLabel)
    joblib.dump(rf, path)
    return clf
 
if __name__ == '__main__':
    # clf = svm.SVC(decision_function_shape='ovr')
    st = time.clock()
    dataMat, dataLabel = read_all_data()
    #path = sys.path[1]
    #model_path=os.path.join(path,'modelsvm.model')
    model_path = 'model/svm.model'
    create_svm(dataMat, dataLabel, model_path, decision='ovr')
    et = time.clock()
    print("Training spent {:.4f}s.".format((et - st)))


 This training process takes a long time, about four hours, please wait patiently until the time spent is printed. The following time range exceeds the maximum value of the variable and will be printed as a negative value, ignoring the warning.

image.png 

Here is the code to test the MNIST data set.

Code path:

 /home/pi/Yahboom_Project/1.OpenCV_course/05machine_learning/03SVM/ 03_3.SVM_MNIST.ipynb

# Test handwritten digits of MNIST data
import sys
import time
import svm
import os
from sklearn.externals import joblib
import sys
import time
from PIL import Image
import os
from sklearn.externals import joblib
import numpy as np
import matplotlib.pyplot as plt
 
# Get all .png files in the specified path
def get_file_list(path):
    return [os.path.join(path, f) for f in os.listdir(path) if f.endswith(".png")]
 
# Parse the name of the .png image file
def get_img_name_str(imgPath):
    return imgPath.split(os.path.sep)[-1]
 
# Convert 28px*28px image data to 1*784 numpy vector
# Parameter: imgFile--image name eg: 0_1.png
# Return: 1*784 numpy vector
def img2vector(imgFile):
    # print("in img2vector func--para:{}".format(imgFile))
    img = Image.open(imgFile).convert('L')
    img_arr = np.array(img, 'i')  # 28px*28px grayscale image
    img_normalization = np.round(img_arr / 255)  # Normalize the gray value
    img_arr2 = np.reshape(img_normalization, (1, -1))  #1*400 matrix
    return img_arr2
 
# Read all data of a category and convert it into a matrix
# Parameter:
#   basePath: the base path where the image data is located
#   MNIST-data / train /
#   MNIST-data / test /
#   cla: category name
#   0,1,2, ..., 9
# Return: all data of a certain category-[number of samples * (image width x image height)] matrix
 
def read_and_convert(imgFileList):
    dataLabel = []  
    dataNum = len(imgFileList)
    dataMat = np.zeros((dataNum, 784))  # dataNum*784 matrix
    for i in range(dataNum):
        imgNameStr = imgFileList[i]
        imgName = get_img_name_str(imgNameStr)  
        # print("imgName: {}".format(imgName))
        classTag = imgNameStr.split(os.path.sep)[-2]
        # classTag = imgName.split(".")[0].split("_")[0]  # Get class label (number)
        #print(classTag)
        #print(imgNameStr)
        dataLabel.append(classTag)
        dataMat[i, :] = img2vector(imgNameStr)
    return dataMat, dataLabel
 
def svmtest(model_path):
 
    tbasePath = "MNIST_data/test/"
    tcName = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
    tst = time.clock()
    allErrCount = 0
    allErrorRate = 0.0
    allScore = 0.0
    ErrCount=np.zeros(10,int)
    TrueCount=np.zeros(10,int)
    # Load the model
    clf = joblib.load(model_path)
    for tcn in tcName:
        testPath = tbasePath + tcn
        # print("class " + tcn + " path is: {}.".format(testPath))
        tflist = get_file_list(testPath)
        # tflist
        tdataMat, tdataLabel = read_and_convert(tflist)
        print("test dataMat shape: {0}, test dataLabel len: {1} ".format(tdataMat.shape, len(tdataLabel)))
        # print("test dataLabel: {}".format(len(tdataLabel)))
        pre_st = time.clock()
        preResult = clf.predict(tdataMat)
        pre_et = time.clock()
        print("Recognition  " + tcn + " spent {:.4f}s.".format((pre_et - pre_st)))
        # print("predict result: {}".format(len(preResult)))
        errCount = len([x for x in preResult if x != tcn])
        ErrCount[int(tcn)]=errCount
        TrueCount[int(tcn)]= len(tdataLabel)-errCount
        print("errorCount: {}.".format(errCount))
        allErrCount += errCount
        score_st = time.clock()
        score = clf.score(tdataMat, tdataLabel)
        score_et = time.clock()
        print("computing score spent {:.6f}s.".format(score_et - score_st))
        allScore += score
        print("score: {:.6f}.".format(score))
        print("error rate is {:.6f}.".format((1 - score)))
 
    tet = time.clock()
    print("Testing All class total spent {:.6f}s.".format(tet - tst))
    print("All error Count is: {}.".format(allErrCount))
    avgAccuracy = allScore / 10.0
    print("Average accuracy is: {:.6f}.".format(avgAccuracy))
    print("Average error rate is: {:.6f}.".format(1 - avgAccuracy))
    print("number"," TrueCount"," ErrCount")
    for tcn in tcName:
        tcn=int(tcn)
        print(tcn,"     ",TrueCount[tcn],"      ",ErrCount[tcn])
    plt.figure(figsize=(12, 6))
    x=list(range(10))
    plt.plot(x,TrueCount, color='green', label="TrueCount")  # Mark right s as red  
    plt.plot(x,ErrCount, color='red', label="ErrCount") #Mark errors as red    plt.legend(loc='best')  #Show the position of the legend, here is the lower right
    plt.title('Projects')
    plt.xlabel('number')    # x-axis label
    plt.ylabel('count')      # y-axis label
    plt.xticks(np.arange(10), ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'])
    plt.show()
 
 
if __name__ == '__main__':
    model_path='model/svm.model'
    svmtest(model_path)

image.png 

According to the above figure, we can see that only the number 7 has a high recognition rate.

Code path: 

/home/pi/Yahboom_Project/1.OpenCV_course/05machine_learning/03SVM/ 03_4.SVM.ipynb

from PIL import Image
import sys
import time
import os
from sklearn.externals import joblib
import numpy as np
import matplotlib.pyplot as plt
 
# Get all .png files in the specified path
def get_file_list(path):
    return [os.path.join(path, f) for f in os.listdir(path) if f.endswith(".png")]
 
# Parse the name of the .png image file
def get_img_name_str(imgPath):
    return imgPath.split(os.path.sep)[-1]
 
# Convert 28px*28px image data to 1*784 numpy vector
# Parameter: imgFile--image name eg: 0_1.png
# Return: 1*784 numpy vector
def img2vector(imgFile):
    # print("in img2vector func--para:{}".format(imgFile))
    img = Image.open(imgFile).convert('L')
    img_arr = np.array(img, 'i')  #28px*28px grayscale image
    img_normalization = np.round(img_arr / 255)  #Normalize the gray value
    img_arr2 = np.reshape(img_normalization, (1, -1))  # 1*400 matrix
    return img_arr2
 
# Read all data of a category and convert it into a matrix
# Parameter:
#    basePath: The basic path where the image data is located
#       MNIST-data/train/
#       MNIST-data/test/
#    cla: classification name
#       0,1,2,...,9
# Returns: all data of a certain category-[number of samples * (image width x image height)] matrix
def read_and_convert(imgFileList):
    dataLabel = []  # Storage class label
    dataNum = len(imgFileList)
    dataMat = np.zeros((dataNum, 784))  # dataNum*784 matrix
    for i in range(dataNum):
        imgNameStr = imgFileList[i]
        imgName = get_img_name_str(imgNameStr)  
        # print("imgName: {}".format(imgName))
        classTag = imgNameStr.split(os.path.sep)[-2]
        # classTag = imgName.split(".")[0].split("_")[0]  # Get class label (number)
        #print(classTag)
        #print(imgNameStr)
        dataLabel.append(classTag)
        dataMat[i, :] = img2vector(imgNameStr)
    return dataMat, dataLabel
 
def svmtest(model_path):
    # Picture path
    tbasePath = "image/"
    # Load the model
    clf = joblib.load(model_path)
    # Get file list
    tflist = get_file_list(tbasePath)
    # tflist
    tdataMat, tdataLabel = read_and_convert(tflist)
    print("test dataMat shape: {0}, test dataLabel len: {1} ".format(tdataMat.shape, len(tdataLabel)))
    pre_st = time.clock()
    # forecast result
    preResult = clf.predict(tdataMat) 
    pre_et = time.clock()
    print("Recognition  1 spent {:.4f}s.".format((pre_et - pre_st)))
    print("predict result: {}".format(len(preResult)))
    score = clf.score(tdataMat, tdataLabel)
 
if __name__ == '__main__':
    model_path='model/svm.model'
    svmtest(model_path)

 Original picture:

image.png 

Result, as shown below.

image.png 



CNN recognition of handwritten numbers
Drive buzzer

COMPANY

  • About us
  • Team Style
  • Blog

LEARNING & EXPLORATION

  • Tutorials
  • Edge AI hardware
  • Educational robots
  • Embedded intelligent hardware

WHERE TO BUY

  • Yahboom Online Store
  • Amazon
  • Alibaba
  • AliExpress
  • Mercado

TECHNOLOGY SUPPORT

  • Email: support@yahboom.com

BE A DISTRIBUTOR

  • Email: sales@yahboom.com
QR Code
QR Code

Copyright © 2017-2026 Yahboom. All Rights Reserved.

EN/中文