C/C++开发,opencv-ml库学习,支持向量机(SVM)应用

目录

一、OpenCV支持向量机(SVM)模块

1.1 openCV的机器学习库

1.2 SVM(支持向量机)模块

1.3 支持向量机(SVM)应用步骤

二、支持向量机(SVM)应用示例

 2.1  训练及验证数据获取

2.2 训练及验证数据加载

2.3 SVM(支持向量机)训练及验证,输出svm模型

2.4 SVM(支持向量机)实时识别应用

三、完整代码编译

3.1 OpenCV+MinGW的MakeFile编译

3.2 OpenCV+vc2015+cmake编译

3.3 执行效果

3.4 附件,main.cpp全文


一、OpenCV支持向量机(SVM)模块

1.1 openCV的机器学习库

        OpenCV-ml库是OpenCV(开放源代码计算机视觉库)中的机器学习模块,常用于分类和回归问题,它是 OpenCV 众多modules下的一个模块。

        该模块提供了一系列常见的统计模型和分类算法,用于进行各种机器学习任务。以下是关于OpenCV-ml库的一些主要功能和特点:

  1. 丰富的算法支持:OpenCV-ml库包含了多种机器学习算法,如支持向量机(SVM)、决策树、Boosting方法、K近邻(KNN)、随机森林等。这些算法可以用于分类、回归、聚类等多种任务。
  2. 易于使用:OpenCV-ml库提供了简洁的API接口,使得开发者能够方便地调用各种机器学习算法。同时,它也支持多种数据格式,方便用户导入和处理数据。
  3. 高效性:OpenCV-ml库经过优化,能够高效地处理大规模数据集,并且具有较快的运算速度。这使得它能够满足实时处理和分析的需求。
  4. 与OpenCV其他模块的集成:OpenCV-ml库与OpenCV的其他模块(如imgproc、features2d等)紧密集成,可以方便地进行图像处理和特征提取,然后将提取的特征用于机器学习任务。
1.2 SVM(支持向量机)模块

        OpenCV 的 SVM(支持向量机)模块是 OpenCV 机器学习库中的一个重要组成部分,它实现了支持向量机算法,用于解决分类和回归问题。支持向量机是一种监督学习模型,广泛应用于各种领域,特别是在图像分类和识别任务中。

        OpenCV 的 SVM 模块提供了灵活的参数设置和多种核函数选择,以适应不同的数据集和问题。以下是一些关于 OpenCV SVM 模块的主要特点:

  1. 多种核函数:支持线性核、多项式核、径向基函数(RBF)核和 Sigmoid 核等,可以根据问题的特性选择合适的核函数。

  2. 参数调整:可以通过调整 SVM 的参数,如 C 值(错误项的惩罚系数)和 gamma 值(对于 RBF、Poly 和 Sigmoid 核函数),来优化模型的性能。

  3. 多类分类支持:通过“一对一”或“一对多”的方式,可以处理多类分类问题。

  4. 概率估计:SVM 可以输出类别的概率估计,这对于某些应用(如置信度评估)非常有用。

  5. 易于使用:OpenCV 提供了简洁的 API,使得 SVM 的训练和测试过程相对简单。

1.3 支持向量机(SVM)应用步骤

        在OpenCV中,使用支持向量机(SVM)进行预测涉及几个步骤。首先,获得训练数据,用于训练一个SVM模型,然后使用该模型对新的、未见过的数据进行预测。

    使用svm模型,包含必要的头文件:

#include <opencv2/opencv.hpp>  
#include <opencv2/ml/ml.hpp>  

   1) 准备训练和测试数据:

    你需要为SVM准备训练和测试数据。这些数据通常是特征向量,存储在cv::Mat对象中。每个特征向量对应一个标签(分类的类别)。
    2)创建和训练SVM模型:
    使用OpenCV的cv::ml::SVM类来创建SVM模型。然后,使用train方法来训练模型。
   3) 进行预测:
    使用训练好的模型对新数据进行预测。这通常涉及将新数据作为输入传递给模型的predict方法。

