summaryrefslogtreecommitdiff
path: root/src/profile.cpp
diff options
context:
space:
mode:
authorNikita Kostovsky <nikita@kostovsky.me>2025-02-21 07:27:00 +0100
committerNikita Kostovsky <nikita@kostovsky.me>2025-02-21 07:27:00 +0100
commitd12498504c279a0a85bbfb024f7903e34dbe07db (patch)
tree0df9f3f8bf27470ac211a57bb8e44be0aa2f6138 /src/profile.cpp
parent27637ab117d8738236f6ab155300ff6e79e4843b (diff)
broken img calc; change dir struct
Diffstat (limited to 'src/profile.cpp')
-rw-r--r--src/profile.cpp155
1 files changed, 155 insertions, 0 deletions
diff --git a/src/profile.cpp b/src/profile.cpp
new file mode 100644
index 0000000..2c7b9a9
--- /dev/null
+++ b/src/profile.cpp
@@ -0,0 +1,155 @@
+#include "profile.h"
+
+#include <iostream>
+
+#include <QDebug>
+#include <QJsonArray>
+
+Profile::Profile(
+ const Pixels& pixels,
+ const CalibrationTablePtr calibrationTableZ,
+ const CalibrationTablePtr calibrationTableX)
+ : m_counters(pixels.counters)
+{
+ if (!calibrationTableZ || !calibrationTableX)
+ {
+ std::cerr << __func__ << ": got invalid calibration tables"
+ << std::endl;
+
+ return;
+ }
+
+ static bool done{false};
+
+ if (!done) {
+ for (size_t i = 9471; i < 9472; i++) {
+ std::cout << __func__ << ": row #" << i << ": ";
+
+ for (size_t j = 0; j < 1280; ++j) {
+ const auto& x = calibrationTableX->at(j).at(i);
+ const auto& z = calibrationTableZ->at(j).at(i);
+ std::cout << "Profile: table: " << x << ' ' << z << std::endl;
+ }
+
+ std::cout << std::endl;
+ }
+ }
+
+ for (size_t i = 0; i < img_width; ++i) {
+ try {
+ const auto& pixel = pixels.pixels[i];
+ const auto pixelDiscrete = pixel * discretesInRage / img_height;
+ if (Q_UNLIKELY(pixel >= sizeof(CalibrationColumn) / sizeof(float))) {
+ qWarning() << "got invalid calibration pixel at" << i << ":"
+ << pixel;
+ m_counters = {};
+ m_pointsMm = {QPointF{std::nan(""), std::nan("")}};
+ return;
+ }
+
+ if (Q_UNLIKELY(pixel == sizeof(CalibrationColumn) - 1)) {
+ qDebug() << "Profile: got edge value";
+ const auto& z = calibrationTableZ->at(i).at(pixelDiscrete);
+
+ if (qFuzzyIsNull(z) || std::isnan(z)) {
+ m_pointsMm.at(i) = {std::nan(""), std::nan("")};
+ continue;
+ }
+
+ const auto& x = calibrationTableX->at(i).at(pixelDiscrete);
+ m_pointsMm.at(i) = {x, z};
+
+ continue;
+ }
+
+ const auto& leftMmZ = calibrationTableZ->at(i).at(
+ size_t(pixelDiscrete));
+ const auto& rightMmZ = calibrationTableZ->at(i).at(
+ size_t(pixelDiscrete) + 1);
+
+ const auto& leftMmX = calibrationTableX->at(i).at(
+ size_t(pixelDiscrete));
+ const auto& rightMmX = calibrationTableX->at(i).at(
+ size_t(pixelDiscrete) + 1);
+
+ const auto& fract = pixelDiscrete - long(pixelDiscrete);
+
+ const auto z = (leftMmZ * (1 - fract) + rightMmZ * fract);
+
+ // TODO: use only NaN (or zero?) everywhere
+ // NOTE: QJsonValue converts NaN to zero
+ if (qFuzzyIsNull(z) || std::isnan(z)) {
+ // qDebug() << "got nan z for discrete" << pixelDiscrete << leftMmZ
+ // << rightMmZ;
+ m_pointsMm.at(i) = {std::nan(""), std::nan("")};
+ continue;
+ }
+
+ const auto x = (leftMmX * (1 - fract) + rightMmX * fract);
+
+ m_pointsMm.at(i) = {x, z};
+
+ if (!done) {
+ qDebug() << "got these values\t" << pixels.pixels[i]
+ << pixelDiscrete << m_pointsMm[i] << leftMmZ
+ << rightMmZ << leftMmX << rightMmX;
+ }
+ } catch (const std::out_of_range& ex) {
+ qWarning() << "out of range exception:" << ex.what();
+ qWarning() << "i:" << i; // << "pixels[i]" << pixels.pixels[i];
+ m_counters = {};
+ m_pointsMm = {QPointF{std::nan(""), std::nan("")}};
+
+ return;
+ } catch (const std::exception& ex) {
+ qWarning() << "exception:" << ex.what();
+ qWarning() << "i:" << i << "pixels[i]" << pixels.pixels[i];
+ m_counters = {};
+ m_pointsMm = {QPointF{std::nan(""), std::nan("")}};
+
+ return;
+ } catch (...) {
+ qWarning() << "unknown exception";
+ m_counters = {};
+ m_pointsMm = {QPointF{std::nan(""), std::nan("")}};
+ return;
+ }
+ }
+
+ done = true;
+
+ // static bool printOnce = [&]() -> bool {
+ // for (size_t i = 0; i < m_pointsMm.size(); ++i) {
+ // qDebug() << '\t' << pixels.pixels[i] << m_pointsMm[i];
+ // }
+
+ // return true;
+ // }();
+}
+
+const Counters& Profile::counters() const
+{
+ return m_counters;
+}
+
+const Profile::PointsMm& Profile::pointsMm() const
+{
+ return m_pointsMm;
+}
+
+Profile::operator const QJsonObject() const
+{
+ QJsonObject counters{
+ {"timestampUs", qint64(m_counters.timestampUs)},
+ {"measurementCounter", qint64(m_counters.measurementCounter)},
+ {"encoderPosition", qint64(m_counters.encoderPosition)},
+ };
+
+ QJsonArray jsonPoints;
+
+ for (const auto& p : m_pointsMm) {
+ jsonPoints << QJsonArray{p.x(), p.y()};
+ }
+
+ return {{"counters", counters}, {"pointsMm", jsonPoints}};
+}