C/C++开发,opencv-ml库学习,随机森林(RTrees)应用

目录

一、随机森林算法

1.1 算法简介

1.2 OpenCV-随机森林(Random Forest)

二、cv::ml::RTrees应用

2.2 RTrees应用

2.2 程序编译

2.3 main.cpp全代码


一、随机森林算法

1.1 算法简介

        随机森林算法是一种集成学习(Ensemble Learning)方法,由多个决策树组成。它结合了决策树的高效性和集成学习的准确性,具有很强的模型泛化能力。

        随机森林算法的原理主要包括两个方面:随机性和集成。

  1. 随机性:体现在样本的随机性和特征的随机性。算法通过引入随机性来构建多个决策树,每个决策树都是基于随机抽样的训练数据和随机选择的特征进行构建的。这种随机性能够有效地减少过拟合的风险,提高模型的泛化能力。
  2. 集成:通过集成多个决策树的预测结果来完成最终的分类或回归任务。通常采用投票的方式进行集成,即多数表决原则。在随机森林中,每棵决策树的构建过程都是相互独立的,这意味着每棵决策树都是在不同的训练数据和特征子集上进行构建的,这种随机性能够有效地降低模型的方差,提高模型的稳定性。
1.2 OpenCV-随机森林(Random Forest)

        在OpenCV中,随机森林(Random Forest)是一种集成学习方法,通过构建并组合多个决策树来做出预测。OpenCV提供了cv::ml::RTrees类来实现随机森林算法。决策树在使用时仅仅构建一棵树,这样容易出现过拟合现象,可以通过构建多个决策树来避免过拟合现象。当构建多个决策树时,就出现了随机森林。这种方法通过多个决策树的投票来得到在最终的结果。

//创建 RTrees对象cv::Ptr<cv::ml::RTrees> rf = cv::ml::RTrees::create();  
RTrees类:setMaxDepth()     设置决策树的最大深度 setMinSampleCount() 设置叶子节点上的最小样本数setRegressionAccuracy() 非必须 回归算法的精度setPriors() 非必须 数据类型setCalculateVarImportance() 非必须 是否要计算varsetActiveVarCount() 非必须 设置var的数目setTermCriteria() 设置终止条件.....

        随机森林通过随机选择特征和样本子集来构建每棵决策树,并将它们的预测结果进行集成。这种方法通常能够降低过拟合的风险,并提高模型的预测性能。

二、cv::ml::RTrees应用

2.1 数据集样本准备

  本文为了快速验证使用,采用mnist数据集,参考本专栏博文《C/C++开发,opencv-ml库学习,支持向量机(SVM)应用-CSDN博客》下载MNIST 数据集(手写数字识别),并解压。

        同时参考该博文“2.4 SVM(支持向量机)实时识别应用”的章节资料,利用python代码解压t10k-images.idx3-ubyte出图片数据文件。

2.2 RTrees应用

        创建了一个 cv::ml::RTrees对象,并设置了训练数据和终止条件。接着,我们调用 train 方法来训练决策树模型。最后,我们使用训练好的模型来预测一个新样本的类别。

   // 3. 设置并训练随机森林模型  cv::Ptr<cv::ml::RTrees> rf = cv::ml::RTrees::create();  rf->setMaxDepth(30);                    // 设置决策树的最大深度  rf->setMinSampleCount(2);             // 设置叶子节点上的最小样本数  rf->setTermCriteria(cv::TermCriteria(cv::TermCriteria::EPS + cv::TermCriteria::COUNT, 10, 0.1)); // 设置终止条件  rf->train(trainingData, cv::ml::ROW_SAMPLE, labelsMat); ......cv::Mat testResp;float response = rf->predict(testData,testResp); ......rf->save("mnist_svm.xml"); 

     训练及测试过的算法模型,保存输出,然后调用

cv::Ptr<cv::ml::RTrees> rf = cv::ml::StatModel::load<cv::ml::RTrees>("mnist_svm.xml");//预测图片
float ret = rf ->predict(image);
std::cout << "predict val = "<< ret << std::endl;
2.2 程序编译

        和讲述支持向量机(SVM)应用的博文编译类似,采用opencv+mingw+makefile方式编译:

