#include "classifier.hpp" #include namespace auto_aim { Classifier::Classifier(const std::string & config_path) { auto yaml = YAML::LoadFile(config_path); auto model = yaml["classify_model"].as(); net_ = cv::dnn::readNetFromONNX(model); auto ovmodel = core_.read_model(model); compiled_model_ = core_.compile_model( ovmodel, "AUTO", ov::hint::performance_mode(ov::hint::PerformanceMode::LATENCY)); } void Classifier::classify(Armor & armor) { if (armor.pattern.empty()) { armor.name = ArmorName::not_armor; return; } cv::Mat gray; cv::cvtColor(armor.pattern, gray, cv::COLOR_BGR2GRAY); auto input = cv::Mat(32, 32, CV_8UC1, cv::Scalar(0)); auto x_scale = static_cast(32) / gray.cols; auto y_scale = static_cast(32) / gray.rows; auto scale = std::min(x_scale, y_scale); auto h = static_cast(gray.rows * scale); auto w = static_cast(gray.cols * scale); if (h == 0 || w == 0) { armor.name = ArmorName::not_armor; return; } auto roi = cv::Rect(0, 0, w, h); cv::resize(gray, input(roi), {w, h}); auto blob = cv::dnn::blobFromImage(input, 1.0 / 255.0, cv::Size(), cv::Scalar()); net_.setInput(blob); cv::Mat outputs = net_.forward(); // softmax float max = *std::max_element(outputs.begin(), outputs.end()); cv::exp(outputs - max, outputs); float sum = cv::sum(outputs)[0]; outputs /= sum; double confidence; cv::Point label_point; cv::minMaxLoc(outputs.reshape(1, 1), nullptr, &confidence, nullptr, &label_point); int label_id = label_point.x; armor.confidence = confidence; armor.name = static_cast(label_id); } void Classifier::ovclassify(Armor & armor) { if (armor.pattern.empty()) { armor.name = ArmorName::not_armor; return; } cv::Mat gray; cv::cvtColor(armor.pattern, gray, cv::COLOR_BGR2GRAY); // Resize image to 32x32 auto input = cv::Mat(32, 32, CV_8UC1, cv::Scalar(0)); auto x_scale = static_cast(32) / gray.cols; auto y_scale = static_cast(32) / gray.rows; auto scale = std::min(x_scale, y_scale); auto h = static_cast(gray.rows * scale); auto w = static_cast(gray.cols * scale); if (h == 0 || w == 0) { armor.name = ArmorName::not_armor; return; } auto roi = cv::Rect(0, 0, w, h); cv::resize(gray, input(roi), {w, h}); // Normalize the input image to [0, 1] range input.convertTo(input, CV_32F, 1.0 / 255.0); ov::Tensor input_tensor(ov::element::f32, {1, 1, 32, 32}, input.data); ov::InferRequest infer_request = compiled_model_.create_infer_request(); infer_request.set_input_tensor(input_tensor); infer_request.infer(); auto output_tensor = infer_request.get_output_tensor(); auto output_shape = output_tensor.get_shape(); cv::Mat outputs(1, 9, CV_32F, output_tensor.data()); // Softmax float max = *std::max_element(outputs.begin(), outputs.end()); cv::exp(outputs - max, outputs); float sum = cv::sum(outputs)[0]; outputs /= sum; double confidence; cv::Point label_point; cv::minMaxLoc(outputs.reshape(1, 1), nullptr, &confidence, nullptr, &label_point); int label_id = label_point.x; armor.confidence = confidence; armor.name = static_cast(label_id); } } // namespace auto_aim