修复人脸画框,xin2,增加了画框人脸识别结果,后面要关闭1
This commit is contained in:
parent
7b0171f48a
commit
e4b382cea3
@ -330,6 +330,9 @@ public:
|
||||
input_dtype_ = config.ValueOr<std::string>("input_dtype", input_dtype_);
|
||||
for (auto& c : input_dtype_) c = static_cast<char>(std::tolower(static_cast<unsigned char>(c)));
|
||||
|
||||
input_layout_ = config.ValueOr<std::string>("input_layout", input_layout_);
|
||||
for (auto& c : input_layout_) c = static_cast<char>(std::tolower(static_cast<unsigned char>(c)));
|
||||
|
||||
// Optional normalization when input_dtype is float.
|
||||
// - scale/bias: x = x*scale + bias
|
||||
// - mean/std: x = (x - mean[c]) / std[c]
|
||||
@ -372,6 +375,13 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
if (const SimpleJson* dbg = config.Find("debug"); dbg && dbg->IsObject()) {
|
||||
stats_log_ = dbg->ValueOr<bool>("stats", stats_log_);
|
||||
stats_interval_ = std::max<uint64_t>(
|
||||
1, static_cast<uint64_t>(dbg->ValueOr<int>("stats_interval", static_cast<int>(stats_interval_))));
|
||||
log_outputs_ = dbg->ValueOr<bool>("log_outputs", log_outputs_);
|
||||
}
|
||||
|
||||
input_queue_ = ctx.input_queue;
|
||||
output_queues_ = ctx.output_queues;
|
||||
if (!input_queue_) {
|
||||
@ -434,6 +444,10 @@ public:
|
||||
for (auto& c : dtype) c = static_cast<char>(std::tolower(static_cast<unsigned char>(c)));
|
||||
input_dtype_ = std::move(dtype);
|
||||
|
||||
std::string layout = new_config.ValueOr<std::string>("input_layout", input_layout_);
|
||||
for (auto& c : layout) c = static_cast<char>(std::tolower(static_cast<unsigned char>(c)));
|
||||
input_layout_ = std::move(layout);
|
||||
|
||||
if (const SimpleJson* norm = new_config.Find("normalize"); norm && norm->IsObject()) {
|
||||
bool use_ms = false;
|
||||
if (const SimpleJson* mean = norm->Find("mean"); mean && mean->IsArray() && mean->AsArray().size() >= 3) {
|
||||
@ -545,7 +559,8 @@ private:
|
||||
InferInput input;
|
||||
input.width = in_w;
|
||||
input.height = in_h;
|
||||
input.is_nhwc = true;
|
||||
const bool want_nchw = (input_layout_ == "nchw");
|
||||
input.is_nhwc = !want_nchw;
|
||||
|
||||
// Default: keep existing UINT8 behavior.
|
||||
if (input_dtype_ == "float" || input_dtype_ == "f32" || input_dtype_ == "float32") {
|
||||
@ -565,12 +580,39 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
input.data = float_input_buf_.data();
|
||||
input.size = float_input_buf_.size() * sizeof(float);
|
||||
const float* fp = float_input_buf_.data();
|
||||
if (want_nchw) {
|
||||
float_input_nchw_buf_.resize(pix * 3);
|
||||
for (int c = 0; c < 3; ++c) {
|
||||
float* dst = float_input_nchw_buf_.data() + static_cast<size_t>(c) * pix;
|
||||
for (size_t i = 0; i < pix; ++i) {
|
||||
dst[i] = fp[i * 3 + static_cast<size_t>(c)];
|
||||
}
|
||||
}
|
||||
input.data = float_input_nchw_buf_.data();
|
||||
input.size = float_input_nchw_buf_.size() * sizeof(float);
|
||||
} else {
|
||||
input.data = float_input_buf_.data();
|
||||
input.size = float_input_buf_.size() * sizeof(float);
|
||||
}
|
||||
input.type = RKNN_TENSOR_FLOAT32;
|
||||
} else {
|
||||
input.data = input_ptr;
|
||||
input.size = in_size;
|
||||
if (want_nchw) {
|
||||
const size_t pix = static_cast<size_t>(in_w) * static_cast<size_t>(in_h);
|
||||
input_nchw_buf_.resize(pix * 3);
|
||||
const uint8_t* p = reinterpret_cast<const uint8_t*>(input_ptr);
|
||||
for (int c = 0; c < 3; ++c) {
|
||||
uint8_t* dst = input_nchw_buf_.data() + static_cast<size_t>(c) * pix;
|
||||
for (size_t i = 0; i < pix; ++i) {
|
||||
dst[i] = p[i * 3 + static_cast<size_t>(c)];
|
||||
}
|
||||
}
|
||||
input.data = input_nchw_buf_.data();
|
||||
input.size = input_nchw_buf_.size();
|
||||
} else {
|
||||
input.data = input_ptr;
|
||||
input.size = in_size;
|
||||
}
|
||||
input.type = RKNN_TENSOR_UINT8;
|
||||
}
|
||||
|
||||
@ -580,6 +622,31 @@ private:
|
||||
return;
|
||||
}
|
||||
|
||||
if (log_outputs_ && !r.outputs.empty()) {
|
||||
// Print basic output tensor info a few times for debugging model mismatches.
|
||||
if (printed_outputs_ < 3) {
|
||||
++printed_outputs_;
|
||||
for (size_t i = 0; i < r.outputs.size(); ++i) {
|
||||
const auto& o = r.outputs[i];
|
||||
std::string shape;
|
||||
shape.reserve(64);
|
||||
shape.push_back('[');
|
||||
for (size_t d = 0; d < o.dims.size(); ++d) {
|
||||
shape += std::to_string(o.dims[d]);
|
||||
if (d + 1 < o.dims.size()) shape += ",";
|
||||
}
|
||||
shape.push_back(']');
|
||||
std::cerr << "[ai_face_det] out" << i
|
||||
<< " type=" << static_cast<int>(o.type)
|
||||
<< " zp=" << o.zp
|
||||
<< " scale=" << o.scale
|
||||
<< " dims=" << shape
|
||||
<< " size=" << o.size
|
||||
<< "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<Tensor> tensors;
|
||||
tensors.reserve(r.outputs.size());
|
||||
for (const auto& o : r.outputs) {
|
||||
@ -599,6 +666,18 @@ private:
|
||||
det.model_name = "retinaface";
|
||||
|
||||
DecodeRetinaFace(tensors, src_w, src_h, in_w, in_h, det);
|
||||
|
||||
++processed_;
|
||||
if (stats_log_ && stats_interval_ > 0 && (processed_ % stats_interval_) == 0) {
|
||||
const size_t n = det.faces.size();
|
||||
const float best = n > 0 ? det.faces[0].score : 0.0f;
|
||||
std::cerr << "[ai_face_det] frame=" << frame->frame_id
|
||||
<< " faces=" << n
|
||||
<< " best=" << best
|
||||
<< " conf_thr=" << conf_thresh_
|
||||
<< " nms=" << nms_thresh_
|
||||
<< "\n";
|
||||
}
|
||||
frame->face_det = std::make_shared<FaceDetResult>(std::move(det));
|
||||
}
|
||||
|
||||
@ -608,7 +687,8 @@ private:
|
||||
FaceDetResult& out) {
|
||||
// Find loc/conf/landms tensors.
|
||||
std::vector<NcTensor> locs;
|
||||
std::vector<NcTensor> confs;
|
||||
std::vector<NcTensor> confs; // Nx2
|
||||
std::vector<NcTensor> confs1; // Nx1 (some models)
|
||||
std::vector<NcTensor> landms;
|
||||
locs.reserve(4);
|
||||
confs.reserve(4);
|
||||
@ -624,12 +704,16 @@ private:
|
||||
confs.push_back(std::move(tmp));
|
||||
continue;
|
||||
}
|
||||
if (ExtractNc(t, 1, tmp)) {
|
||||
confs1.push_back(std::move(tmp));
|
||||
continue;
|
||||
}
|
||||
if (ExtractNc(t, 10, tmp)) {
|
||||
landms.push_back(std::move(tmp));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (locs.empty() || confs.empty()) return;
|
||||
if (locs.empty() || (confs.empty() && confs1.empty())) return;
|
||||
|
||||
// Concatenate along N.
|
||||
auto Concat = [](const std::vector<NcTensor>& parts) -> NcTensor {
|
||||
@ -650,7 +734,15 @@ private:
|
||||
};
|
||||
|
||||
NcTensor loc = Concat(locs);
|
||||
NcTensor conf = Concat(confs);
|
||||
NcTensor conf;
|
||||
bool conf_is_2 = false;
|
||||
if (!confs.empty()) {
|
||||
conf = Concat(confs);
|
||||
conf_is_2 = true;
|
||||
} else {
|
||||
conf = Concat(confs1);
|
||||
conf_is_2 = false;
|
||||
}
|
||||
NcTensor lmk;
|
||||
if (output_landmarks_ && !landms.empty()) lmk = Concat(landms);
|
||||
|
||||
@ -678,13 +770,19 @@ private:
|
||||
constexpr float var1 = 0.2f;
|
||||
|
||||
for (int i = 0; i < n; ++i) {
|
||||
const float s0 = conf.data[static_cast<size_t>(i) * 2 + 0];
|
||||
const float s1 = conf.data[static_cast<size_t>(i) * 2 + 1];
|
||||
float score;
|
||||
if (s0 >= 0.0f && s0 <= 1.0f && s1 >= 0.0f && s1 <= 1.0f && std::fabs((s0 + s1) - 1.0f) < 0.1f) {
|
||||
score = s1;
|
||||
float score = 0.0f;
|
||||
if (conf_is_2) {
|
||||
const float s0 = conf.data[static_cast<size_t>(i) * 2 + 0];
|
||||
const float s1 = conf.data[static_cast<size_t>(i) * 2 + 1];
|
||||
if (s0 >= 0.0f && s0 <= 1.0f && s1 >= 0.0f && s1 <= 1.0f && std::fabs((s0 + s1) - 1.0f) < 0.1f) {
|
||||
score = s1;
|
||||
} else {
|
||||
score = Softmax2(s0, s1);
|
||||
}
|
||||
} else {
|
||||
score = Softmax2(s0, s1);
|
||||
const float s = conf.data[static_cast<size_t>(i)];
|
||||
if (s >= 0.0f && s <= 1.0f) score = s;
|
||||
else score = Sigmoid(s);
|
||||
}
|
||||
if (score < conf_thresh_) continue;
|
||||
|
||||
@ -772,6 +870,7 @@ private:
|
||||
|
||||
// Model input dtype: "uint8" (default) or "float32".
|
||||
std::string input_dtype_ = "uint8";
|
||||
std::string input_layout_ = "nhwc";
|
||||
float norm_scale_ = 1.0f;
|
||||
float norm_bias_ = 0.0f;
|
||||
bool norm_use_mean_std_ = false;
|
||||
@ -785,12 +884,20 @@ private:
|
||||
std::vector<std::shared_ptr<SpscQueue<FramePtr>>> output_queues_;
|
||||
|
||||
std::vector<uint8_t> input_buf_;
|
||||
std::vector<uint8_t> input_nchw_buf_;
|
||||
std::vector<float> float_input_buf_;
|
||||
std::vector<float> float_input_nchw_buf_;
|
||||
|
||||
ModelHandle model_handle_ = kInvalidModelHandle;
|
||||
int model_w_ = 320;
|
||||
int model_h_ = 320;
|
||||
uint32_t n_output_ = 0;
|
||||
|
||||
bool stats_log_ = false;
|
||||
uint64_t stats_interval_ = 100;
|
||||
bool log_outputs_ = false;
|
||||
uint64_t processed_ = 0;
|
||||
int printed_outputs_ = 0;
|
||||
};
|
||||
|
||||
REGISTER_NODE(AiFaceDetNode, "ai_face_det");
|
||||
|
||||
@ -572,6 +572,9 @@ public:
|
||||
input_dtype_ = config.ValueOr<std::string>("input_dtype", input_dtype_);
|
||||
for (auto& c : input_dtype_) c = static_cast<char>(std::tolower(static_cast<unsigned char>(c)));
|
||||
|
||||
input_layout_ = config.ValueOr<std::string>("input_layout", input_layout_);
|
||||
for (auto& c : input_layout_) c = static_cast<char>(std::tolower(static_cast<unsigned char>(c)));
|
||||
|
||||
if (const SimpleJson* norm = config.Find("normalize"); norm && norm->IsObject()) {
|
||||
if (const SimpleJson* mean = norm->Find("mean"); mean && mean->IsArray() && mean->AsArray().size() >= 3) {
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
@ -667,6 +670,10 @@ public:
|
||||
for (auto& c : dtype) c = static_cast<char>(std::tolower(static_cast<unsigned char>(c)));
|
||||
input_dtype_ = std::move(dtype);
|
||||
|
||||
std::string layout = new_config.ValueOr<std::string>("input_layout", input_layout_);
|
||||
for (auto& c : layout) c = static_cast<char>(std::tolower(static_cast<unsigned char>(c)));
|
||||
input_layout_ = std::move(layout);
|
||||
|
||||
if (const SimpleJson* norm = new_config.Find("normalize"); norm && norm->IsObject()) {
|
||||
bool use_ms = false;
|
||||
if (const SimpleJson* mean = norm->Find("mean"); mean && mean->IsArray() && mean->AsArray().size() >= 3) {
|
||||
@ -818,7 +825,8 @@ private:
|
||||
InferInput in;
|
||||
in.width = model_w_;
|
||||
in.height = model_h_;
|
||||
in.is_nhwc = true;
|
||||
const bool want_nchw = (input_layout_ == "nchw");
|
||||
in.is_nhwc = !want_nchw;
|
||||
|
||||
if (input_dtype_ == "float" || input_dtype_ == "f32" || input_dtype_ == "float32") {
|
||||
float_input_buf_.resize(static_cast<size_t>(model_w_) * static_cast<size_t>(model_h_) * 3);
|
||||
@ -837,12 +845,39 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
in.data = float_input_buf_.data();
|
||||
in.size = float_input_buf_.size() * sizeof(float);
|
||||
const float* fp = float_input_buf_.data();
|
||||
if (want_nchw) {
|
||||
float_input_nchw_buf_.resize(pix * 3);
|
||||
for (int c = 0; c < 3; ++c) {
|
||||
float* dst = float_input_nchw_buf_.data() + static_cast<size_t>(c) * pix;
|
||||
for (size_t i = 0; i < pix; ++i) {
|
||||
dst[i] = fp[i * 3 + static_cast<size_t>(c)];
|
||||
}
|
||||
}
|
||||
in.data = float_input_nchw_buf_.data();
|
||||
in.size = float_input_nchw_buf_.size() * sizeof(float);
|
||||
} else {
|
||||
in.data = float_input_buf_.data();
|
||||
in.size = float_input_buf_.size() * sizeof(float);
|
||||
}
|
||||
in.type = RKNN_TENSOR_FLOAT32;
|
||||
} else {
|
||||
in.data = face_buf_.data();
|
||||
in.size = face_buf_.size();
|
||||
if (want_nchw) {
|
||||
const size_t pix = static_cast<size_t>(model_w_) * static_cast<size_t>(model_h_);
|
||||
input_nchw_buf_.resize(pix * 3);
|
||||
const uint8_t* p = face_buf_.data();
|
||||
for (int c = 0; c < 3; ++c) {
|
||||
uint8_t* dst = input_nchw_buf_.data() + static_cast<size_t>(c) * pix;
|
||||
for (size_t i = 0; i < pix; ++i) {
|
||||
dst[i] = p[i * 3 + static_cast<size_t>(c)];
|
||||
}
|
||||
}
|
||||
in.data = input_nchw_buf_.data();
|
||||
in.size = input_nchw_buf_.size();
|
||||
} else {
|
||||
in.data = face_buf_.data();
|
||||
in.size = face_buf_.size();
|
||||
}
|
||||
in.type = RKNN_TENSOR_UINT8;
|
||||
}
|
||||
|
||||
@ -899,6 +934,7 @@ private:
|
||||
std::string model_input_format_ = "rgb";
|
||||
|
||||
std::string input_dtype_ = "uint8";
|
||||
std::string input_layout_ = "nhwc";
|
||||
float norm_scale_ = 1.0f;
|
||||
float norm_bias_ = 0.0f;
|
||||
bool norm_use_mean_std_ = false;
|
||||
@ -916,7 +952,9 @@ private:
|
||||
std::vector<std::shared_ptr<SpscQueue<FramePtr>>> output_queues_;
|
||||
|
||||
std::vector<uint8_t> face_buf_;
|
||||
std::vector<uint8_t> input_nchw_buf_;
|
||||
std::vector<float> float_input_buf_;
|
||||
std::vector<float> float_input_nchw_buf_;
|
||||
|
||||
ModelHandle model_handle_ = kInvalidModelHandle;
|
||||
int model_w_ = 112;
|
||||
|
||||
@ -10,6 +10,7 @@
|
||||
|
||||
#include "face/face_result.h"
|
||||
#include "node.h"
|
||||
#include "utils/dma_alloc.h"
|
||||
#include "utils/logger.h"
|
||||
|
||||
namespace rk3588 {
|
||||
@ -335,9 +336,18 @@ public:
|
||||
if (out.use_count() > 1) {
|
||||
out = CloneFrameForWrite(out);
|
||||
}
|
||||
|
||||
// If we are drawing directly onto a DMA-BUF backed frame, we must sync CPU caches,
|
||||
// otherwise downstream HW (RGA/encoder) may not see the updated pixels.
|
||||
if (out->dma_fd >= 0 && out->data) {
|
||||
DmaSyncStartFd(out->dma_fd);
|
||||
}
|
||||
DrawDetections(out);
|
||||
DrawFaceDet(out);
|
||||
DrawFaceRecog(out);
|
||||
if (out->dma_fd >= 0 && out->data) {
|
||||
DmaSyncEndFd(out->dma_fd);
|
||||
}
|
||||
}
|
||||
|
||||
PushToDownstream(out);
|
||||
|
||||
@ -174,6 +174,8 @@ ModelHandle AiScheduler::LoadModel(const std::string& model_path, std::string& e
|
||||
" (handle=" + std::to_string(handle) +
|
||||
", input=" + std::to_string(ctx->input_w) + "x" + std::to_string(ctx->input_h) +
|
||||
"x" + std::to_string(ctx->input_c) +
|
||||
", fmt=" + std::string(ctx->input_attrs[0].fmt == RKNN_TENSOR_NCHW ? "NCHW" : "NHWC") +
|
||||
", dtype=" + std::to_string(static_cast<int>(ctx->input_attrs[0].type)) +
|
||||
", outputs=" + std::to_string(ctx->n_output) + ")");
|
||||
|
||||
return handle;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user