基于opencv的特征值分类

opencv可以很方便对图像求hog特征值,然后使用SVM进行分离,最终达到特定物体识别的功能。下面的示例

#include <opencv2/opencv.hpp>
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"  
#include<opencv2/imgproc/imgproc.hpp>  
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/imgproc/imgproc.hpp>  // Gaussian Blur
#include <opencv2/core/core.hpp>        // Basic OpenCV structures (cv::Mat, Scalar)
#include <opencv2/highgui/highgui.hpp>  // OpenCV window I/O
#include <opencv2/imgproc/types_c.h>
#include <opencv2/core/utils/logger.hpp>
#include <opencv2/imgproc/imgproc_c.h>
#include <iostream>  
#include <thread>
using namespace std;
using namespace cv;

void train()
{
    //定义加载正样本数据和负样本数据的文件路径
    string positive_path = "e:/media/src/msk/"; 
    string negative_path = "e:/media/src/ok/";
    //通过glob()将路径下的所有图像文件以string类型读取进来
    vector<string> positive_images_str, negative_images_str;
    glob(positive_path, positive_images_str);
    glob(negative_path, negative_images_str);


    HOGDescriptor* hog_train = new HOGDescriptor;
    vector<vector<float>> train_descriptors;
    vector<int> labels;
    for (int i = 0; i < positive_images_str.size(); i++)
    {
        Mat tmp = imread(positive_images_str[i]);
        resize(tmp, tmp, Size(64, 128));

        Mat gray;
        cvtColor(tmp, gray, COLOR_BGR2GRAY);            //计算HOG描述子时需要使用灰度图像
        vector<float> descriptor;
        hog_train->compute(gray, descriptor, Size(8, 8), Size(0, 0));
        train_descriptors.push_back(descriptor);
        labels.push_back(1);
    }
    for (int i = 0; i < negative_images_str.size(); i++)
    {
        Mat tmp = imread(negative_images_str[i]);
        resize(tmp, tmp, Size(64, 128));

        Mat gray;
        cvtColor(tmp, gray, COLOR_BGR2GRAY);            //计算HOG描述子时需要使用灰度图像
        vector<float> descriptor;
        hog_train->compute(gray, descriptor, Size(8, 8), Size(0, 0));
        train_descriptors.push_back(descriptor);
        labels.push_back(-1);
    }
    //将训练数据vector转换为Mat对象,每一行为一个描述子,行数即为样本数
    int width = train_descriptors[0].size();
    int height = train_descriptors.size();
    Mat train_data = Mat::zeros(Size(width, height), CV_32F);
    for (int r = 0; r < height; r++)
    {
        for (int c = 0; c < width; c++)
        {
            train_data.at<float>(r, c) = train_descriptors[r][c];
        }
    }
    //使用最优参数训练SVM分类器,并保存到与代码同目录下
    auto train_svm = ml::SVM::create();
    train_svm->trainAuto(train_data, ml::ROW_SAMPLE, labels);
    train_svm->save("model.xml");
    hog_train->~HOGDescriptor();
    train_svm->clear();
}
void demo()
{
    auto test_svm = ml::SVM::load("model.xml");
    Mat frame = imread("src.jpg");
    Mat dst;
    resize(frame, dst, Size(64, 128));//规范图像尺寸


    HOGDescriptor hog;
    vector<float> des;//HOG特征向量
    hog.compute(dst, des);//计算hog特征
    float result=test_svm->predict(des);//这里要么是1要么是-1 1表示训练中是正值
    printf("ret=%.1f\n", result);
}
int main()
{
    train();//这个进行训练,训练好就可以不调用了。
    demo();//加载模型 进行分类
    return 0;
}

 

posted on 2024-07-29 15:24  弘道者  阅读(4)  评论(0编辑  收藏  举报