#/bin/sh
#win32
CX= g++ -DWIN32 
#linux
#CX= g++ -Dlinux BIN 		:= ./
TARGET      := opencv_ml03.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)

make编译,make clean 清除可重新编译。

运行效果,同样数据样本,相比决策树算法训练结果,其准确率有了较大改善,大家可以尝试调整参数验证:

2.3 main.cpp全代码

        main.cpp源代码,由于是基于前两篇博文支持向量机(SVM)应用、决策树(DTrees)应用基础上,快速移用实现的,有很多支持向量机(SVM)应用或决策树(DTrees)的痕迹,采用的数据样本也非较合适的,仅仅是为了阐述c++ opencv 随机森林(RTrees)应用说明。

#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;std::cout << "trainingData.type() = " << trainingData.type() << std::endl;  std::cout << "trainingData.rows = " << trainingData.rows << std::endl; std::cout << "trainingData.cols = " << trainingData.cols << 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 << "labelsMat.type() = " << labelsMat.type() << std::endl;  std::cout << "labelsMat.rows = " << labelsMat.rows << std::endl; std::cout << "labelsMat.cols = " << labelsMat.cols << std::endl; std::cout << "trainingData & labelsMat finish!" << std::endl;  // //create SVM model// cv::Ptr<cv::ml::SVM> svm = cv::ml::SVM::create();  // //set svm args,type and KernelTypes// svm->setType(cv::ml::SVM::C_SVC);  // svm->setKernel(cv::ml::SVM::POLY);  // //KernelTypes POLY is need set gamma and degree// svm->setGamma(3.0);// svm->setDegree(2.0);// //Set iteration termination conditions, maxCount is importance// svm->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; // // 创建决策树对象  // cv::Ptr<cv::ml::DTrees> dtree = cv::ml::DTrees::create();  // dtree->setMaxDepth(30);          // 设置树的最大深度  // dtree->setCVFolds(0);// dtree->setMinSampleCount(1);   // 设置分裂内部节点所需的最小样本数 // std::cout << "create dtree object finish!" << std::endl;  // // 训练决策树--trainingData训练数据,labelsMat训练标签// cv::Ptr<cv::ml::TrainData> td = cv::ml::TrainData::create(trainingData, cv::ml::ROW_SAMPLE, labelsMat);  // std::cout << "create TrainData object finish!" << std::endl; // if(dtree->train(td))// {// 	std::cout << "dtree training finish!" << std::endl;// }else{// 	std::cout << "dtree training fail!" << std::endl; // }// 3. 设置并训练随机森林模型  cv::Ptr<cv::ml::RTrees> rf = cv::ml::RTrees::create();  rf->setMaxDepth(30);                    // 设置决策树的最大深度  rf->setMinSampleCount(2);             // 设置叶子节点上的最小样本数  rf->setTermCriteria(cv::TermCriteria(cv::TermCriteria::EPS + cv::TermCriteria::COUNT, 10, 0.1)); // 设置终止条件  rf->train(trainingData, cv::ml::ROW_SAMPLE, labelsMat);  // 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); // float response = dtree->predict(testData,testResp); float response = rf->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 model// svm->save("mnist_svm.xml");// dtree->save("mnist_svm.xml");rf->save("mnist_svm.xml");
}void prediction(const std::string fileName,cv::Ptr<cv::ml::DTrees> dtree)
// 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 = dtree->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 model// cv::Ptr<cv::ml::SVM> svm = cv::ml::StatModel::load<cv::ml::SVM>("mnist_svm.xml");//load DTrees model// cv::Ptr<cv::ml::DTrees> dtree = cv::ml::StatModel::load<cv::ml::DTrees>("mnist_svm.xml");cv::Ptr<cv::ml::RTrees> rf = cv::ml::StatModel::load<cv::ml::RTrees>("mnist_svm.xml");for (size_t i = 0; i < 5; i++){prediction(imgDir+ImgFiles[i],rf);}
}int main()  
{  train_SVM();predictimgs();	return 0;  
}

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

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

