Port the SAR3D background gate, CLEAN and object boxes from Multi_depthnorm_clean
- BG_GATE_ENABLE: frame peak over its median background (sar3d_background); the GUI scales the frame with bg_gate_gain and its cloud threshold. - SAR_CLEAN_ENABLE: CLEAN of a one-frame aperture on a 4x10x4 cm search grid over the whole scene; objects in their own scale (sar3d_objects). - SAR_MARK_ENABLE: boxes by class around object groups (sar3d_marks), with the legend under the views. - SAR_VOXEL_M as three steps X/Y/Z with the notebook defaults 0.025/0.02/0.02. - GPU backend: image/download/load/project API, per-plane block reduction for the maximum, depth gate without FMA; sar3d host code built with -ffp-contract=off. - References regenerated from notebook cells 1 and 5, with new CLEAN scenes and a synthetic box-rule case; docs updated.
This commit is contained in:
@@ -1,9 +1,11 @@
|
||||
#include "sar3d_processor.hpp"
|
||||
#include "gpr_processor.hpp"
|
||||
#include "../processing/processors/src/sar3d_clean.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <complex>
|
||||
#include <iostream>
|
||||
#include <numbers>
|
||||
#include <vector>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
@@ -40,11 +42,37 @@ auto collection(const Json& source) -> ipc::PreprocessedCollection {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Boxes around given CLEAN objects, rows [x, y, z, y_low, y_high, level], in a scene with the
|
||||
// given X and Y bounds and radar placement (sar3d::marks).
|
||||
auto marks(const Json& input) -> Json {
|
||||
std::vector<processing::sar3d::CleanObject> objects;
|
||||
for (const auto& row : input.at("objects")) {
|
||||
objects.push_back({.index = {}, .position = {row.at(0), row.at(1), row.at(2)},
|
||||
.y_low = row.at(3), .y_high = row.at(4), .level = row.at(5)});
|
||||
}
|
||||
const auto x = input.at("x").get<std::vector<double>>();
|
||||
const auto y = input.at("y").get<std::vector<double>>();
|
||||
const processing::sar3d::VolumeRequest frame{
|
||||
.grid = {x, y, {}},
|
||||
.pitch_rad = input.at("pitch").get<double>() * (std::numbers::pi / 180.0),
|
||||
.ground_depth_m = input.at("ground"),
|
||||
.min_depth_m = input.at("min_depth"),
|
||||
.max_depth_m = input.at("max_depth"),
|
||||
};
|
||||
Json rows = Json::array();
|
||||
for (const auto& mark : processing::sar3d::marks(objects, frame)) {
|
||||
Json row = Json::array({static_cast<int>(mark.kind)});
|
||||
for (const double edge : mark.box) { row.push_back(edge); }
|
||||
rows.push_back(std::move(row));
|
||||
}
|
||||
return Json{{"marks", rows}};
|
||||
}
|
||||
}
|
||||
|
||||
// Runs GPR or sar3d on one request or a batch, retaining processor caches. Each request holds the antenna
|
||||
// geometry, the live settings and the latest and previous collections; the
|
||||
// published payloads go to stdout as JSON.
|
||||
// published payloads go to stdout as JSON. A request with mode "marks" boxes given objects instead.
|
||||
int main() {
|
||||
try {
|
||||
const Json source = Json::parse(std::cin);
|
||||
@@ -54,6 +82,10 @@ int main() {
|
||||
processing::Sar3dProcessor sar;
|
||||
processing::GprProcessor gpr;
|
||||
for (const auto& input : requests) {
|
||||
if (input.value("mode", "sar3d") == "marks") {
|
||||
results.push_back(marks(input));
|
||||
continue;
|
||||
}
|
||||
config::RunConfig config;
|
||||
config.rings.results.slot_size_bytes = input.value("slot", config.rings.results.slot_size_bytes);
|
||||
for (const auto& row : input.at("tx")) {
|
||||
@@ -62,6 +94,7 @@ int main() {
|
||||
for (const auto& row : input.at("rx")) {
|
||||
config.gpr.rx_geometry.push_back({row.at(0), row.at(1), row.at(2), row.at(3)});
|
||||
}
|
||||
const bool gpr_mode = input.value("mode", "sar3d") == "gpr";
|
||||
processing::ProcessingLiveConfig live;
|
||||
live.gpr_start_freq_mhz = input.at("f_start").get<double>() / 1e6;
|
||||
live.gpr_stop_freq_mhz = input.at("f_stop").get<double>() / 1e6;
|
||||
@@ -69,31 +102,39 @@ int main() {
|
||||
live.gpr_max_depth_m = input.at("max_depth");
|
||||
live.gpr_speed_m_s = input.at("speed");
|
||||
live.gpr_look_angle_deg = input.at("pitch");
|
||||
live.sar3d_voxel_m = input.at("voxel");
|
||||
live.sar3d_bp_ground_depth_m = input.at("ground");
|
||||
live.sar3d_frame_radius = input.at("radius");
|
||||
live.sar3d_comp_range_power = input.at("power");
|
||||
live.sar3d_use_compensation = input.at("compensation");
|
||||
live.sar3d_normalize_each_frame = input.at("normalize");
|
||||
live.pair_depth_equalize = input.value("equalize", true);
|
||||
live.gpr_background_subtract_enabled = input.value("subtract_mean", false);
|
||||
live.gpr_background_mean_count = input.value("mean_count", 10U);
|
||||
live.sar3d_x_size_m = input.value("x_size", 0.0F);
|
||||
live.sar3d_y_min_m = input.value("y_min", -0.5F);
|
||||
live.sar3d_y_max_m = input.value("y_max", 2.0F);
|
||||
live.sar3d_z_size_m = input.value("z_size", 0.0F);
|
||||
live.gpr_bp_ground_depth_m = input.at("ground");
|
||||
live.gpr_range_comp_power = input.at("power");
|
||||
live.gpr_motion_mode = input.value("motion", "int_minus");
|
||||
live.gpr_object_approach_min_frames = 1;
|
||||
live.gpr_remove_sidelobe_objects_enabled = false;
|
||||
if (gpr_mode) {
|
||||
live.gpr_bp_ground_depth_m = input.at("ground");
|
||||
live.gpr_range_comp_power = input.at("power");
|
||||
live.gpr_motion_mode = input.value("motion", "int_minus");
|
||||
live.gpr_object_approach_min_frames = 1;
|
||||
live.gpr_remove_sidelobe_objects_enabled = false;
|
||||
} else {
|
||||
const auto& voxel = input.at("voxel");
|
||||
live.sar3d_voxel_x_m = voxel.at(0);
|
||||
live.sar3d_voxel_y_m = voxel.at(1);
|
||||
live.sar3d_voxel_z_m = voxel.at(2);
|
||||
live.sar3d_bp_ground_depth_m = input.at("ground");
|
||||
live.sar3d_frame_radius = input.at("radius");
|
||||
live.sar3d_comp_range_power = input.at("power");
|
||||
live.sar3d_use_compensation = input.at("compensation");
|
||||
live.sar3d_normalize_each_frame = input.at("normalize");
|
||||
live.sar3d_x_size_m = input.value("x_size", 0.0F);
|
||||
live.sar3d_y_min_m = input.value("y_min", -0.5F);
|
||||
live.sar3d_y_max_m = input.value("y_max", 2.0F);
|
||||
live.sar3d_z_size_m = input.value("z_size", 0.0F);
|
||||
live.sar3d_bg_gate_enabled = input.value("bg_gate", live.sar3d_bg_gate_enabled);
|
||||
live.sar3d_clean_enabled = input.value("clean", live.sar3d_clean_enabled);
|
||||
}
|
||||
std::vector<ipc::PreprocessedCollection> previous;
|
||||
for (const auto& member : input.at("previous")) {
|
||||
previous.push_back(collection(member));
|
||||
}
|
||||
const auto latest = collection(input.at("latest"));
|
||||
for (const auto& trace : latest.traces) { config.run_combos.push_back(trace.combo); }
|
||||
processing::ProcessorInterface& processor = input.value("mode", "sar3d") == "gpr"
|
||||
processing::ProcessorInterface& processor = gpr_mode
|
||||
? static_cast<processing::ProcessorInterface&>(gpr) : static_cast<processing::ProcessorInterface&>(sar);
|
||||
const auto result = processor.process_collection(config, latest, previous, live);
|
||||
Json payloads = Json::array();
|
||||
|
||||
Reference in New Issue
Block a user