基于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; }