相关文章

百度沈抖:智能,生成无限可能

4月16日&#xff0c;Create 2024百度AI开发者大会在深圳举行。会上&#xff0c;百度集团执行副总裁、百度智能云事业群总裁沈抖正式发布新一代智能计算操作系统——百度智能云万源。它能管理万卡规模的集群&#xff0c;极致地发挥GPU、CPU的性能&#xff1b;它有强大的大模型作…

本地环境运行Llama 3大型模型:可行性与实践指南

简介&#xff1a; Llama 是由 Meta&#xff08;前身为 Facebook&#xff09;的人工智能研究团队开发并开源的大型语言模型&#xff08;LLM&#xff09;&#xff0c;它对商业用途开放&#xff0c;对整个人工智能领域产生了深远的影响。继之前发布的、支持4096个上下文的Llama 2…

Python 数据可视化 boxplot

Python 数据可视化 boxplot import pandas as pd import matplotlib.pyplot as plt import numpy as np import seaborn as sns# 读取 TSV 文件 df pd.read_csv(result.tsv, sep\t)normal_df df[df["sample_name"].str.contains("normal")] tumor_df df…

重磅!!!监控分布式NVIDIA-GPU状态

简介&#xff1a;Uptime Kuma是一个易于使用的自托管监控工具&#xff0c;它的界面干净简洁&#xff0c;部署和使用都非常方便&#xff0c;用来监控GPU是否在占用&#xff0c;非常美观。 历史攻略&#xff1a; docker应用&#xff1a;搭建uptime-kuma监控站点 win下持续观察…

Unity Meta Quest MR 开发(七):使用 Stencil Test 模板测试制作可以在虚拟与现实之间穿梭的 MR 传送门

文章目录 &#x1f4d5;教程说明&#x1f4d5;Stencil Test 模板测试&#x1f4d5;Stencil Shader&#x1f4d5;使用 Unity URP 渲染管线设置模板测试⭐Render Pipeline Asset 与 Universal Renderer Data⭐删除场景中的天空盒⭐设置虚拟世界的层级 Layer⭐设置模板测试 &#…

《Vid2Seq》论文笔记

原文链接 [2302.14115] Vid2Seq: Large-Scale Pretraining of a Visual Language Model for Dense Video Captioning (arxiv.org) 原文笔记 What&#xff1a; 《Vid2Seq: Large-Scale Pretraining of a Visual Language Model for Dense Video Captioning》 作者提出一种多…

深度学习检测算法YOLOv5的实战应用

在当前的检测项目中&#xff0c;需要一个高效且准确的算法来处理大量的图像数据。经过一番研究和比较&#xff0c;初步选择了YOLOv5作为算法工具。YOLOv5是一个基于深度学习的检测算法&#xff0c;以其快速和准确而闻名。它不仅能够快速处理图像数据&#xff0c;还能提供较高的…

【OceanBase诊断调优】——hpet(高精度时钟源)引起的CPU高问题排查

最近总结一些诊断OCeanBase的一些经验&#xff0c;出一个【OceanBase诊断调优】专题出来&#xff0c;也欢迎大家贡献自己的诊断OceanBase的方法。 1. 前言 昨天在问答区帮忙排查一个用户CPU高的问题&#xff0c;帖子链接&#xff1a;《刚刚新安装的OceanBase集群&#xff0c;…

Rime 如何通过 iCloud 实现词库多端同步,Windows、iOS、macOS

Rime 如何通过 iCloud 实现词库多端同步&#xff0c;Windows、iOS、macOS 一、设备环境 最理想的输入环境就是在多端都使用同一个词库&#xff0c;这样能保持多端的输入习惯是一致的。 以我为例&#xff0c;手头每天都要用到的操作平台和对应的输入法&#xff1a; 操作系统设…

【热门前端【vue框架】】——vue框架和node.js的下载和安装保姆式教程

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;程序员-曼亿点 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 曼亿点 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a…

