19 #define LOG_OCC_WARN(...) do { CLOG(WARNING ,"librealsense") << __VA_ARGS__; } while(false)
21 #define LOG_OCC_WARN(...)
192 _interactive_scan(false),
194 _average_step_count(-1),
195 _collected_counter(-1),
196 _collected_frame_num(-1),
197 _collected_sum(-1.0),
208 std::map<std::string, int>
values;
210 for (
auto it =
j.begin();
it !=
j.end(); ++
it)
220 std::replace(
key.begin(),
key.end(),
'_',
' ');
221 if (jsn.find(
key) != jsn.end())
234 if (Is<librealsense::device>(
handle))
239 snr = &(As<librealsense::device>(
handle)->get_sensor(0));
247 std::this_thread::sleep_for(std::chrono::milliseconds(100));
251 LOG_WARNING(
"Thermal Compensation guard failed to invoke");
263 LOG_WARNING(
"Thermal Compensation guard failed to complete");
291 std::this_thread::sleep_for(std::chrono::milliseconds(200));
299 if (!((retries++) % 5))
301 LOG_DEBUG(
"Not enough data from CALIB_STATUS!");
318 progress_func(
count);
323 }
while (
now -
start < std::chrono::milliseconds(timeout_ms) && !
done);
329 throw std::runtime_error(
"Operation timed-out!\n"
330 "Calibration state did not converge on time");
343 int apply_preset = 1;
356 int scan_only_v3 = 0;
357 int interactive_scan_v3 = 0;
370 int tmp_host_assistance(0);
372 try_fetch(jsn,
"calib type", &calib_type);
378 <<
"Auto calibration failed! Given value of 'speed' " << speed
379 <<
" is out of range (0 - 4)." );
385 try_fetch(jsn,
"host assistance", &tmp_host_assistance);
388 <<
"Auto calibration failed! Given value of 'host assistance' "
389 << tmp_host_assistance <<
" is out of range (0 - "
395 try_fetch(jsn,
"apply preset", &apply_preset);
397 try_fetch(jsn,
"fl step count", &fl_step_count);
398 try_fetch(jsn,
"fy scan range", &fy_scan_range);
399 try_fetch(jsn,
"keep new value after sucessful scan", &keep_new_value_after_sucessful_scan);
400 try_fetch(jsn,
"fl data sampling", &fl_data_sampling);
401 try_fetch(jsn,
"adjust both sides", &adjust_both_sides);
403 try_fetch(jsn,
"fl scan location", &fl_scan_location);
404 try_fetch(jsn,
"fy scan direction", &fy_scan_direction);
405 try_fetch(jsn,
"white wall mode", &white_wall_mode);
407 try_fetch(jsn,
"scan only", &scan_only_v3);
408 try_fetch(jsn,
"interactive scan", &interactive_scan_v3);
414 if (step_count_v3 > 0)
416 for (
int i = 0;
i < step_count_v3; ++
i)
419 std::stringstream
ss;
420 ss <<
"fill factor " <<
i;
428 std::vector<uint8_t> res;
473 throw std::runtime_error(
"Firmware calibration values are not yet set.");
480 std::shared_ptr<ds_advanced_mode_base> preset_recover;
495 if (interactive_scan_v3)
501 std::this_thread::sleep_for(std::chrono::milliseconds(200));
509 <<
" send occ py_rx_calib_begin, speed = " << speed <<
", p4 = " << p4 <<
" res size = " << res.size()));
517 LOG_OCC_WARN(
" occ interactive_scan_control 0,0 - save statistics ");
519 cmd.data.push_back(
p[0]);
520 cmd.data.push_back(
p[1]);
523 p =
reinterpret_cast<uint8_t*
>(fill_factor +
i);
524 cmd.data.push_back(
p[0]);
525 cmd.data.push_back(
p[1]);
534 std::this_thread::sleep_for(std::chrono::milliseconds(1000));
541 std::this_thread::sleep_for(std::chrono::milliseconds(100));
544 while(( ++iter < 3) && (!
success));
560 std::this_thread::sleep_for(std::chrono::milliseconds(100));
575 else if (calib_type == 1)
577 LOG_DEBUG(
"run_on_chip_focal_length_calibration with parameters: step count = " << fl_step_count
578 <<
", fy scan range = " << fy_scan_range <<
", keep new value after sucessful scan = " << keep_new_value_after_sucessful_scan
579 <<
", interrrupt data sampling " << fl_data_sampling <<
", adjust both sides = " << adjust_both_sides
580 <<
", fl scan location = " << fl_scan_location <<
", fy scan direction = " << fy_scan_direction <<
", white wall mode = " << white_wall_mode);
581 check_focal_length_params(fl_step_count, fy_scan_range, keep_new_value_after_sucessful_scan, fl_data_sampling, adjust_both_sides, fl_scan_location, fy_scan_direction, white_wall_mode);
585 if (keep_new_value_after_sucessful_scan)
587 if (fl_data_sampling)
589 if (adjust_both_sides)
591 if (fl_scan_location)
593 if (fy_scan_direction)
599 if (interactive_scan_v3)
605 std::this_thread::sleep_for(std::chrono::milliseconds(200));
612 static_cast< uint32_t >( fl_step_count ),
613 static_cast< uint32_t >( fy_scan_range ),
624 cmd.data.push_back(
p[0]);
625 cmd.data.push_back(
p[1]);
628 p =
reinterpret_cast<uint8_t*
>(fill_factor +
i);
629 cmd.data.push_back(
p[0]);
630 cmd.data.push_back(
p[1]);
647 std::this_thread::sleep_for(std::chrono::milliseconds(200));
673 }
while (
now -
start < std::chrono::milliseconds(timeout_ms) && !
done);
679 throw std::runtime_error(
"Operation timed-out!\n"
680 "Calibration did not converge on time");
683 std::this_thread::sleep_for(std::chrono::milliseconds(100));
696 else if (calib_type == 2)
698 LOG_DEBUG(
"run_on_chip_calibration with parameters: speed = " << speed_fl
699 <<
", keep new value after sucessful scan = " << keep_new_value_after_sucessful_scan
700 <<
" data_sampling = " <<
data_sampling <<
", adjust both sides = " << adjust_both_sides
701 <<
", fl scan location = " << fl_scan_location <<
", fy scan direction = " << fy_scan_direction <<
", white wall mode = " << white_wall_mode);
707 if (keep_new_value_after_sucessful_scan)
709 if (fl_data_sampling)
711 if (adjust_both_sides)
713 if (fl_scan_location)
715 if (fy_scan_direction)
721 if (interactive_scan_v3)
727 std::this_thread::sleep_for(std::chrono::milliseconds(200));
735 static_cast< uint32_t >( speed_fl ),
748 cmd.data.push_back(
p[0]);
749 cmd.data.push_back(
p[1]);
752 p =
reinterpret_cast<uint8_t*
>(fill_factor +
i);
753 cmd.data.push_back(
p[0]);
754 cmd.data.push_back(
p[1]);
774 std::this_thread::sleep_for(std::chrono::milliseconds(200));
783 throw std::runtime_error(
"Not enough data from CALIB_STATUS!");
788 catch (
const std::exception& ex)
806 }
while (
now -
start < std::chrono::milliseconds(timeout_ms) && !
done);
811 throw std::runtime_error(
"Operation timed-out!\n"
812 "Calibration state did not converge on time");
815 std::this_thread::sleep_for(std::chrono::milliseconds(100));
825 int health_1 =
static_cast<int>(std::abs(h_1) * 1000.0f + 0.5f);
828 int health_2 =
static_cast<int>(std::abs(h_2) * 1000.0f + 0.5f);
840 *health =
static_cast<float>(
h);
856 int apply_preset = 1;
859 std::vector<uint8_t> res;
868 try_fetch(jsn,
"average step count", &average_step_count);
869 try_fetch(jsn,
"step count", &step_count);
873 try_fetch(jsn,
"apply preset", &apply_preset);
874 int tmp_host_assistance(0);
875 try_fetch(jsn,
"host assistance", &tmp_host_assistance);
878 <<
"Auto calibration failed! Given value of 'host assistance' "
879 << tmp_host_assistance <<
" is out of range (0 - "
910 throw std::runtime_error(
"Firmware calibration values are not yet set.");
920 LOG_OCC_WARN(
"run_tare_calibration interactive control (2) with parameters: depth = " <<
depth);
928 std::shared_ptr<ds_advanced_mode_base> preset_recover;
937 std::this_thread::sleep_for(std::chrono::milliseconds(200));
940 LOG_DEBUG(
"run_tare_calibration with parameters: speed = " << speed <<
" average_step_count = " << average_step_count <<
" step_count = " << step_count <<
" accuracy = " << accuracy <<
" scan_parameter = " <<
scan_parameter <<
" data_sampling = " <<
data_sampling);
946 static_cast< uint8_t >( step_count ),
947 static_cast< uint8_t >( accuracy ),
982 std::this_thread::sleep_for(std::chrono::milliseconds(200));
992 throw std::runtime_error(
"Not enough data from CALIB_STATUS!");
998 catch (
const std::exception& ex)
1007 else if (
depth == 0)
1013 }
while (
now -
start < std::chrono::milliseconds(timeout_ms) && !
done);
1021 throw std::runtime_error(
"Operation timed-out!\n"
1022 "Calibration did not converge on time");
1028 float* ph =
reinterpret_cast<float*
>(
p);
1032 LOG_INFO(
"Ground truth: " << ground_truth_mm <<
"mm");
1033 LOG_INFO(
"Health check numbers from TareCalibrationResult(0x0C): before=" << ph[0] <<
", after=" << ph[1]);
1034 LOG_INFO(
"Z calculated from health check numbers : before=" << (ph[0] + 1) * ground_truth_mm <<
", after=" << (ph[1] + 1) * ground_truth_mm);
1045 std::this_thread::sleep_for(std::chrono::milliseconds(200));
1062 int roi_start_w = (
width - roi_w) / 2;
1063 int roi_start_h = (
height - roi_h) / 2;
1064 int from = roi_start_h;
1065 int to = roi_start_h + roi_h;
1066 int roi_size = roi_w * roi_h;
1067 int data_size = roi_size;
1070 #ifdef SAVE_RAW_IMAGE
1071 std::vector<uint16_t> cropped_image(
width *
height, 0);
1073 cropped_idx += from *
width + roi_start_w;
1076 p += from *
width + roi_start_w;
1079 for (
int j = from;
j < to; ++
j)
1081 for (
int i = 0;
i < roi_w; ++
i)
1083 #ifdef SAVE_RAW_IMAGE
1084 cropped_image[cropped_idx] = (*p);
1092 #ifdef SAVE_RAW_IMAGE
1093 cropped_idx += (
width - roi_w);
1096 #ifdef SAVE_RAW_IMAGE
1098 unsigned long milliseconds_since_epoch =
1099 std::chrono::duration_cast<std::chrono::milliseconds>
1102 std::stringstream name_s;
1103 name_s <<
"cropped_image_" << std::setfill(
'0') << std::setw(4) << milliseconds_since_epoch <<
"_" <<
frame->
get_frame_number() <<
".raw";
1105 fout.write((
char*)&cropped_image[0], cropped_image.size() *
sizeof(
uint16_t));
1109 double tmp =
static_cast<double>(
counter) /
static_cast<double>(data_size) * 10000.0;
1124 throw std::runtime_error(
rsutils::string::from() <<
"There is no enought valid data in the array!" );
1132 for (
int i = 0;
i <
size; ++
i)
1165 for (
int i = 255;
i >= 0;
i--)
1180 static const int _outlier_percentile = 9500;
1181 for (
int i = 0;
i <= 253;
i++)
1183 auto val1 =
data[
i];
1184 auto val2 =
data[
i+1];
1185 auto val3 =
data[
i+2];
1188 if ((val2 > val1) && (val2 > val3))
1190 auto diff = val3-val1;
1191 auto delta = std::max(std::abs(val2-val1),std::abs(val2-val3));
1196 if ((delta > 500) && (delta > (std::abs(diff) * 3)) && (val2 > _outlier_percentile))
1214 int roi_start_w = (
width - roi_w) / 2;
1215 int roi_start_h = (
height - roi_h) / 2;
1219 #ifdef SAVE_RAW_IMAGE
1220 std::vector<uint16_t> origin_image(
width *
height, 0);
1222 origin_image[ii] = *(
p + ii);
1225 unsigned long milliseconds_since_epoch =
1226 std::chrono::duration_cast<std::chrono::milliseconds>
1229 std::stringstream name_s;
1230 name_s <<
"origin_tare_image_" << std::setfill(
'0') << std::setw(4) << milliseconds_since_epoch <<
"_" <<
frame->
get_frame_number() <<
".raw";
1233 fout.write((
char*)&origin_image[0], origin_image.size() *
sizeof(
uint16_t));
1236 std::vector<uint16_t> cropped_image(
width *
height, 0);
1238 cropped_idx += roi_start_h *
width + roi_start_w;
1241 p += roi_start_h *
width + roi_start_w;
1243 for (
int j = 0;
j < roi_h; ++
j)
1245 for (
int i = 0;
i < roi_w; ++
i)
1247 #ifdef SAVE_RAW_IMAGE
1248 cropped_image[cropped_idx] = (*p);
1259 #ifdef SAVE_RAW_IMAGE
1260 cropped_idx += (
width - roi_w);
1263 #ifdef SAVE_RAW_IMAGE
1265 unsigned long milliseconds_since_epoch =
1266 std::chrono::duration_cast<std::chrono::milliseconds>
1269 std::stringstream name_s;
1270 name_s <<
"cropped_tare_image_" << std::setfill(
'0') << std::setw(4) << milliseconds_since_epoch <<
"_" <<
frame->
get_frame_number() <<
".raw";
1273 fout.write((
char*)&cropped_image[0], cropped_image.size() *
sizeof(
uint16_t));
1284 std::vector<uint8_t> res;
1350 #ifdef SAVE_RAW_IMAGE
1352 unsigned long milliseconds_since_epoch =
1353 std::chrono::duration_cast<std::chrono::milliseconds>
1356 std::stringstream name_s;
1357 name_s <<
"all_frame_numbers.txt";
1358 std::ofstream fout(name_s.str(), std::ios::app);
1364 #ifdef SAVE_RAW_IMAGE
1371 unsigned long milliseconds_since_epoch =
1372 std::chrono::duration_cast<std::chrono::milliseconds>
1375 std::stringstream name_s;
1376 name_s <<
"origin_image_" << std::setfill(
'0') << std::setw(4) << milliseconds_since_epoch <<
"_" <<
frame->
get_frame_number() <<
".raw";
1392 throw std::runtime_error(
"Frames arrived in a wrong order!");
1430 static const int FRAMES_TO_SKIP(1);
1440 progress_callback->on_update_progress(
static_cast<float>(20 +
static_cast<int>(progress_rate * 60.0)));
1462 std::stringstream
ss;
1463 ss <<
"{\n \"depth\":" <<
depth <<
"}";
1501 #ifdef SAVE_RAW_IMAGE
1503 std::stringstream
ss;
1504 ss <<
"{\n \"calib type\":" << 0 <<
1505 ",\n \"host assistance\":" << 2 <<
1511 std::stringstream name_s;
1512 name_s <<
"fill_factor_before_fill.txt";
1521 std::stringstream
ss;
1522 ss <<
"{\n \"calib type\":" << 0 <<
1523 ",\n \"host assistance\":" << 2 <<
1530 #ifdef SAVE_RAW_IMAGE
1532 std::stringstream name_s;
1533 name_s <<
"fill_factor.txt";
1544 std::stringstream
ss;
1545 ss <<
"{\n \"depth\":" << -1 <<
"}";
1558 catch (
const std::exception&)
1568 preset old_preset_values{};
1576 old_preset_values = advanced_mode->get_all();
1580 std::shared_ptr<ds_advanced_mode_base> recover_preset(advanced_mode, [old_preset, advanced_mode, old_preset_values](
ds_advanced_mode_base* adv)
1585 adv->
set_all(old_preset_values);
1588 advanced_mode->_preset_opt->set(
static_cast<float>(old_preset));
1591 return recover_preset;
1613 throw std::runtime_error(
"Can not cast to advance mode base");
1621 advanced_mode->_preset_opt->set(
static_cast<float>(
_old_preset));
1630 <<
"Auto calibration failed! Given value of 'speed' " << speed
1631 <<
" is out of range (0 - 4)." );
1634 <<
"Auto calibration failed! Given value of 'scan parameter' "
1638 <<
"Auto calibration failed! Given value of 'data sampling' " <<
data_sampling
1639 <<
" is out of range (0 - 1)." );
1646 if (average_step_count < 1 || average_step_count > 30)
1648 <<
"Auto calibration failed! Given value of 'number of frames to average' "
1649 << average_step_count <<
" is out of range (1 - 30)." );
1650 if (step_count < 5 || step_count > 30)
1652 <<
"Auto calibration failed! Given value of 'max iteration steps' "
1653 << step_count <<
" is out of range (5 - 30)." );
1654 if (accuracy < very_high || accuracy >
low)
1656 <<
"Auto calibration failed! Given value of 'subpixel accuracy' " << accuracy
1657 <<
" is out of range (0 - 3)." );
1660 void auto_calibrated::check_focal_length_params(
int step_count,
int fy_scan_range,
int keep_new_value_after_sucessful_scan,
int interrrupt_data_samling,
int adjust_both_sides,
int fl_scan_location,
int fy_scan_direction,
int white_wall_mode)
const
1662 if (step_count < 8 || step_count > 256)
1664 if (fy_scan_range < 1 || fy_scan_range > 60000)
1666 if (keep_new_value_after_sucessful_scan < 0 || keep_new_value_after_sucessful_scan > 1)
1668 if (interrrupt_data_samling < 0 || interrrupt_data_samling > 1)
1670 if (adjust_both_sides < 0 || adjust_both_sides > 1)
1672 if (fl_scan_location < 0 || fl_scan_location > 1)
1674 if (fy_scan_direction < 0 || fy_scan_direction > 1)
1676 if (white_wall_mode < 0 || white_wall_mode > 1)
1684 if (keep_new_value_after_sucessful_scan < 0 || keep_new_value_after_sucessful_scan > 1)
1688 if (adjust_both_sides < 0 || adjust_both_sides > 1)
1690 if (fl_scan_location < 0 || fl_scan_location > 1)
1692 if (fy_scan_direction < 0 || fy_scan_direction > 1)
1694 if (white_wall_mode < 0 || white_wall_mode > 1)
1702 throw std::runtime_error(
"Calibration didn't converge! - edges too close\n"
1703 "Please retry in different lighting conditions");
1707 throw std::runtime_error(
"Not enough depth pixels! - low fill factor)\n"
1708 "Please retry in different lighting conditions");
1712 throw std::runtime_error(
"Calibration failed to converge\n"
1713 "Please retry in different lighting conditions");
1717 throw std::runtime_error(
"Calibration didn't converge! - no depth average\n"
1718 "Please retry in different lighting conditions");
1722 <<
"Calibration didn't converge! (RESULT=" <<
int(
status ) <<
")" );
1732 throw std::runtime_error(
"Not enough data from CALIB_STATUS!");
1739 throw std::runtime_error(
"Table truncated in CALIB_STATUS!");
1741 std::vector<uint8_t> calib;
1744 memcpy(calib.data(),
header, calib.size());
1747 *health = reslt->m_dscResultParams.m_healthCheck;
1759 throw std::runtime_error(
"Not enough data from CALIB_STATUS!");
1766 throw std::runtime_error(
"Table truncated in CALIB_STATUS!");
1768 std::vector<uint8_t> calib;
1770 memcpy(calib.data(),
header, calib.size());
1773 *health_fl = reslt->FL_heathCheck;
1776 *health = reslt->healthCheck;
1785 std::vector<uint8_t> res;
1791 if (calib.size() <
sizeof(
table_header))
throw std::runtime_error(
"Missing calibration header from GETINITCAL!");
1796 if (calib.size() <
sizeof(
table_header) + hd->table_size)
1797 throw std::runtime_error(
"Table truncated from GETINITCAL!");
1800 memcpy(res.data(), hd, res.size());
1809 throw std::runtime_error(
"Write calibration can be called only after set calibration table was called");
1817 case d400_calibration_table_id::coefficients_table_id:
1820 case d400_calibration_table_id::rgb_calibration_id:
1825 throw std::runtime_error(
rsutils::string::from() <<
"Flashing calibration table type 0x" << std::hex
1826 <<
static_cast<int>(tbl_id) <<
" is not supported" );
1833 LOG_DEBUG(
"Flashing " << ((tbl_id == d400_calibration_table_id::coefficients_table_id) ?
"Depth" :
"RGB") <<
" calibration table");
1846 case d400_calibration_table_id::coefficients_table_id:
1857 LOG_ERROR(
"Flashing coefficients_table_id failed");
1861 case d400_calibration_table_id::rgb_calibration_id:
1866 <<
"the operation is not defined for calibration table type " <<
static_cast<int>(tbl_id));
1879 std::vector<std::array<float, 4>> rect_sides_arr;
1886 throw std::runtime_error(
"Extract target rectangle info - no frames in input queue!");
1902 std::array< float, 4 > rec_sides_cur{};
1905 throw std::runtime_error(
"Failed to extract target information\nfrom the captured frames!");
1906 rect_sides_arr.emplace_back(rec_sides_cur);
1915 if (rect_sides_arr.size())
1917 for (
int i = 0;
i < 4; ++
i)
1918 rect_sides[
i] = rect_sides_arr[0][
i];
1920 for (
int j = 1;
j < rect_sides_arr.size(); ++
j)
1922 for (
int i = 0;
i < 4; ++
i)
1923 rect_sides[
i] += rect_sides_arr[
j][
i];
1926 for (
int i = 0;
i < 4; ++
i)
1927 rect_sides[
i] /= rect_sides_arr.size();
1930 throw std::runtime_error(
"Failed to extract the target rectangle info!");
1936 float fx[2] = { -1.0f, -1.0f };
1937 float fy[2] = { -1.0f, -1.0f };
1939 float left_rect_sides[4] = {0.f};
1942 float right_rect_sides[4] = {0.f};
1945 std::vector<uint8_t> ret;
1946 const float correction_factor = 0.5f;
1951 float ar[2] = { 0 };
1952 float tmp = left_rect_sides[2] + left_rect_sides[3];
1954 ar[0] = (left_rect_sides[0] + left_rect_sides[1]) /
tmp;
1956 tmp = right_rect_sides[2] + right_rect_sides[3];
1958 ar[1] = (right_rect_sides[0] + right_rect_sides[1]) /
tmp;
1962 align = ar[1] / ar[0] - 1.0f;
1964 float ta[2] = { 0 };
1965 float gt[4] = { 0 };
1966 float ave_gt = 0.0f;
1968 if (left_rect_sides[0] > 0)
1969 gt[0] =
fx[0] * target_w / left_rect_sides[0];
1971 if (left_rect_sides[1] > 0)
1972 gt[1] =
fx[0] * target_w / left_rect_sides[1];
1974 if (left_rect_sides[2] > 0)
1975 gt[2] =
fy[0] * target_h / left_rect_sides[2];
1977 if (left_rect_sides[3] > 0)
1978 gt[3] =
fy[0] * target_h / left_rect_sides[3];
1981 for (
int i = 0;
i < 4; ++
i)
1985 ta[0] = atanf(
align * ave_gt / std::abs(
table->baseline));
1988 if (right_rect_sides[0] > 0)
1989 gt[0] =
fx[1] * target_w / right_rect_sides[0];
1991 if (right_rect_sides[1] > 0)
1992 gt[1] =
fx[1] * target_w / right_rect_sides[1];
1994 if (right_rect_sides[2] > 0)
1995 gt[2] =
fy[1] * target_h / right_rect_sides[2];
1997 if (right_rect_sides[3] > 0)
1998 gt[3] =
fy[1] * target_h / right_rect_sides[3];
2001 for (
int i = 0;
i < 4; ++
i)
2005 ta[1] = atanf(
align * ave_gt / std::abs(
table->baseline));
2008 *
angle = (ta[0] + ta[1]) / 2;
2013 float c =
fx[0] /
fx[1];
2015 if (left_rect_sides[0] > 0.1
f)
2016 r[0] =
c * right_rect_sides[0] / left_rect_sides[0];
2018 if (left_rect_sides[1] > 0.1
f)
2019 r[1] =
c * right_rect_sides[1] / left_rect_sides[1];
2022 if (left_rect_sides[2] > 0.1
f)
2023 r[2] =
c * right_rect_sides[2] / left_rect_sides[2];
2025 if (left_rect_sides[3] > 0.1
f)
2026 r[3] =
c * right_rect_sides[3] / left_rect_sides[3];
2029 for (
int i = 0;
i < 4; ++
i)
2036 *ratio = ra - correction_factor *
align;
2037 float ratio_to_apply = *ratio / 100.0f + 1.0f;
2039 if (adjust_both_sides)
2041 float ratio_to_apply_2 = sqrtf(ratio_to_apply);
2042 table->intrinsic_left.x.x /= ratio_to_apply_2;
2043 table->intrinsic_left.x.y /= ratio_to_apply_2;
2044 table->intrinsic_right.x.x *= ratio_to_apply_2;
2045 table->intrinsic_right.x.y *= ratio_to_apply_2;
2049 table->intrinsic_right.x.x *= ratio_to_apply;
2050 table->intrinsic_right.x.y *= ratio_to_apply;
2056 table->header.crc32 = crc;
2068 if (roi_ws < 0) roi_ws = 0;
2069 if (roi_hs < 0) roi_hs = 0;
2074 std::vector<uint8_t>
tmp(size3);
2075 memset(
tmp.data(), 0, size3);
2082 int width3 =
width * 3;
2085 for (
int j = roi_hs;
j < roi_he; ++
j)
2087 for (
int i = roi_ws;
i < roi_we; ++
i)
2089 x =
static_cast<float>(
i);
2090 y =
static_cast<float>(
j);
2097 float r2 =
x *
x +
y *
y;
2108 m =
static_cast<int>(
x + 0.5f);
2111 n =
static_cast<int>(
y + 0.5f);
2114 idx_from =
j * width3 +
i * 3;
2115 idx_to =
n * width3 +
m * 3;
2116 tmp[idx_to++] =
img[idx_from++];
2117 tmp[idx_to++] =
img[idx_from++];
2118 tmp[idx_to++] =
img[idx_from++];
2124 memmove(
img,
tmp.data(), size3);
2129 bool got_intrinsics =
false;
2130 std::vector<std::array<float, 4>> dots_x_arr;
2131 std::vector<std::array<float, 4>> dots_y_arr;
2144 if (!got_intrinsics)
2148 intrin = vsp.get_intrinsics();
2149 got_intrinsics =
true;
2159 float dots[8] = { 0 };
2162 throw std::runtime_error(
"Failed to extract target information\nfrom the captured frames!");
2164 std::array<float, 4> dots_x_cur;
2165 std::array<float, 4> dots_y_cur;
2167 for (
int i = 0;
i < 4; ++
i)
2170 dots_x_cur[
i] = dots[
j];
2171 dots_y_cur[
i] = dots[
j + 1];
2173 dots_x_arr.emplace_back(dots_x_cur);
2174 dots_y_arr.emplace_back(dots_y_cur);
2183 for (
int i = 0;
i < 4; ++
i)
2185 dots_x[
i] = dots_x_arr[0][
i];
2186 dots_y[
i] = dots_y_arr[0][
i];
2189 for (
int j = 1;
j < dots_x_arr.size(); ++
j)
2191 for (
int i = 0;
i < 4; ++
i)
2193 dots_x[
i] += dots_x_arr[
j][
i];
2194 dots_y[
i] += dots_y_arr[
j][
i];
2198 for (
int i = 0;
i < 4; ++
i)
2200 dots_x[
i] /= dots_x_arr.size();
2201 dots_y[
i] /= dots_y_arr.size();
2211 int pos_tl[4] = { 0 };
2212 int pos_tr[4] = { 0 };
2213 int pos_bl[4] = { 0 };
2214 int pos_br[4] = { 0 };
2216 float left_z_tl[4] = { 0 };
2217 float left_z_tr[4] = { 0 };
2218 float left_z_bl[4] = { 0 };
2219 float left_z_br[4] = { 0 };
2221 bool got_width =
false;
2242 for (
int i = 0;
i < 4; ++
i)
2244 x1[
i] =
static_cast<int>(left_x[
i]);
2245 y1[
i] =
static_cast<int>(left_y[
i]);
2247 x2[
i] =
static_cast<int>(left_x[
i] + 1.0f);
2248 y2[
i] =
static_cast<int>(left_y[
i] + 1.0f);
2258 for (
int i = 0;
i < 4; ++
i)
2260 left_z_tl[
i] +=
static_cast<float>(
depth[pos_tl[
i]]);
2261 left_z_tr[
i] +=
static_cast<float>(
depth[pos_tr[
i]]);
2262 left_z_bl[
i] +=
static_cast<float>(
depth[pos_bl[
i]]);
2263 left_z_br[
i] +=
static_cast<float>(
depth[pos_br[
i]]);
2272 for (
int i = 0;
i < 4; ++
i)
2286 for (
int i = 0;
i < 4; ++
i)
2288 s = left_x[
i] -
x1[
i];
2289 z_1 = (1.0f -
s) * left_z_bl[
i] +
s * left_z_br[
i];
2290 z_2 = (1.0f -
s) * left_z_tl[
i] +
s * left_z_tr[
i];
2292 s = left_y[
i] -
y1[
i];
2293 left_z[
i] = (1.0f -
s) * z_2 +
s * z_1;
2294 left_z[
i] *= 0.001f;
2301 float left_dots_x[4];
2302 float left_dots_y[4];
2307 float color_dots_x[4];
2308 float color_dots_y[4];
2318 float pixel_left[4][2] = { 0 };
2319 float point_left[4][3] = { 0 };
2321 float pixel_color[4][2] = { 0 };
2322 float pixel_color_norm[4][2] = { 0 };
2323 float point_color[4][3] = { 0 };
2325 for (
int i = 0;
i < 4; ++
i)
2327 pixel_left[
i][0] = left_dots_x[
i];
2328 pixel_left[
i][1] = left_dots_y[
i];
2333 pixel_color_norm[
i][0] = point_color[
i][0] / point_color[
i][2];
2334 pixel_color_norm[
i][1] = point_color[
i][1] / point_color[
i][2];
2339 float diff[4] = { 0 };
2341 for (
int i = 0;
i < 4; ++
i)
2343 tmp = (pixel_color[
i][0] - color_dots_x[
i]);
2347 tmp = (pixel_color[
i][1] - color_dots_y[
i]);
2351 diff[
i] = sqrtf(diff[
i]);
2354 float err_before = 0.0f;
2355 for (
int i = 0;
i < 4; ++
i)
2356 err_before += diff[
i];
2371 for (
int i = 0;
i < 4; ++
i)
2373 ppx += color_dots_x[
i] - pixel_color_norm[
i][0] *
fx;
2374 ppy += color_dots_y[
i] - pixel_color_norm[
i][1] *
fy;
2389 for (
int i = 0;
i < 4; ++
i)
2391 x += pixel_color_norm[
i][0];
2392 y += pixel_color_norm[
i][1];
2393 c_x += color_dots_x[
i];
2394 c_y += color_dots_y[
i];
2395 x_2 += pixel_color_norm[
i][0] * pixel_color_norm[
i][0];
2396 y_2 += pixel_color_norm[
i][1] * pixel_color_norm[
i][1];
2397 c_xc += color_dots_x[
i] * pixel_color_norm[
i][0];
2398 c_yc += color_dots_y[
i] * pixel_color_norm[
i][1];
2401 double d_x = 4 * x_2 -
x *
x;
2405 fx =
static_cast<float>(d_x * (4 * c_xc -
x * c_x));
2406 ppx =
static_cast<float>(d_x * (x_2 * c_x -
x * c_xc));
2409 double d_y = 4 * y_2 -
y *
y;
2413 fy =
static_cast<float>(d_y * (4 * c_yc -
y * c_y));
2414 ppy =
static_cast<float>(d_y * (y_2 * c_y -
y * c_yc));
2418 float err_after = 0.0f;
2421 for (
int i = 0;
i < 4; ++
i)
2423 tmpx = pixel_color_norm[
i][0] *
fx +
ppx - color_dots_x[
i];
2426 tmpy = pixel_color_norm[
i][1] *
fy +
ppy - color_dots_y[
i];
2429 err_after += sqrtf(tmpx + tmpy);
2434 std::vector<uint8_t> ret;
2435 const float max_change = 16.0f;
2442 health[1] =
table->intrinsic(2, 1);
2443 health[2] =
table->intrinsic(0, 0);
2444 health[3] =
table->intrinsic(1, 1);
2451 float calib_aspect_ratio = 9.f / 16.f;
2452 if (
table->calib_width &&
table->calib_height)
2453 calib_aspect_ratio = float(
table->calib_height) / float(
table->calib_width);
2456 if (actual_aspect_ratio < calib_aspect_ratio)
2458 table->intrinsic(1, 1) /= calib_aspect_ratio / actual_aspect_ratio;
2459 table->intrinsic(2, 1) /= calib_aspect_ratio / actual_aspect_ratio;
2463 table->intrinsic(0, 0) /= actual_aspect_ratio / calib_aspect_ratio;
2464 table->intrinsic(2, 0) /= actual_aspect_ratio / calib_aspect_ratio;
2470 health[0] = (std::abs(
table->intrinsic(2, 0) / health[0]) - 1) * 100;
2471 health[1] = (std::abs(
table->intrinsic(2, 1) / health[1]) - 1) * 100;
2472 health[2] = (std::abs(
table->intrinsic(0, 0) / health[2]) - 1) * 100;
2473 health[3] = (std::abs(
table->intrinsic(1, 1) / health[3]) - 1) * 100;
2482 constexpr
size_t min_frames_required = 10;
2483 bool created =
false;
2486 float target_fw = 0;
2487 float target_fh = 0;
2489 float target_z_value = -1.f;
2490 std::vector<float4> rec_sides_data;
2511 target_fh = vsp.get_intrinsics().fy * target_h;
2518 rec_sides_data.push_back(rect_sides);
2531 if (rec_sides_data.size())
2534 if ((frm_idx < min_frames_required))
2535 throw std::runtime_error(
rsutils::string::from() <<
"Target distance calculation requires at least "
2536 << min_frames_required <<
" frames, aborting" );
2537 if (
float(rec_sides_data.size() / frm_idx) < 0.5f)
2538 throw std::runtime_error(
"Please re-adjust the camera position \nand make sure the specific target is \nin the middle of the camera image!");
2541 auto avg_data = std::accumulate(rec_sides_data.begin(), rec_sides_data.end(), rect_sides);
2542 for (
auto i = 0UL;
i < 4;
i++)
2543 avg_data[
i] /= rec_sides_data.size();
2545 float gt[4] = { 0 };
2547 gt[0] = target_fw / avg_data[0];
2549 gt[1] = target_fw / avg_data[1];
2551 gt[2] = target_fh / avg_data[2];
2553 gt[3] = target_fh / avg_data[3];
2555 if (gt[0] <= 0.1
f || gt[1] <= 0.1
f || gt[2] <= 0.1
f || gt[3] <= 0.1
f)
2556 throw std::runtime_error(
"Target distance calculation failed");
2559 target_z_value = 0.f;
2560 for (
int i = 0;
i < 4; ++
i)
2561 target_z_value += gt[
i];
2562 target_z_value /= 4.f;
2564 return target_z_value;
2567 throw std::runtime_error(
"Failed to extract target dimension info!");