|
|
@@ -89,8 +89,7 @@ std::vector<float> YoloFeatureExtractor::extractFeatures(const std::string& imag
|
|
|
cv::dnn::blobFromImage(image, blob, 1.0 / 255.0, cv::Size(inputWidth, inputHeight), cv::Scalar(0, 0, 0), true, false);
|
|
|
net.setInput(blob);
|
|
|
|
|
|
- std::string info = custom_printf("✅ blob 形状:%d×%d×%d×%d\n", blob.size[0], blob.size[1], blob.size[2], blob.size[3]);
|
|
|
- DEBUG_LOG(info.c_str());
|
|
|
+ DEBUG_LOG::debug_printf("✅ blob 形状:%d×%d×%d×%d\n", blob.size[0], blob.size[1], blob.size[2], blob.size[3]);
|
|
|
|
|
|
auto time_2 = std::chrono::high_resolution_clock::now();
|
|
|
|
|
|
@@ -99,68 +98,44 @@ std::vector<float> YoloFeatureExtractor::extractFeatures(const std::string& imag
|
|
|
|
|
|
std::vector<float> features;
|
|
|
|
|
|
- int layerIndex = -6;
|
|
|
- if (layerIndex == -1)
|
|
|
+
|
|
|
+ // 选择GAP层(对于yolo2026,通常是倒数第6层)的输出作为特征向量
|
|
|
+ outputNames.push_back(layerNames[layerNames.size() - 6]);
|
|
|
+
|
|
|
+ std::vector<cv::Mat> outputs;
|
|
|
+ net.forward(outputs, outputNames);
|
|
|
+
|
|
|
+ // 检查输出是否有效
|
|
|
+ if (outputs.empty() || outputs[0].empty())
|
|
|
{
|
|
|
- outputNames.push_back(layerNames[layerNames.size() - 1]);
|
|
|
-
|
|
|
- std::vector<cv::Mat> outputs;
|
|
|
- net.forward(outputs, outputNames);
|
|
|
-
|
|
|
- for (size_t i = 0; i < outputs.size(); ++i)
|
|
|
- {
|
|
|
- cv::Mat output = outputs[i];
|
|
|
- features.reserve(features.size() + output.total());
|
|
|
- for (int j = 0; j < output.total(); ++j)
|
|
|
- {
|
|
|
- features.push_back(output.at<float>(j));
|
|
|
- }
|
|
|
- }
|
|
|
+ throw std::runtime_error("模型前向传播未产生有效输出");
|
|
|
}
|
|
|
- else if (layerIndex == -6)
|
|
|
- {
|
|
|
- // 选择GAP层(对于yolo2026,通常是倒数第6层)的输出作为特征向量
|
|
|
- outputNames.push_back(layerNames[layerNames.size() - 6]);
|
|
|
-
|
|
|
- std::vector<cv::Mat> outputs;
|
|
|
- net.forward(outputs, outputNames);
|
|
|
-
|
|
|
- // 检查输出是否有效
|
|
|
- if (outputs.empty() || outputs[0].empty())
|
|
|
- {
|
|
|
- throw std::runtime_error("模型前向传播未产生有效输出");
|
|
|
- }
|
|
|
-
|
|
|
- // 获取GAP层输出并转换为特征向量
|
|
|
- cv::Mat featuresMat = outputs[0];
|
|
|
- info = printf("✅ 原始特征形状:%d×%d,类型:%d(CV_32F=5)\n", featuresMat.cols, featuresMat.rows, featuresMat.type());
|
|
|
- DEBUG_LOG(info.c_str());
|
|
|
-
|
|
|
- cv::Mat featuresMatVec = featuresMat.reshape(1, 1);
|
|
|
- info = printf("✅ 重塑后特征形状:%d×%d,类型:%d\n", featuresMatVec.cols, featuresMatVec.rows, featuresMatVec.type());
|
|
|
- DEBUG_LOG(info.c_str());
|
|
|
|
|
|
- float norm_before = cv::norm(featuresMatVec, cv::NORM_L2);
|
|
|
- printf("📌 归一化前 norm:%.6f\n", norm_before);
|
|
|
+ // 获取GAP层输出并转换为特征向量
|
|
|
+ cv::Mat featuresMat = outputs[0];
|
|
|
+ DEBUG_LOG::debug_printf("✅ 原始特征形状:%d×%d,类型:%d(CV_32F=5)\n", featuresMat.cols, featuresMat.rows, featuresMat.type());
|
|
|
+
|
|
|
+ cv::Mat featuresMatVec = featuresMat.reshape(1, 1);
|
|
|
+ DEBUG_LOG::debug_printf("✅ 重塑后特征形状:%d×%d,类型:%d\n", featuresMatVec.cols, featuresMatVec.rows, featuresMatVec.type());
|
|
|
|
|
|
+ float norm_before = cv::norm(featuresMatVec, cv::NORM_L2);
|
|
|
+ DEBUG_LOG::debug_printf("📌 归一化前 norm:%.6f\n", norm_before);
|
|
|
|
|
|
- normalizeL2(featuresMatVec);
|
|
|
- //cv::normalize(featuresMat, featuresMat, 1.0, 0.0, cv::NORM_L2);
|
|
|
+ //normalizeL2(featuresMatVec);
|
|
|
+ cv::normalize(featuresMat, featuresMat, 1.0, 0.0, cv::NORM_L2);
|
|
|
|
|
|
- float norm_after = cv::norm(featuresMatVec, cv::NORM_L2);
|
|
|
- printf("📌 归一化后 norm:%.6f\n", norm_after);
|
|
|
+ float norm_after = cv::norm(featuresMatVec, cv::NORM_L2);
|
|
|
+ DEBUG_LOG::debug_printf("📌 归一化后 norm:%.6f\n", norm_after);
|
|
|
|
|
|
- features.reserve(features.size() + featuresMat.total());
|
|
|
- for (int j = 0; j < featuresMat.total(); ++j)
|
|
|
- {
|
|
|
- features.push_back(featuresMat.at<float>(j));
|
|
|
- }
|
|
|
+ features.reserve(features.size() + featuresMat.total());
|
|
|
+ for (int j = 0; j < featuresMat.total(); ++j)
|
|
|
+ {
|
|
|
+ features.push_back(featuresMat.at<float>(j));
|
|
|
+ }
|
|
|
|
|
|
- int a = 1;
|
|
|
|
|
|
- // 转换为std::vector<float>
|
|
|
- //features = std::vector<float>(featuresMat.begin<float>(), featuresMat.end<float>());
|
|
|
- }
|
|
|
+ // 转换为std::vector<float>
|
|
|
+ //features = std::vector<float>(featuresMat.begin<float>(), featuresMat.end<float>());
|
|
|
|
|
|
|
|
|
auto time_3 = std::chrono::high_resolution_clock::now();
|