二、支持向量机(SVM)应用示例

 2.1  训练及验证数据获取

        以下展示如何使用OpenCV的机器学习模块来实现一个基于SVM的手写数字识别器。首先前往网站:MNIST handwritten digit database, Yann LeCun, Corinna Cortes and Chris Burges,下载MNIST database,用于实现一个SVM的手写数字识别模型训练及验证。

        下载完成后,进行解压操作:

        解压后是idx1-ubyteidx3-ubyte 是两种常见的标签编码格式,主要用于图像分割任务中。它们都是用来表示图像中每个像素所属类别的标签图像(也称为掩码或mask)。

  1. idx1-ubyte:

    • idx: 表示这是一个索引图像。
    • 1: 表示每个像素用一个字节(8位)来表示,且这些值从0开始,通常是连续的整数。
    • ubyte: 表示无符号字节类型,其值的范围是0到255。在idx1-ubyte格式中,通常会将0用作背景或未标记的类别,而其他值则用于表示不同的分割区域或类别。
  2. idx3-ubyte:

    • idx: 同样表示这是一个索引图像。
    • 3: 这里并不是指每个像素用3个字节来表示,而是指每个像素用一个字节来表示,但值的范围是从0到255,通常用来表示256个不同的类别(包括0作为背景或未标记的类别)。注意,虽然名为idx3,但实际上它并不是用3个字节来存储每个像素的值。
    • ubyte: 同样表示无符号字节类型。

        在图像分割任务中,这些标签图像通常与原始RGB图像一起使用。RGB图像用于显示给人类观察者或作为模型的输入,而标签图像则用于训练模型或评估模型的性能。

2.2 训练及验证数据加载

        idx3-ubyte 文件通常与 MNIST 数据集相关联,这是一个大型的手写数字数据库,经常用于机器学习和深度学习中的图像识别任务。MNIST 数据集包含两个文件:train-images-idx3-ubytetrain-labels-idx1-ubyte(用于训练),以及 t10k-images-idx3-ubytet10k-labels-idx1-ubyte(用于测试)。这些文件使用特定的二进制格式存储图像和标签。

        通过两个函数来读取手写图像数据集和手写图像数据对应的标签(每个标签都是一个 0 到 9 之间的整数,表示对应图像中的手写数字)。

//大小端转换
int intReverse(int num)
{return (num>>24|((num&0xFF0000)>>8)|((num&0xFF00)<<8)|((num&0xFF)<<24));
}//读取手写图像数据集
cv::Mat read_mnist_image(const std::string fileName) {int magic_number = 0;int number_of_images = 0;int img_rows = 0;int img_cols = 0;cv::Mat DataMat;std::ifstream file(fileName, std::ios::binary);if (file.is_open()){std::cout << "open images file: "<< fileName << std::endl;file.read((char*)&magic_number, sizeof(magic_number));//formatfile.read((char*)&number_of_images, sizeof(number_of_images));//images numberfile.read((char*)&img_rows, sizeof(img_rows));//img rowsfile.read((char*)&img_cols, sizeof(img_cols));//img colsmagic_number = intReverse(magic_number);number_of_images = intReverse(number_of_images);img_rows = intReverse(img_rows);img_cols = intReverse(img_cols);std::cout << "format:" << magic_number<< " img num:" << number_of_images<< " img row:" << img_rows<< " img col:" << img_cols << std::endl;std::cout << "read img data" << std::endl;DataMat = cv::Mat::zeros(number_of_images, img_rows * img_cols, CV_32FC1);unsigned char temp = 0;for (int i = 0; i < number_of_images; i++) {for (int j = 0; j < img_rows * img_cols; j++) {file.read((char*)&temp, sizeof(temp));//svm data is CV_32FC1float pixel_value = float(temp);DataMat.at<float>(i, j) = pixel_value;}}std::cout << "read img data finish!" << std::endl;}file.close();return DataMat;
}
//读取手写标签
cv::Mat read_mnist_label(const std::string fileName) {int magic_number;int number_of_items;cv::Mat LabelMat;std::ifstream file(fileName, std::ios::binary);if (file.is_open()){std::cout << "open label file: "<< fileName << std::endl;file.read((char*)&magic_number, sizeof(magic_number));file.read((char*)&number_of_items, sizeof(number_of_items));magic_number = intReverse(magic_number);number_of_items = intReverse(number_of_items);std::cout << "format:" << magic_number << "  ;label_num:" << number_of_items << std::endl;std::cout << "read Label data" << std::endl;//data type:CV_32SC1,channel:1LabelMat = cv::Mat::zeros(number_of_items, 1, CV_32SC1);for (int i = 0; i < number_of_items; i++) {unsigned char temp = 0;file.read((char*)&temp, sizeof(temp));LabelMat.at<unsigned int>(i, 0) = (unsigned int)temp;}std::cout << "read label data finish!" << std::endl;}file.close();return LabelMat;
}
2.3 SVM(支持向量机)训练及验证,输出svm模型

        1)加载训练图像数据和标签数据,采用cv::Mat存储,图像数据虚归一化;

        2)创建svm模型,设置svm模型的各关联参数,不同参数设置,对应模型精度有较大影响;

        3)加载测试图像数据和标签数据,采用cv::Mat存储,图像数据虚归一化;

        4)采用测试图像数据验证已经训练好的svm模型,获得测试推演结果;

        5)通过测试结果和已有的标签数据进行校对,验证该模型精度。

        6)将训练好的模型保持输出。便于后续用于实时识别应用。

