目录
配置
硬件
普通台式机,处理器Intel(R) Xeon(R) CPU E3-1231 v3 @ 3.40GHz
安装内存RAM16.0GB
系统类型64位操作系统
软件
操作系统:Windows 7 旗舰版;Ubuntu 16.04 LTS
开发IDE:Visual Studio 2015(win7)
OpenCV version:OpenCV 4.0.0
例程类型:C++控制台简易程序
说明
OpenCV中实现的正态贝叶斯分类器Normal Bayes Classifier,而不是其他类型的贝叶斯分类器,例如朴素贝叶斯分类器Naive Bayes Classifier。正态贝叶斯分类器中样本特征属性之间不必是相互独立的,因而适用范围更广,但是只能处理特征属性是连续数值的分类问题。
源码
实例1 根据身高体重脚长预测性别
题例
例子是维基百科中英文条目Naive Bayes classifier所列举的例子。下表是某国人体特征指标的一组统计资料:
问题是,已知某人身高6英尺,体重130磅,脚掌长8英寸,利用前面的训练样本来预测该人是男还是女。
实现
// NormalBayes.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "opencv2/opencv.hpp"
#include "opencv2/ml.hpp"
#include <iostream>
using namespace cv;
using namespace cv::ml;
using namespace std;
void main(int argc, char** argv)
{
//创建正态贝叶斯分类器
Ptr<NormalBayesClassifier> model = NormalBayesClassifier::create();
//创建训练样本
float trainingData[8][3] =
{
{ 6, 180, 12 },
{ 5.92, 190, 11 },
{ 5.58, 170, 12 },
{ 5.92, 165, 10 },
{ 5, 100, 6 },
{ 5.5, 150, 8 },
{ 5.42, 130, 7 },
{ 5.75, 150, 9 }
};
Mat trainingDataMat(8, 3, CV_32FC1, trainingData);
cout << trainingDataMat << endl;
//1代表M -1代表F
int labels[8] = { 1, 1, 1, 1, -1, -1, -1, -1 };
Mat labelsMat(8, 1, CV_32SC1, labels);
cout << labelsMat << endl;
//创建TrainData并进行训练
Ptr<TrainData> tData = TrainData::create(trainingDataMat, ROW_SAMPLE, labelsMat);
model->train(tData);
float myData[3] = { 6, 130, 8 }; //测试样本
Mat myDataMat(1, 3, CV_32FC1, myData); //
int res = model->predict(myDataMat); //利用训练好的分类器进行测试样本预测
cout << endl << "The result is : " << res << endl;
waitKey(0);
}
预测结果如下:
实例2 二分类训练结果展示
题例
算法的二分类训练展示
实现
// NormalBayes.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "opencv2/opencv.hpp"
#include "opencv2/ml.hpp"
#include <iostream>
using namespace cv;
using namespace cv::ml;
using namespace std;
int main(int, char**)
{
Mat image = Mat::zeros(512, 512, CV_8UC3);
int labels[10] = { 1, -1, 1, 1,-1,1,-1,1,-1,-1 };
Mat labelsMat(10, 1, CV_32SC1, labels);
float trainingData[10][2] = { { 501, 150 },{ 255, 10 },{ 501, 255 },{ 10, 501 },{ 25, 80 },
{ 150, 300 },{ 77, 200 } ,{ 300, 300 } ,{ 45, 250 } ,{ 200, 200 } };
Mat trainingDataMat(10, 2, CV_32FC1, trainingData);
Ptr<NormalBayesClassifier> model = NormalBayesClassifier::create();
Ptr<TrainData> tData = TrainData::create(trainingDataMat, ROW_SAMPLE, labelsMat);
model->train(tData);
Vec3b green(0, 255, 0), blue(255, 0, 0);
// Show the decision regions given by the SVM
for (int i = 0; i < image.rows; ++i)
for (int j = 0; j < image.cols; ++j)
{
Mat sampleMat = (Mat_<float>(1, 2) << j, i);
float response = model->predict(sampleMat);
if (response == 1)
image.at<Vec3b>(i, j) = green;
else if (response == -1)
image.at<Vec3b>(i, j) = blue;
}
//
Scalar c1 = Scalar::all(0);
Scalar c2 = Scalar::all(255);
for (int i = 0; i < labelsMat.rows; i++)
{
const float* v = trainingDataMat.ptr<float>(i);
Point pt = Point((int)v[0], (int)v[1]);
if (labels[i] == 1)
circle(image, pt, 5, c1, -1, 8);
else
circle(image, pt, 5, c2, -1, 8);
}
imshow("NormalBayesClassifier", image);
waitKey(0);
return 0;
}
训练的分类器结果如下:
实例3 简单的病情诊断预测
题例
假定以下是根据医院历来可靠数据获取的体温、咳嗽、流涕三个症状的严重程度判定的三类病情,分别是冷感冒、肺炎、热感冒。根据10组数据进行训练,然后输入一位病人的数据,自动进行诊断病情,以下是训练数据:
输入病人的数据为:体温-40、咳嗽-8、流涕-10,诊断结果为何。
实现
// NormalBayes.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "opencv2/opencv.hpp"
#include "opencv2/ml.hpp"
#include <iostream>
using namespace cv;
using namespace cv::ml;
using namespace std;
int main(int argc, char** argv)
{
//创建正态贝叶斯分类器
Ptr<NormalBayesClassifier> model = NormalBayesClassifier::create();
//已知训练样本数据
float trainingData[10][3] = {
{ 34,1,1},
{ 35,2,2},
{ 36,3,3},
{ 37,8,4},
{ 38,9,5},
{ 39,10,6},
{ 40,7,7},
{ 41,4,8},
{ 42,5,9},
{ 43,6,10}
};
Mat trainingDataMat(10, 3, CV_32FC1, trainingData);
//标签值,1代表冷感冒,-1代表肺炎,0代表热感冒
float responses[10] = { 1,1,1,-1,-1,-1,0,0,0,0 };
Mat responsesMat(10, 1, CV_32SC1, responses);
//创建TrainData并进行分类器的训练
Ptr<TrainData> tData = TrainData::create(trainingDataMat, ROW_SAMPLE, responsesMat);
model->train(tData);
//已知的测试样本导入并进行分类器预测
float myData[3] = { 40, 8, 10 }; //
Mat myDataMat(1, 3, CV_32FC1, myData);
float r = model->predict(myDataMat);
int result = r;
//结果输出
string output;
switch (result)
{
case 1:
output = "Cold-cold";
break;
case -1:
output = "Pneumonia";
break;
case 0:
output = "Hot-cold";
break;
default:
output = "Healthy";
break;
}
cout << endl << "The patient's disease was diagnosed as : " << output << endl << endl;
system("pause");
return 0;
}
病情预测结果为:
参考
https://docs.opencv.org/4.0.0/index.html
https://blog.youkuaiyun.com/zhaocj/article/details/50615049
https://www.cnblogs.com/denny402/p/5031613.html
https://blog.youkuaiyun.com/dcrmg/article/details/53026593#commentBox