正态贝叶斯分类器CvNormalBayesClassifier的OpenCV4.0多个实例代码实战

旧巷老猫 提交于 2020-03-24 08:28:08

3 月,跳不动了?>>>

说明
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.csdn.net/zhaocj/article/details/50615049

https://www.cnblogs.com/denny402/p/5031613.html

https://blog.csdn.net/dcrmg/article/details/53026593#commentBox
————————————————
版权声明:本文为CSDN博主「yueyueniaolzp」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/yueyueniaolzp/article/details/85263859


发布了230 篇原创文章 · 获赞 192 · 访问量 60万+
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!