//change path for real paths
std::string trainImgFile = "D:\\workForMy\\OpenCVLib\\opencv_demo\\opencv_ml01\\train-images.idx3-ubyte";
std::string trainLabeFile = "D:\\workForMy\\OpenCVLib\\opencv_demo\\opencv_ml01\\train-labels.idx1-ubyte";
std::string testImgFile = "D:\\workForMy\\OpenCVLib\\opencv_demo\\opencv_ml01\\t10k-images.idx3-ubyte";
std::string testLabeFile = "D:\\workForMy\\OpenCVLib\\opencv_demo\\opencv_ml01\\t10k-labels.idx1-ubyte";void train_SVM()
{//read train images, data type CV_32FC1cv::Mat trainingData = read_mnist_image(trainImgFile);//images data normalizationtrainingData = trainingData/255.0;std::cout << "trainingData.size() = " << trainingData.size() << std::endl; //read train label, data type CV_32SC1cv::Mat labelsMat = read_mnist_label(trainLabeFile);std::cout << "labelsMat.size() = " << labelsMat.size() << std::endl; std::cout << "trainingData & labelsMat finish!" << std::endl;  //create SVM modelcv::Ptr<cv::ml::SVM> svm = cv::ml::SVM::create();  //set svm args,type and KernelTypessvm->setType(cv::ml::SVM::C_SVC);  svm->setKernel(cv::ml::SVM::POLY);  //KernelTypes POLY is need set gamma and degreesvm->setGamma(3.0);svm->setDegree(2.0);//Set iteration termination conditions, maxCount is importancesvm->setTermCriteria(cv::TermCriteria(cv::TermCriteria::EPS | cv::TermCriteria::COUNT, 1000, 1e-8)); std::cout << "create SVM object finish!" << std::endl;  std::cout << "trainingData.rows = " << trainingData.rows << std::endl; std::cout << "trainingData.cols = " << trainingData.cols << std::endl; std::cout << "trainingData.type() = " << trainingData.type() << std::endl; // svm model train svm->train(trainingData, cv::ml::ROW_SAMPLE, labelsMat);  std::cout << "SVM training finish!" << std::endl; // svm model test  cv::Mat testData = read_mnist_image(testImgFile);//images data normalizationtestData = testData/255.0;std::cout << "testData.rows = " << testData.rows << std::endl; std::cout << "testData.cols = " << testData.cols << std::endl; std::cout << "testData.type() = " << testData.type() << std::endl; //read test label, data type CV_32SC1cv::Mat testlabel = read_mnist_label(testLabeFile);cv::Mat testResp;float response = svm->predict(testData,testResp); // std::cout << "response = " << response << std::endl; testResp.convertTo(testResp,CV_32SC1);int map_num = 0;for (int i = 0; i <testResp.rows&&testResp.rows==testlabel.rows; i++){if (testResp.at<int>(i, 0) == testlabel.at<int>(i, 0)){map_num++;}// else{// 	std::cout << "testResp.at<int>(i, 0) " << testResp.at<int>(i, 0) << std::endl;// 	std::cout << "testlabel.at<int>(i, 0) " << testlabel.at<int>(i, 0) << std::endl;// }}float proportion  = float(map_num) / float(testResp.rows);std::cout << "map rate: " << proportion * 100 << "%" << std::endl;std::cout << "SVM testing finish!" << std::endl; //save svm modelsvm->save("mnist_svm.xml");
}
2.4 SVM(支持向量机)实时识别应用

        将t10k-images.idx3-ubyte处理成图片数据,用于svm模型调用示例,本文主要是通过一段python代码,将t10k-images.idx3-ubyte另存为一张张手写图片。

