svm->train(X, cv::ml::ROW_SAMPLE, labels);
这是堆栈跟踪:
[内嵌框架] svm&ssd_car_ detector.exe!invoke_main() 第 78 行 C++
在此功能中:
cv::Ptr<cv::ml::SVM> train_svm_model(const cv::Mat& X, const cv::Mat& labels) {
if (X.empty() || labels.empty()) {
cerr << "Error: Feature matrix (X) or labels matrix is empty." << endl;
return nullptr;
}
// Check if dimensions match
if (X.rows != labels.rows) {
cerr << "Error: Number of rows in feature matrix (X) does not match the number of labels." << endl;
return nullptr;
}
// Check data type of X
if (X.type() != CV_32F) {
cerr << "Error: Feature matrix (X) should have data type CV_32F." << endl;
return nullptr;
}
// Check data type of labels
if (labels.type() != CV_32F) {
cerr << "Error: Labels matrix should have data type CV_32F." << endl;
return nullptr;
}
// Create an SVM object
cv::Ptr<cv::ml::SVM> svm = cv::ml::SVM::create();
//Set SVM parameters (adjust as needed)
svm->setC(1.5);
svm->setKernel(cv::ml::SVM::POLY);
svm->setTermCriteria(cv::TermCriteria(cv::TermCriteria::MAX_ITER, 100, 1e-6));
try {
// Train the SVM model
svm->train(X, cv::ml::ROW_SAMPLE, labels);
}
catch (const cv::Exception& e) {
cerr << "Error during SVM training: " << e.msg << endl;
return nullptr;
}
return svm;
}
我正在使用 Visual Studio 2022 和 opencv 4.8.0 这是我的漏洞代码:
#include <iostream>
#include <opencv2/opencv.hpp>
#include <random>
#include <opencv2/ml.hpp>
using namespace std;
vector<float> get_single_img_hog_features(cv::Mat image, int orient, int pixels_per_cell, int cells_per_block) {
cv::HOGDescriptor hog;
hog.winSize = image.size();
hog.blockSize = cv::Size(cells_per_block * pixels_per_cell, cells_per_block * pixels_per_cell);
hog.blockStride = cv::Size(pixels_per_cell, pixels_per_cell);
hog.cellSize = cv::Size(pixels_per_cell, pixels_per_cell);
hog.nbins = orient;
// Compute HOG descriptors
vector<float> features;
hog.compute(image, features, cv::Size(32, 32));
return features;
}
// Function to extract features from a single image window
vector<float> single_img_features(cv::Mat img, int orient, int pix_per_cell, int cell_per_block, int hog_channel) {
cv::Mat img_features;
cv::cvtColor(img, img_features, cv::COLOR_BGR2RGB);
if (hog_channel == -1) { // Compute HOG features for all channels
vector<vector<float>> hog_channel_features;
for (int channel = 0; channel < img_features.channels(); ++channel) {
cv::Mat channel_image;
cv::extractChannel(img_features, channel_image, channel);
vector<float> hog_channel_feature = get_single_img_hog_features(channel_image, orient, pix_per_cell, cell_per_block);
hog_channel_features.push_back(hog_channel_feature);
}
vector<float> flattened_vec;
for (const auto& inner_vec : hog_channel_features) {
flattened_vec.insert(flattened_vec.end(), inner_vec.begin(), inner_vec.end());
}
return flattened_vec;
}
else { // Compute HOG features for a single channel
vector<float> hog_features;
cv::Mat channel_image;
cv::extractChannel(img_features, channel_image, hog_channel);
hog_features = get_single_img_hog_features(channel_image, orient, pix_per_cell, cell_per_block);
return hog_features;
}
}
// Function to extract features from a list of images
vector<vector<float>> extract_features(vector<string> imgs, int orient, int pix_per_cell, int cell_per_block, int hog_channel) {
vector<vector<float>> features;
for (const auto& file : imgs) {
cv::Mat img = cv::imread(file);
if (img.empty()) {
cout << "image file empty" << endl;
continue; // Skip if unable to read image
}
vector<float> file_features = single_img_features(img,orient, pix_per_cell, cell_per_block, hog_channel);
features.push_back(file_features);
}
return features;
}
// Function to perform feature scaling
cv::Mat featureScaling(const cv::Mat& X) {
cv::Mat scaled_X;
cv::Scalar mean, stddev;
cv::meanStdDev(X, mean, stddev);
scaled_X = (X - mean) / stddev;
return scaled_X;
}
// Function to shuffle rows of two matrices simultaneously
void shuffle_matrices(cv::Mat& X, cv::Mat& labels) {
// Check compatibility of sizes
if (X.rows != labels.rows) {
cerr << "Error: Matrix dimensions must be equal for shuffling." << endl;
return;
}
// Create a random number generator
std::random_device rd;
std::mt19937 g(rd());
// Shuffle the indices manually
for (int i = 0; i < X.rows; ++i) {
// Generate a random index within the range [0, X.rows - 1]
int random_index = std::uniform_int_distribution<int>(0, X.rows - 1)(g);
// Swap the current row with the randomly chosen row
cv::Mat temp_row = X.row(i);
X.row(i) = X.row(random_index);
X.row(random_index) = temp_row;
cv::Mat temp_row_label = labels.row(i);
labels.row(i) = labels.row(random_index);
labels.row(random_index) = temp_row_label;
}
}
tuple<cv::Mat, cv::Mat> prepare_images_for_processing(const vector<string>& car_img_folders, const vector<string>& noncar_img_folders, const string& image_type, int orient, int pix_per_cell, int cell_per_block, int hog_channel) {
vector<string> cars;
for (const auto& folder : car_img_folders) {
// Find all image files in the current folder with the specified image type
vector<cv::String> filenames;
cv::glob(folder + "/*." + image_type, filenames, false);
for (const auto& filename : filenames) {
cars.push_back(filename);
}
}
vector<string> notcars;
for (const auto& folder : noncar_img_folders) {
// Find all image files in the current folder with the specified image type
vector<cv::String> filenames;
cv::glob(folder + "/*." + image_type, filenames, false);
for (const auto& filename : filenames) {
notcars.push_back(filename);
}
}
cout << "Cars len: " << cars.size() << endl;
cout << "Notcars len: " << notcars.size() << endl;
// Keep distribution even
int train_size = 8500;
if (cars.size() > train_size) {
cars.resize(train_size);
}
if (notcars.size() > train_size) {
notcars.resize(train_size);
}
// Extract features for car images
vector<vector<float>> car_features = extract_features(cars, orient, pix_per_cell, cell_per_block, hog_channel);
// Extract features for non-car images
vector<vector<float>> notcar_features = extract_features(notcars, orient, pix_per_cell, cell_per_block, hog_channel);
cout << car_features.size() << endl;
cout << notcar_features.size() << endl;
// Concatenate v1 and v2 vertically into a single cv::Mat
int num_features = car_features[0].size();
int total_samples = car_features.size() + notcar_features.size();
// Create a cv::Mat to hold the concatenated data
cv::Mat X(total_samples, num_features, CV_32FC1);
// Copy data from v1 to mat
for (int i = 0; i < car_features.size(); ++i) {
for (int j = 0; j < num_features; ++j) {
X.at<float>(i, j) = car_features[i][j];
}
}
// Copy data from v2 to mat
for (int i = 0; i < notcar_features.size(); ++i) {
for (int j = 0; j < num_features; ++j) {
X.at<float>(i + car_features.size(), j) = notcar_features[i][j];
}
}
// Define the labels vector
cv::Mat labels(X.rows, 1, CV_32FC1);
labels.rowRange(0, 8500).setTo(1); // Set car labels to 1
labels.rowRange(8500, total_samples).setTo(0); // Set non-car labels to 0
// Apply the scaler to X
cv::Mat scaled_X =featureScaling(X);
shuffle_matrices(scaled_X, labels);
// Return the scaled X, and labels
return make_tuple(scaled_X, labels);
}
// Function to train an SVM model
cv::Ptr<cv::ml::SVM> train_svm_model(const cv::Mat& X, const cv::Mat& labels) {
if (X.empty() || labels.empty()) {
cerr << "Error: Feature matrix (X) or labels matrix is empty." << endl;
return nullptr;
}
// Check if dimensions match
if (X.rows != labels.rows) {
cerr << "Error: Number of rows in feature matrix (X) does not match the number of labels." << endl;
return nullptr;
}
// Check data type of X
if (X.type() != CV_32F) {
cerr << "Error: Feature matrix (X) should have data type CV_32F." << endl;
return nullptr;
}
// Check data type of labels
if (labels.type() != CV_32F) {
cerr << "Error: Labels matrix should have data type CV_32F." << endl;
return nullptr;
}
// Create an SVM object
cv::Ptr<cv::ml::SVM> svm = cv::ml::SVM::create();
//Set SVM parameters (adjust as needed)
svm->setC(1.5);
svm->setKernel(cv::ml::SVM::POLY);
svm->setTermCriteria(cv::TermCriteria(cv::TermCriteria::MAX_ITER, 100, 1e-6));
try {
// Train the SVM model
svm->train(X, cv::ml::ROW_SAMPLE, labels);
}
catch (const cv::Exception& e) {
cerr << "Error during SVM training: " << e.msg << endl;
return nullptr;
}
return svm;
}
// Function to save the trained SVM model
void save_svm_model(cv::Ptr<cv::ml::SVM> svm, const string& filename) {
svm->save(filename);
}
int main() {
// Define parameters
vector<string> car_folders = { "C:/Users/DELL/Desktop/vehicle-detection-with-svm/vehicles/GTI_Far", "C:/Users/DELL/Desktop/vehicle-detection-with-svm/vehicles/GTI_Left", "C:/Users/DELL/Desktop/vehicle-detection-with-svm/vehicles/GTI_MiddleClose", "C:/Users/DELL/Desktop/vehicle-detection-with-svm/vehicles/GTI_Right", "C:/Users/DELL/Desktop/vehicle-detection-with-svm/vehicles/KITTI_extracted" };
vector<string> notcar_folders = { "C:/Users/DELL/Desktop/vehicle-detection-with-svm/non-vehicles/Extras", "C:/Users/DELL/Desktop/vehicle-detection-with-svm/non-vehicles/GTI" };
string image_type = "png";
int orient = 9;
int pix_per_cell = 8;
int cell_per_block = 2;
int hog_channel = -1;
tuple<cv::Mat, cv::Mat> processed_data = prepare_images_for_processing(car_folders, notcar_folders, image_type, orient, pix_per_cell, cell_per_block, hog_channel);
// Unpack the processed data
cv::Mat scaled_X = get<0>(processed_data);
cv::Mat labels = get<1>(processed_data);
// Split data into training and testing sets (adjust split ratio as needed)
int train_size = 0.8 * scaled_X.rows;
cv::Mat X_train = scaled_X.rowRange(0, train_size);
cv::Mat X_test = scaled_X.rowRange(train_size, scaled_X.rows);
cv::Mat labels_train = labels.rowRange(0, train_size);
cv::Mat labels_test = labels.rowRange(train_size, labels.rows);
// Train the SVM model
cv::Ptr<cv::ml::SVM> svm_model = train_svm_model(X_train, labels_train);
// Save the trained SVM model
//save_svm_model(svm_model, "C:/Users/DELL/Desktop/svm_model.xml"); // Replace with your desired filename
return 0;
}
您可以尝试打印 X 和标签的所有值来检查它们是否包含任何 NaN 或 Inf 值。