【ARM 裸机】模仿 STM32 驱动开发

1、修改驱动 对于 STM32 来说&#xff0c;使用了一个结构体将一个外设的所有寄存器都放在一起&#xff0c;在上一节的基础上进行修改&#xff1b; 1.1、添加清除 bss 段代码&#xff0c; 1.2、添加寄存器结构体 新建一个文件&#xff0c;命名imx6u.h&#xff0c;注意地址的连…

NLP Step by Step -- How to use pipeline

正如我们在摸鱼有一手&#xff1a;NLP step by step -- 了解Transformer中看到的那样&#xff0c;Transformers模型通常非常大。对于数以百万计到数千万计数十亿的参数&#xff0c;训练和部署这些模型是一项复杂的任务。此外&#xff0c;由于几乎每天都在发布新模型&#xff0c…

Linux系统网络---DNS域名解析服务

目录 一、DNS的简介 DNS系统的分布式数据结构&#x1f447; DNS系统类 两种查询方式 二.正向解析实验 1.先关闭防火墙、selinux 2.安装bind 3.查看配置、修改配置 4.修改区域配置文件 正向解析&#x1f447; 反向解析&#x1f447; 5.修改 正向解析&#x1f…

python环境安装jupyter

1 前提条件&#xff1a;python环境 系统&#xff1a;win10 python&#xff1a;本地已经有python&#xff0c;可以查看本地的python版本&#xff1a; C:\Users\PC>python --version Python 3.8.10 2 安装jupyter并启动 安装jupyter C:\Users\PC>pip install jupyter …

Qt xml示范

1.数据格式 #ifndef XML_DATA_H #define XML_DATA_H#include<QWidget>struct Student {int s_id;QString s_name;double s_math_score;double s_english_score;}; struct Teacher{int t_id;QString t_name;QVector<Student> t_students_v; };#endif // XML_DATA_H…

面试:JVM垃圾回收

一、三种垃圾回收算法 1、标记清除&#xff08;已废弃&#xff09; 找到根对象&#xff08;局部变量正在引用的对象、静态变量正在引用的对象&#xff09;&#xff1b;沿着根对象的引用链&#xff0c;查看当前的对象是否被根对象所引用&#xff0c;若被引用&#xff0c;则加上…

区块链 | OpenSea 相关论文:Toward Achieving Anonymous NFT Trading(一)

​ &#x1f951;原文&#xff1a; Toward Achieving Anonymous NFT Trading &#x1f951;写在前面&#xff1a; 本文对实体的介绍基于论文提出的方案&#xff0c;而非基于 OpenSea 实际采用的方案。 其实右图中的 Alice 也是用了代理的&#xff0c;不过作者没有画出来。 正文…

UEFI安全启动模式下安装Ubuntu的NVIDIA显卡驱动

UEFI安全启动模式下安装ubuntu的nvidia显卡驱动 实践设备&#xff1a;华硕FX-PRO&#xff08;NVIDIA GeForce GTX 960M&#xff09; 一、NVIDIA官网下载驱动 1.1在浏览器地址栏输入https://www.nvidia.cn/drivers/lookup/进入网站&#xff0c;接着手动驱动搜索&#xff0c;并…

The Clock and the Pizza [NeurIPS 2023 oral]

本篇文章发表于NeurIPS 2023 (oral)&#xff0c;作者来自于MIT。 文章链接&#xff1a;https://arxiv.org/abs/2306.17844 一、概述 目前&#xff0c;多模态大语言模型的出现为人工智能带来新一轮发展&#xff0c;相关理论也逐渐从纸面走向现实&#xff0c;影响着人们日常生活…

探讨mfc100u.dll丢失的解决方法,修复mfc100u.dll有效方法解析

mfc100u.dll丢失是一个比较常见的情况&#xff0c;由于你电脑的各种操作&#xff0c;是有可能引起dll文件的缺失的&#xff0c;而mfc100u.dll就是其中的一个重要的dll文件&#xff0c;它的确实严重的话是会导致程序打不开&#xff0c;系统错误的。今天我们就来给大家科普一下mf…