import numpy as np 
import os 
from PIL import Image  
from struct import unpack  def read_idx3_ubyte(filename):  with open(filename, 'rb') as f:  magic, num_images, rows, cols = unpack('>IIII', f.read(16))  buf = f.read()  data = np.frombuffer(buf, dtype=np.uint8).reshape((num_images, rows, cols))  return data  def save_images_as_png(idx3_file, output_dir, prefix='image'):  images = read_idx3_ubyte(idx3_file)  for i, image in enumerate(images):  image_pil = Image.fromarray(image, 'L')  # 'L' 表示灰度模式  filename = f"{output_dir}/{prefix}_{i}.png"  image_pil.save(filename)  # 使用示例  
# idx3_file = 'train-images.idx3-ubyte'  
# output_dir = 'train-images' 
# if not os.path.exists(output_dir):#检查目录是否存在
# 	os.makedirs(output_dir)#如果不存在则创建目录
# save_images_as_png(idx3_file, output_dir)idx3_file = 't10k-images.idx3-ubyte'  
output_dir = 't10k-images' 
if not os.path.exists(output_dir):#检查目录是否存在os.makedirs(output_dir)#如果不存在则创建目录
save_images_as_png(idx3_file, output_dir)

        在获得图片数据后,将加载这些图片,和上述已保存的svm模型(mnist_svm.xml),实现模型调用验证。

void prediction(const std::string fileName,cv::Ptr<cv::ml::SVM> svm)
{//read img 28*28 sizecv::Mat image = cv::imread(fileName, cv::IMREAD_GRAYSCALE);//uchar->float32image.convertTo(image, CV_32F);//image data normalizationimage = image / 255.0;//28*28 -> 1*784image = image.reshape(1, 1);//预测图片float ret = svm->predict(image);std::cout << "predict val = "<< ret << std::endl;
}std::string imgDir = "D:\\workForMy\\OpenCVLib\\opencv_demo\\opencv_ml01\\t10k-images\\";
std::string ImgFiles[5] = {"image_0.png","image_10.png","image_20.png","image_30.png","image_40.png",};
void predictimgs()
{//load svm modelcv::Ptr<cv::ml::SVM> svm = cv::ml::StatModel::load<cv::ml::SVM>("mnist_svm.xml");for (size_t i = 0; i < 5; i++){prediction(imgDir+ImgFiles[i],svm);}
}

三、完整代码编译

3.1 OpenCV+MinGW的MakeFile编译

        本文是采用win系统下,opencv采用MinGW编译的静态库(C/C++开发,win下OpenCV+MinGW编译环境搭建_opencv mingw-CSDN博客),建立makefile:

#/bin/sh
#win32
CX= g++ -DWIN32 
#linux
#CX= g++ -Dlinux BIN 		:= ./
TARGET      := opencv_ml01.exe
FLAGS		:= -std=c++11 -static
SRCDIR 		:= ./
#INCLUDES
INCLUDEDIR 	:= -I"../../opencv_MinGW/include" -I"./"
#-I"$(SRCDIR)"
staticDir   := ../../opencv_MinGW/x64/mingw/staticlib/
#LIBDIR		:= $(staticDir)/libopencv_world460.a\
#			   $(staticDir)/libade.a \
#			   $(staticDir)/libIlmImf.a \
#			   $(staticDir)/libquirc.a \
#			   $(staticDir)/libzlib.a \
#			   $(wildcard $(staticDir)/liblib*.a) \
#			   -lgdi32 -lComDlg32 -lOleAut32 -lOle32 -luuid 
#opencv_world放弃前,然后是opencv依赖的第三方库,后面的库是MinGW编译工具的库LIBDIR 	    := -L $(staticDir) -lopencv_world460 -lade -lIlmImf -lquirc -lzlib \-llibjpeg-turbo -llibopenjp2 -llibpng -llibprotobuf -llibtiff -llibwebp \-lgdi32 -lComDlg32 -lOleAut32 -lOle32 -luuid 
source		:= $(wildcard $(SRCDIR)/*.cpp) $(TARGET) :$(CX) $(FLAGS) $(INCLUDEDIR) $(source)  -o $(BIN)/$(TARGET) $(LIBDIR)clean:rm  $(BIN)/$(TARGET)

        编译如下:

3.2 OpenCV+vc2015+cmake编译

        第二种编译,本文采用了vs2015 x64编译了opencv库(C/C++开发,opencv在win下安装及应用_windows安装opencv c++-CSDN博客)。

        建立cmake文件:

# CMake 最低版本号要求
cmake_minimum_required (VERSION 2.8)
# 项目信息
project (opencv_test)
#
message(STATUS "windows compiling...")
add_definitions(-D_PLATFORM_IS_WINDOWS_)
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd")
set(WIN_OS true)#
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)# 指定源文件的目录,并将名称保存到变量
SET(source_h#)SET(source_cpp#${PROJECT_SOURCE_DIR}/main.cpp)#头文件目录
include_directories(${PROJECT_SOURCE_DIR}/../../opencv_VC/include)set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4819")add_definitions("-D_CRT_SECURE_NO_WARNINGS""-D_WINSOCK_DEPRECATED_NO_WARNINGS""-DNO_WARN_MBCS_MFC_DEPRECATION""-DWIN32_LEAN_AND_MEAN"
)link_directories(${PROJECT_SOURCE_DIR}/../../opencv_VC/x64/vc14/bin${PROJECT_SOURCE_DIR}/../../opencv_VC/x64/vc14/lib)if (CMAKE_BUILD_TYPE STREQUAL "Debug")set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${PROJECT_SOURCE_DIR})
# 指定生成目标
add_executable(opencv_testd ${source_h} ${source_cpp})else(CMAKE_BUILD_TYPE)set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${PROJECT_SOURCE_DIR})
# 指定生成目标
add_executable(opencv_test ${source_h} ${source_cpp})target_link_libraries(opencv_test opencv_world460.lib opencv_img_hash460.lib)endif (CMAKE_BUILD_TYPE)# mkdir build_win
# cd build_win
# cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_BUILD_TYPE=Release ..
# msbuild opencv_test.sln /p:Configuration="Release" /p:Platform="x64"

启动vs2015 x64的命令工具(使前面配置的环境变量生效),进入main.cpp文件目录,编译如下:

mkdir build_win
cd build_win
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_BUILD_TYPE=Release ..
msbuild opencv_test.sln /p:Configuration="Release" /p:Platform="x64"

        编译输出大致如下:

3.3 执行效果

        【1】OpenCV+MinGW+makefile编译程序执行输出,准确率达到98%以上(PS,大家可尝试去调设SVM模型的参数设置,看怎样设置可以获得更高的准确率)

        通过模型调用识别图片全OK(呵呵,毕竟是测试集内的图片数据)

【2】opencv+vc2015+cmake编译程序执行输出,同样能到达效果。

3.4 附件,main.cpp全文
#include <opencv2/opencv.hpp>  
#include <opencv2/ml/ml.hpp>  
#include <opencv2/imgcodecs.hpp>
#include <iostream>  
#include <vector>  
#include <iostream>
#include <fstream>int intReverse(int num)
{return (num>>24|((num&0xFF0000)>>8)|((num&0xFF00)<<8)|((num&0xFF)<<24));
}std::string intToString(int num)
{char buf[32]={0};itoa(num,buf,10);return std::string(buf);
}cv::Mat read_mnist_image(const std::string fileName) {int magic_number = 0;int number_of_images = 0;int img_rows = 0;int img_cols = 0;cv::Mat DataMat;std::ifstream file(fileName, std::ios::binary);if (file.is_open()){std::cout << "open images file: "<< fileName << std::endl;file.read((char*)&magic_number, sizeof(magic_number));//formatfile.read((char*)&number_of_images, sizeof(number_of_images));//images numberfile.read((char*)&img_rows, sizeof(img_rows));//img rowsfile.read((char*)&img_cols, sizeof(img_cols));//img colsmagic_number = intReverse(magic_number);number_of_images = intReverse(number_of_images);img_rows = intReverse(img_rows);img_cols = intReverse(img_cols);std::cout << "format:" << magic_number<< " img num:" << number_of_images<< " img row:" << img_rows<< " img col:" << img_cols << std::endl;std::cout << "read img data" << std::endl;DataMat = cv::Mat::zeros(number_of_images, img_rows * img_cols, CV_32FC1);unsigned char temp = 0;for (int i = 0; i < number_of_images; i++) {for (int j = 0; j < img_rows * img_cols; j++) {file.read((char*)&temp, sizeof(temp));//svm data is CV_32FC1float pixel_value = float(temp);DataMat.at<float>(i, j) = pixel_value;}}std::cout << "read img data finish!" << std::endl;}file.close();return DataMat;
}cv::Mat read_mnist_label(const std::string fileName) {int magic_number;int number_of_items;cv::Mat LabelMat;std::ifstream file(fileName, std::ios::binary);if (file.is_open()){std::cout << "open label file: "<< fileName << std::endl;file.read((char*)&magic_number, sizeof(magic_number));file.read((char*)&number_of_items, sizeof(number_of_items));magic_number = intReverse(magic_number);number_of_items = intReverse(number_of_items);std::cout << "format:" << magic_number << "  ;label_num:" << number_of_items << std::endl;std::cout << "read Label data" << std::endl;//data type:CV_32SC1,channel:1LabelMat = cv::Mat::zeros(number_of_items, 1, CV_32SC1);for (int i = 0; i < number_of_items; i++) {unsigned char temp = 0;file.read((char*)&temp, sizeof(temp));LabelMat.at<unsigned int>(i, 0) = (unsigned int)temp;}std::cout << "read label data finish!" << std::endl;}file.close();return LabelMat;
}//change path for real paths
std::string trainImgFile = "D:\\workForMy\\OpenCVLib\\opencv_demo\\opencv_ml01\\train-images.idx3-ubyte";
std::string trainLabeFile = "D:\\workForMy\\OpenCVLib\\opencv_demo\\opencv_ml01\\train-labels.idx1-ubyte";
std::string testImgFile = "D:\\workForMy\\OpenCVLib\\opencv_demo\\opencv_ml01\\t10k-images.idx3-ubyte";
std::string testLabeFile = "D:\\workForMy\\OpenCVLib\\opencv_demo\\opencv_ml01\\t10k-labels.idx1-ubyte";void train_SVM()
{//read train images, data type CV_32FC1cv::Mat trainingData = read_mnist_image(trainImgFile);//images data normalizationtrainingData = trainingData/255.0;std::cout << "trainingData.size() = " << trainingData.size() << std::endl; //read train label, data type CV_32SC1cv::Mat labelsMat = read_mnist_label(trainLabeFile);std::cout << "labelsMat.size() = " << labelsMat.size() << std::endl; std::cout << "trainingData & labelsMat finish!" << std::endl;  //create SVM modelcv::Ptr<cv::ml::SVM> svm = cv::ml::SVM::create();  //set svm args,type and KernelTypessvm->setType(cv::ml::SVM::C_SVC);  svm->setKernel(cv::ml::SVM::POLY);  //KernelTypes POLY is need set gamma and degreesvm->setGamma(3.0);svm->setDegree(2.0);//Set iteration termination conditions, maxCount is importancesvm->setTermCriteria(cv::TermCriteria(cv::TermCriteria::EPS | cv::TermCriteria::COUNT, 1000, 1e-8)); std::cout << "create SVM object finish!" << std::endl;  std::cout << "trainingData.rows = " << trainingData.rows << std::endl; std::cout << "trainingData.cols = " << trainingData.cols << std::endl; std::cout << "trainingData.type() = " << trainingData.type() << std::endl; // svm model train svm->train(trainingData, cv::ml::ROW_SAMPLE, labelsMat);  std::cout << "SVM training finish!" << std::endl; // svm model test  cv::Mat testData = read_mnist_image(testImgFile);//images data normalizationtestData = testData/255.0;std::cout << "testData.rows = " << testData.rows << std::endl; std::cout << "testData.cols = " << testData.cols << std::endl; std::cout << "testData.type() = " << testData.type() << std::endl; //read test label, data type CV_32SC1cv::Mat testlabel = read_mnist_label(testLabeFile);cv::Mat testResp;float response = svm->predict(testData,testResp); // std::cout << "response = " << response << std::endl; testResp.convertTo(testResp,CV_32SC1);int map_num = 0;for (int i = 0; i <testResp.rows&&testResp.rows==testlabel.rows; i++){if (testResp.at<int>(i, 0) == testlabel.at<int>(i, 0)){map_num++;}// else{// 	std::cout << "testResp.at<int>(i, 0) " << testResp.at<int>(i, 0) << std::endl;// 	std::cout << "testlabel.at<int>(i, 0) " << testlabel.at<int>(i, 0) << std::endl;// }}float proportion  = float(map_num) / float(testResp.rows);std::cout << "map rate: " << proportion * 100 << "%" << std::endl;std::cout << "SVM testing finish!" << std::endl; //save svm modelsvm->save("mnist_svm.xml");
}void prediction(const std::string fileName,cv::Ptr<cv::ml::SVM> svm)
{//read img 28*28 sizecv::Mat image = cv::imread(fileName, cv::IMREAD_GRAYSCALE);//uchar->float32image.convertTo(image, CV_32F);//image data normalizationimage = image / 255.0;//28*28 -> 1*784image = image.reshape(1, 1);//预测图片float ret = svm->predict(image);std::cout << "predict val = "<< ret << std::endl;
}std::string imgDir = "D:\\workForMy\\OpenCVLib\\opencv_demo\\opencv_ml01\\t10k-images\\";
std::string ImgFiles[5] = {"image_0.png","image_10.png","image_20.png","image_30.png","image_40.png",};
void predictimgs()
{//load svm modelcv::Ptr<cv::ml::SVM> svm = cv::ml::StatModel::load<cv::ml::SVM>("mnist_svm.xml");for (size_t i = 0; i < 5; i++){prediction(imgDir+ImgFiles[i],svm);}
}int main()  
{  train_SVM();predictimgs();	return 0;  
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/3415.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Gin+WebSocket实战——在线聊天室WebSocketDemo详细使用教程

文章目录 仓库地址项目简介如何使用 仓库地址 Github&#xff1a;https://github.com/palp1tate/WebsocketDemo 欢迎star&#xff01;&#x1f60e; 项目简介 利用 GinWebSocket 实现的在线聊天室Demo项目&#xff0c;支持加入/离开聊天室广播、给其他用户发送消息等。 如何…

STL——List常用接口模拟实现及其使用

认识list list的介绍 list是可以在常数范围内在任意位置进行插入和删除的序列式容器&#xff0c;并且该容器可以前后双向迭代。 list的底层是双向链表结构&#xff0c;双向链表中每个元素存储在互不相关的独立节点中&#xff0c;在节点中通过指针指向其前一个元素和后一个元素…

系统思考—心智模式

如果你总是做你过去一直做的事&#xff0c;你将永远得到你一直得到的结果。——托尼罗宾斯 在1980年代早期&#xff0c;美国汽车公司的高层主管定期前往日本参观&#xff0c;想要了解日本汽车行业为何能超越美国。这些主管返回后常说&#xff1a;“他们没有让我们看到真正的工…

工作任务管理平台作品集源文件 figma格式UX/UI设计师作品集

交付文件&#xff1a;作品集源文件项目源文件包装样机源文件字体文件 交付格式&#xff1a;figma、psd 作品集文件页数&#xff1a;28页 项目文件页数&#xff1a;12页&#xff08;Web&#xff09;12页&#xff08;App&#xff09; 以下重点哦&#xff0c;请认真阅读&#…

Halcon 3D 使用3D ROI截取模型

Halcon 3D 使用3D ROI截取模型 链接:https://pan.baidu.com/s/1UfFyZ6y-EFq9jy0T_DTJGA 提取码:ewdi * 1.读取图片 ****************

《R语言与农业数据统计分析及建模》学习——方差分析

方差分析是研究一种或多种因素的变化对试验结果的观测值是否有显著影响&#xff0c;从而找到较优试验条件或生产条件的一种常用数理统计方法。 方差分析根据平方和的加和原理&#xff0c;利用F检验&#xff0c;进而判断试验因素对试验结果的影响是否显著。 分为&#xff1a;单因…

CMake+qt+Visual Studio

#使用qt Creator 创建Cmake 项目,使用Cmake Gui 生成sln 工程&#xff0c;使用Visual Studio 开发 ##使用qt Creator 创建CMake项目 和创建pro工程的步骤一致&#xff0c;只是在选择构建系统的步骤上选择CMake,接下来步骤完全相同 工程新建完成之后&#xff0c;构建cmake 项…

公司服务器中的kafka消息中间件挂了,我是如何修复的?

今天的公司的system系统服务在运行过程中&#xff0c;提示连接不上kafuka的消息中间件。但是负责kafka的同事已经离职了&#xff0c;询问公司开发也不知道如何处理&#xff0c;我是如何重启kafka消息中间件使system系统服务正常运行&#xff1f; 查看kafka的安装位置 在下面的…

WPF —— MVVM架构

1 什么是MVVM&#xff1f; MVVM是一种软件架构模式&#xff0c;它将应用程序分为三个层次 model&#xff08;数据模型&#xff09;&#xff0c;view&#xff08;视图&#xff09;&#xff0c;viewmodel&#xff08;视图模型&#xff09; model&#xff1a;表示应用程序当中数…

SpringCloud之Feign集成Ribbon

Feign定义【可跳过】 Spring Cloud Feign是一个声明式的伪Http客户端&#xff0c;它使得写Http客户端变得更简单。其英文表意为“假装&#xff0c;伪装&#xff0c;变形”&#xff0c;是一个http请求调用的轻量级框架&#xff0c;可以以Java接口注解的方式调用Http请求&#x…

IDM下载器_Internet Download Manager 6.42.7

网盘下载 IDM下载器是一款针对互联网所打造的下载管理器。IDM下载器能将下载速度提高5倍&#xff0c;恢复因丢失的连接&#xff0c;网络问题&#xff0c;计算机关闭或意外断电而重新启动中断或中断的下载。IDM下载器还可支持所有流行的浏览器&#xff0c;以使用独特的“高级浏…

视频改字祝福 豪车装X系统源码uniapp前端源码

内容目录 一、详细介绍二、效果展示1.部分代码2.效果图展示 三、学习资料下载 一、详细介绍 uniapp视频改字祝福 豪车装X系统源码 全开源。 创意无限&#xff01;AI视频改字祝福&#xff0c;豪车装X系统源码开源&#xff0c;打造个性化祝福视频不再难&#xff01; 想要为你的…

RealSenseSR300工程环境配置说明

新建目录结构如下&#xff1a; output:存储可执行文件.exe等src:存储源码.cpp .h等3rdparty:存储第三方库 opencv等 其中将源码按照main及其相关文件分为以下三类 vs2015许可证到期后先激活&#xff0c;激活码很多网上有&#xff0c;如&#xff1a;HMGNV-WCYXV-X7G9W-YCX63…

2024.4.25

#include <iostream> #include <iomanip> using namespace std; class Person{const string name;int age;char sex; public:Person(const string name):name(name){cout << "第一个Person构造函数" << endl;}Person():name("zhangsan&…

3.7设计模式——Observer 观察者模式(行为型)

意图 定义对象间的一种一对多的依赖关系&#xff0c;当一个对象的状态发生改变时&#xff0c;所有依赖于他的对象都得到通知并被自动更新。 结构 Subject&#xff08;目标&#xff09;知道它的观察者&#xff0c;可以有任意多个观察者观察同一个目标&#xff0c;提供注册和删…

快速入门基础控制台API

目录 一、什么是win32API 二、API基础函数介绍 2.1控制台基础命令 2.1.1标题修改 2.1.2长宽修改 2.1.3坐标 2.2GetStdHandle 2.3GetConsoleCursorInfo 2.4SetConsoleCursorInfo 2.5SetConsoleCursorPosition 2.6GetAsyncKeyState 三、API函数综合应用 3.1设置光标…

IDEA-关于idea在import类时,代码报红的解决方法,找不到包

关于idea在import类时&#xff0c;代码报红的解决方法_idea import报红-CSDN博客

软件企业质量保证的基石――QA,QC的良性协作

软件企业质量保证的基石――QA、QC的良性协作 国内的软件产业发展了20多年的时间&#xff0c;已经由个人英雄时代步入到中、小团队协作时代。相信不久的将来&#xff0c;国内一定会出现航母级的软件企业&#xff0c;那时候我们会迎来集团军作战的时代。不同的时代表明软件规模…

Pandas 2.2 中文官方教程和指南(二十五·二)

新列 使用 DataFrame.map&#xff08;以前称为 applymap&#xff09;高效动态创建新列 In [53]: df pd.DataFrame({"AAA": [1, 2, 1, 3], "BBB": [1, 1, 2, 2], "CCC": [2, 1, 3, 1]})In [54]: df Out[54]: AAA BBB CCC 0 1 1 2 1…

用html写一个旋转菜单

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>旋转菜单</title><link relstylesheet href"https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css"&…