From 9dde2ab53c8e2c97647164fce89cf149260fbc8f Mon Sep 17 00:00:00 2001 From: Nikita Kostovsky Date: Sun, 12 Jan 2025 11:50:34 +0100 Subject: implement calibration --- main.cpp | 845 +++++++++++++-------------------------------------------------- 1 file changed, 174 insertions(+), 671 deletions(-) (limited to 'main.cpp') diff --git a/main.cpp b/main.cpp index 9304ed9..431e82d 100644 --- a/main.cpp +++ b/main.cpp @@ -8,12 +8,15 @@ #include #include "LibCamera.h" +#include "calibration.h" +#include "dumps.h" #include "fuck_intel.h" #include "genetic_algos.h" #include "httpservice.h" #include "imagealgos.h" #include "pigpio.h" #include "printerclient.h" +#include "profile.h" #include "rotaryencoder.h" #include @@ -28,47 +31,23 @@ #include #include #include -#include - -// #define FIRST_COLUMN_ONLY - -#define try_apply_config() \ - if (!applyConfig(config)) \ - { \ - camera->release(); \ - cm->stop(); \ - \ - return EXIT_FAILURE; \ +#include + +#define try_apply_config() \ + if (!applyConfig(config)) { \ + camera->release(); \ + cm->stop(); \ +\ + return EXIT_FAILURE; \ } -const QString exposureTimeKey = "exposureTime"; -const QString laserLevelKey = "laserLevel"; - -enum ScanningModeFlags : uint8_t -{ - None = 0, - Calibration -}; - -// ScanningModeFlags operator|(ScanningModeFlags lhs, ScanningModeFlags rhs) -// { -// using T = std::underlying_type::type; -// return static_cast(static_cast(lhs) | -// static_cast(rhs)); -// } - ScanningModeFlags scanningModeFlags{ScanningModeFlags::None}; QElapsedTimer calibrationTimer; extern volatile int32_t positionSteps; -struct requested_params_t -{ - int32_t exposureTime = {1000}; - int32_t laserLevel = {3000}; - uint32_t stepsPerMm{200}; -} requested_params; +requested_params_t requested_params; namespace { @@ -78,8 +57,6 @@ std::vector calibrationPixels; QMutex calibrationPixelsMutex; } // namespace -const QString dumpsRoot{QStringLiteral("/home/user/dumps")}; - using namespace std::chrono_literals; static std::shared_ptr camera; @@ -88,21 +65,10 @@ static std::map> mappedBuffers_; std::vector> requests; libcamera::ControlList lastControls; -static QList openDump(const QString& dumpPath = ""); -static std::optional openRawProfile(const QString& filePath); -constexpr float hardcodedZRangeMm{175.f}; -constexpr size_t calibrationTableHeight{0x4000}; // 16384 -// img_width * calibrationTableHeight -using CalibrationColumn = std::array; -using CalibrationTable = std::array; -constexpr auto calibrationColumnHeight = std::tuple_size(); -// CalibrationTable* calibrationTable { new CalibrationTable {{ 0 }} }; - namespace { -QSharedPointer calibrationTableZ; -QSharedPointer calibrationTableX; -constexpr uint16_t discretesInRage{16384}; +CalibrationTablePtr calibrationTableZ; +CalibrationTablePtr calibrationTableX; } // namespace static bool applyConfig( @@ -110,21 +76,7 @@ static bool applyConfig( ); static void onRequestCompleted(libcamera::Request* completed_request); static void printControls(); -static void dumpCalibrationPixels(); static QList filter(const QList& rawProfiles); -static QSharedPointer calibrateX( - const QList& rawProfiles -); -static QSharedPointer calibrateZ( - const QList& rawProfiles -); - -static QImage calibrationTableToImage( - const QSharedPointer& calibrationTable -); - -static void interpolate(QSharedPointer& table); -static void interpolate(CalibrationColumn& column); auto printPixels = [](const auto& pixels) { for (size_t i = (img_width - 10) / 2; @@ -142,24 +94,87 @@ int main(int argc, char* argv[]) { QCoreApplication app(argc, argv); - if (!initLaser()) - { - return EXIT_FAILURE; - } - - PrinterClient printerClient; - // if (false) qDebug() << "size of raw profile" << sizeof(Pixels); if (true) { - // auto rawProfiles = openDump("/home/user/dumps/2024.11.24_19.17.32"); - // auto rawProfiles = openDump("/home/user/dumps/2024.11.26_21.53.55"); - // auto rawProfiles = - // openDump("/home/user/dumps/2024.11.26_21.53.55_small"); + if (false) { + // z + // if (!openCalibrationTable( + // "/home/user/dumps/binz.calibration_table", + // ::calibrationTableZ + // )) + // { + // exit(EXIT_FAILURE); + // } - { - auto rawProfiles = openDump("/home/user/dumps/2024.12.07_14.09.33"); + // if (!calibrationTableToImage(::calibrationTableZ) + // .save("/home/user/dumps/imageZ.png")) + // { + // qDebug() << "cannot save imageZ.png"; + // exit(EXIT_FAILURE); + // } + + // interpolate(::calibrationTableZ); + // exit(EXIT_SUCCESS); + + // calibrationTableToImage(::calibrationTableZ) + // .save("/home/user/dumps/imageZ_interpolated.png"); + + auto rawProfiles = openDump("/home/user/dumps/binx"); + qDebug() << "raw x-profiles count is" << rawProfiles.size(); + // qDebug() << "height" << calibrationColumnHeight; + + auto filteredRawProfiles = filter(std::move(rawProfiles)); + qDebug() << "filtered x-profiles count is" + << filteredRawProfiles.count(); + + ::calibrationTableX = calibrateX(std::move(filteredRawProfiles)); + + for (size_t i = 9471; i < 9472; i++) { + std::cout << "row #" << i << ": "; + + for (size_t j = 0; j < 1280; ++j) { + const auto& p = ::calibrationTableX->at(j).at(i); + std::cout << p << ' '; + } + + std::cout << std::endl; + } + + // x + qDebug() << "open x table"; + if (!openCalibrationTable("/home/user/dumps/binx.calibration_table", + ::calibrationTableX)) { + exit(EXIT_FAILURE); + } + + // if (!calibrationTableToImage(::calibrationTableX) + // .save("/home/user/dumps/imageX.png")) { + // qDebug() << "cannot save imageX.png"; + // exit(EXIT_FAILURE); + // } + + for (size_t i = 9471; i < 9472; i++) { + std::cout << "row #" << i << ": "; + + for (size_t j = 0; j < 1280; ++j) { + const auto& p = ::calibrationTableX->at(j).at(i); + std::cout << p << ' '; + } + + std::cout << std::endl; + } + + exit(EXIT_SUCCESS); + interpolate(::calibrationTableX); + + // calibrationTableToImage(::calibrationTableX) + // .save("/home/user/dumps/imageX_interpolated.png"); + } + + if (true) { + auto rawProfiles = openDump("/home/user/dumps/binz"); // auto rawProfiles = openDump("/home/user/dumps/z"); qDebug() << "raw z-profiles count is" << rawProfiles.size(); // qDebug() << "height" << calibrationColumnHeight; @@ -168,26 +183,36 @@ int main(int argc, char* argv[]) qDebug() << "filtered z-profiles count is" << filteredRawProfiles.count(); - ::calibrationTableZ = calibrateZ(std::move(filteredRawProfiles)); + ::calibrationTableZ = calibrateZ(std::move(filteredRawProfiles), + requested_params.stepsPerMm); + // if (!dump( + // ::calibrationTableZ, + // "/home/user/dumps/binz.calibration_table" + // )) + // { + // qApp->exit(EXIT_FAILURE); + // } - bool ok = calibrationTableToImage(::calibrationTableZ) - .save("/home/user/dumps/z/imageZ.png"); + // bool ok = calibrationTableToImage(::calibrationTableZ) + // .save("/home/user/dumps/z/imageZ.png"); - if (!ok) - { - qDebug() << "cannot save imageZ.png"; - exit(EXIT_FAILURE); - } + // if (!ok) + // { + // qDebug() << "cannot save imageZ.png"; + // exit(EXIT_FAILURE); + // } interpolate(::calibrationTableZ); - calibrationTableToImage(::calibrationTableZ) - .save("/home/user/dumps/z/imageZ_interpolated.png"); + // calibrationTableToImage(::calibrationTableZ) + // .save("/home/user/dumps/z/imageZ_interpolated.png"); + // exit(EXIT_SUCCESS); } - if (true) - { - auto rawProfiles = openDump("/home/user/dumps/2024.12.07_14.51.07"); + qDebug() << "--------------------------------------------------------"; + + if (true) { + auto rawProfiles = openDump("/home/user/dumps/binx"); qDebug() << "raw x-profiles count is" << rawProfiles.size(); // qDebug() << "height" << calibrationColumnHeight; @@ -197,24 +222,39 @@ int main(int argc, char* argv[]) ::calibrationTableX = calibrateX(std::move(filteredRawProfiles)); - bool ok = calibrationTableToImage(::calibrationTableX) - .save("/home/user/dumps/z/imageX.png"); + // if (!dump( + // ::calibrationTableZ, + // "/home/user/dumps/binx.calibration_table" + // )) + // { + // qApp->exit(EXIT_FAILURE); + // } - if (!ok) - { - qDebug() << "cannot save imageX.png"; - exit(EXIT_FAILURE); - } + // bool ok = calibrationTableToImage(::calibrationTableX) + // .save("/home/user/dumps/z/imageX.png"); + + // if (!ok) + // { + // qDebug() << "cannot save imageX.png"; + // exit(EXIT_FAILURE); + // } interpolate(::calibrationTableX); - calibrationTableToImage(::calibrationTableX) - .save("/home/user/dumps/z/imageX_interpolated.png"); + // calibrationTableToImage(::calibrationTableX) + // .save("/home/user/dumps/z/imageX_interpolated.png"); } } // exit(EXIT_SUCCESS); + if (!initLaser()) + { + return EXIT_FAILURE; + } + + // PrinterClient printerClient; + QElapsedTimer t; t.start(); @@ -499,21 +539,31 @@ int main(int argc, char* argv[]) return QHttpServerResponse(QJsonDocument(json).toJson()); }); - qHttpServer.route( - "/v1/commands/resetEncoder", - [&](const QHttpServerRequest& request) -> QHttpServerResponse { - if (request.method() != QHttpServerRequest::Method::Post) - { - return QHttpServerResponse::StatusCode::NotFound; - } + qHttpServer.route("/v1/profile", [&]() { + std::lock_guard lg(pgm_image_mtx); - qDebug() << "reset encoder"; + const Profile profile(::pixels, + ::calibrationTableZ, + ::calibrationTableX); - positionSteps = 0; + const QJsonObject json{{"profile", QJsonObject(profile)}}; - return QHttpServerResponse::StatusCode::Ok; - } - ); + return QHttpServerResponse(QJsonDocument(json).toJson()); + }); + + qHttpServer + .route("/v1/commands/resetEncoder", + [&](const QHttpServerRequest& request) -> QHttpServerResponse { + if (request.method() != QHttpServerRequest::Method::Post) { + return QHttpServerResponse::StatusCode::NotFound; + } + + qDebug() << "reset encoder"; + + positionSteps = 0; + + return QHttpServerResponse::StatusCode::Ok; + }); qHttpServer.route( "/v1/commands/startCalibration", @@ -545,7 +595,7 @@ int main(int argc, char* argv[]) qDebug() << "send gCode:" << command; - printerClient.sendCommand(command); + // printerClient.sendCommand(command); return QHttpServerResponse::StatusCode::Ok; } @@ -563,7 +613,7 @@ int main(int argc, char* argv[]) qDebug() << "send gCode:" << command; - printerClient.sendCommand(command); + // printerClient.sendCommand(command); return QHttpServerResponse::StatusCode::Ok; } @@ -897,8 +947,16 @@ void onRequestCompleted(libcamera::Request* completed_request) // qDebug() << "stop calibration mode"; scanningModeFlags = ScanningModeFlags::None; - QFuture dumpCalirationPixelsFuture = - QtConcurrent::run(&dumpCalibrationPixels); + { + QMutexLocker l(&calibrationPixelsMutex); + // QFuture dumpCalirationPixelsFuture + // = QtConcurrent::run(&dumpCalibrationPixels, + // calibrationPixels); + auto future = QtConcurrent::run([&]() { + dumpCalibrationPixels( + std::move(::calibrationPixels)); + }); + } } else { @@ -971,9 +1029,9 @@ void onRequestCompleted(libcamera::Request* completed_request) auto fps{1000.f / msPerFrame}; - qDebug() << "fps ideal/real is" << configFps << "/" << fps - << "; ms per frame is" << msPerFrame << "counted fps" - << performanceCounter; + // qDebug() << "fps ideal/real is" << configFps << "/" << fps + // << "; ms per frame is" << msPerFrame << "counted fps" + // << performanceCounter; elapsedSum = 0; performanceCounter = 0; @@ -1048,224 +1106,6 @@ static void printControls() } } -static void dumpCalibrationPixels() -{ - std::vector rawProfiles; - - { - QMutexLocker l(&calibrationPixelsMutex); - std::swap(rawProfiles, ::calibrationPixels); - } - - const QString dumpSubdir{ - QDateTime::currentDateTime().toString("yyyy.MM.dd_hh.mm.ss") - }; - const QDir dumpPath{dumpsRoot + "/" + dumpSubdir}; - - if (!dumpPath.mkdir(dumpPath.path())) - { - qWarning() << "cannot create dir: " << dumpPath.path(); - - return; - } - - for (const auto& rawProfile : rawProfiles) - { - const auto filename = - QLatin1String("raw_profile_meas_%1_enc_%2") - .arg(QString::number(rawProfile.counters.measurementCounter)) - .arg(rawProfile.counters.encoderPosition); - const auto filepath = dumpPath.path() + "/" + filename; - - QFile f{filepath}; - - if (!f.open(QFile::WriteOnly)) - { - qWarning() << "cannot open dump dump file" << f.fileName(); - qWarning() << "error is:" << f.errorString(); - - return; - } - - QJsonObject jsonCounters{ - {"timestampUs", qint64(rawProfile.counters.timestampUs)}, - {"measurementCounter", - qint64(rawProfile.counters.measurementCounter)}, - {"encoderPosition", qint64(rawProfile.counters.encoderPosition)}, - }; - - QJsonObject json; - - json["counters"] = jsonCounters; - - QJsonArray jsonPixels; - - for (const auto& pixel : rawProfile.pixels) - { - jsonPixels << pixel; - } - - json["pixels"] = jsonPixels; - - if (!f.write(QJsonDocument(json).toJson())) - { - qWarning() << "cannot write file" << f.fileName(); - qWarning() << "error is" << f.errorString(); - - return; - } - - qDebug() << "file written: " << f.fileName(); - } - - qDebug() << "dump finished"; -} - -static QList openDump(const QString& dumpPath) -{ - QString dirToRead{dumpPath}; - qDebug() << "trying to open dump path:" << dirToRead; - - if (dirToRead.isEmpty()) - { - qDebug() << "dumpPath not specified. looking into" << dumpsRoot; - - QDir dumpsRootDir{dumpsRoot}; - - const auto filter = QDir::Dirs | QDir::NoDotAndDotDot | QDir::Readable; - // there is no battery in my rpi5 for now - const auto sort = QDir::Name; - const auto entries = dumpsRootDir.entryList(filter, sort); - - if (entries.isEmpty()) - { - qWarning() << "dumps root" << dumpsRoot << "contains no dumps. " - << "specify existing dump path"; - - return {}; - } - - dirToRead = dumpsRoot + "/" + entries.last(); - } - - QDir dumpDir{dirToRead}; - - const QStringList nameFilters{"*.bin"}; - const auto filter = QDir::Files; - const auto sort = QDir::Name; - - auto filenames = dumpDir.entryList(filter, sort); - - if (filenames.isEmpty()) - { - qDebug() << "no filenames found in" << dumpDir.path(); - return {}; - } - - qDebug() << "create results array" << filenames.size(); - auto resultOptionals = - QScopedPointer(new QList>(filenames.size())); - - QElapsedTimer t; - t.start(); - qDebug() << "open real files"; - std::cout << "here" << std::endl; - - std::transform( - std::execution::par_unseq, - filenames.begin(), - filenames.end(), - resultOptionals->begin(), - [dirToRead](const auto& filename) { - // std::cout << '.'; - auto rawProfile = openRawProfile(dirToRead + "/" + filename); - if (rawProfile.has_value()) - { - QFile f(dirToRead + "/" + filename + ".bin"); - qDebug() << "save" << dirToRead + "/" + filename << "too" - << f.fileName(); - f.open(QFile::WriteOnly); - f.write((const char*)&rawProfile.value(), sizeof(Pixels)); - } - return rawProfile; - // return openRawProfile(dirToRead + "/" + filename); - } - ); - - filenames.clear(); - filenames.squeeze(); - - qDebug() << Q_FUNC_INFO << "open raw profiles: elapsed (ms)" << t.elapsed(); - // std::cout << std::endl; - - std::remove_if( - std::execution::par, - resultOptionals->begin(), - resultOptionals->end(), - [](auto& a) { return !a.has_value(); } - ); - - QList result(resultOptionals->size()); - - std::transform( - std::execution::par, - std::make_move_iterator(resultOptionals->begin()), - std::make_move_iterator(resultOptionals->end()), - result.begin(), - [](auto& p) { return p.value(); } - ); - - qDebug() << Q_FUNC_INFO << "elapsed (ms)" << t.elapsed(); - - return result; -} - -static std::optional openRawProfile(const QString& filePath) -{ - QFile f{filePath}; - - if (!f.open(QFile::ReadOnly)) - { - qWarning() << "cannot open file for reading:" << f.fileName(); - qWarning() << "error string:" << f.errorString(); - - return {}; - } - - // TODO: rewrite to remove manual serialization/deserialization - const auto json = QJsonDocument::fromJson(f.readAll()).object(); - const auto jsonCounters = json["counters"].toObject(); - - Pixels result; - result.counters.timestampUs = jsonCounters["timestampUs"].toInteger(); - result.counters.measurementCounter = - jsonCounters["measurementCounter"].toInteger(); - result.counters.encoderPosition = - jsonCounters["encoderPosition"].toInteger(); - - const auto jsonPixels = json["pixels"].toArray(); - // TODO: check json pixels count -#ifdef FIRST_COLUMN_ONLY - result.pixels[0] = jsonPixels.at(0).toDouble(); -#else - std::transform( - // std::execution::par_unseq, - jsonPixels.constBegin(), - jsonPixels.constEnd(), - result.pixels.begin(), - [](const auto& jsonPixel) { return jsonPixel.toDouble(); } - ); - - // for (size_t i = 0; i < jsonPixels.count() && i < result.pixels.size(); - // ++i) - // { - // result.pixels[i] = jsonPixels[i].toDouble(); - // } -#endif - - return result; -} - static QList filter(const QList& rawProfiles) { QList result; @@ -1315,184 +1155,6 @@ static QList filter(const QList& rawProfiles) return result; } -static QSharedPointer calibrateZ( - const QList& rawProfiles -) -{ - QSharedPointer result{new CalibrationTable{{0}}}; - - for (const auto& rawProfile : rawProfiles) - { - // std::cout << "calibration: pos is " - // << rawProfile.counters.encoderPosition << std::endl; - const float positionMm{ - float(rawProfile.counters.encoderPosition) / - float(requested_params.stepsPerMm) - }; - - const auto& pixels = rawProfile.pixels; - // printPixels(pixels); - // static size_t counter { 0 }; - // qDebug() << "calibrated" << counter++; - const float pos = rawProfile.counters.encoderPosition; - const float divider = requested_params.stepsPerMm; - // std::cout << pos << " " << divider << " " << pos / divider << - // std::endl; std::cout << std::setw(5) << - // rawProfile.counters.encoderPosition - // << std::setw(5) << requested_params.stepsPerMm - // << std::setw(8) << positionMm - // << std::setw(8) << - // float(rawProfile.counters.encoderPosition) / - // float(requested_params.stepsPerMm) - // << ": "; - - for (size_t columnIdx = 0; columnIdx < pixels.size(); ++columnIdx) - { - const auto& pixelValue = pixels.at(columnIdx); - - // float[0, img_height] -> uint16_t[0, calibrationColumnHeight] - const uint16_t discretePixelValue{ - uint16_t(pixelValue * discretesInRage / img_height) - }; - - Q_ASSERT_X( - discretePixelValue > 0 && - discretePixelValue < calibrationColumnHeight, - Q_FUNC_INFO, - ("got ivalid discrete value " + - QString::number(discretePixelValue) + ". pixelValues is " + - QString::number(pixelValue) + ". calc result is " + - QString::number(pixelValue * discretesInRage / img_height)) - .toStdString() - .c_str() - ); - - // auto& calibrationColumn = result[columnIdx]; - auto& calibrationColumn = (*result)[columnIdx]; - calibrationColumn[discretePixelValue] = positionMm; - - // if (columnIdx >= ((img_width - 10) / 2) && - // columnIdx < img_width - ((img_width - 10) / 2)) - // { - // std::cout << discretePixelValue << ";"; - // } - } - - // std::cout << std::endl << std::flush; - } - - return result; - // TODO: try something interesting - // return {}; -} - -static QSharedPointer calibrateX( - const QList& rawProfiles -) -{ - QSharedPointer result{new CalibrationTable{{0}}}; - - for (const auto& rawProfile : rawProfiles) - { - const auto& pixels = rawProfile.pixels; - auto lines = pixelsToLines(rawProfile); - - Q_ASSERT_X(lines.count() > 2, Q_FUNC_INFO, "no lines"); - - QList xAnchors(lines.size() + 1); - - std::transform( - std::execution::par_unseq, - lines.constBegin(), - lines.constEnd(), - xAnchors.begin(), - [](const auto& l) { return l.x1(); } - ); - - xAnchors.last() = lines.last().x2(); - - constexpr double triangleHeightMm{5.}; - constexpr double triangleBaseMm{8.}; - - auto nearestAnchorToX0 = std::min_element( - std::execution::par_unseq, - xAnchors.constBegin(), - xAnchors.constEnd(), - [](const auto& a, const auto& b) { - return std::abs(a) < std::abs(b); - } - ); - - int nearestAnchorToX0Idx = nearestAnchorToX0 - xAnchors.constBegin(); - - QList xAnchorsMm(xAnchors.count()); - - for (int i = 0; i < xAnchors.size(); ++i) - { - xAnchorsMm[i] = (i - nearestAnchorToX0Idx) * triangleBaseMm / 2.; - } - - auto xAnchorIt = xAnchors.constBegin() + 1; - auto xAnchorMmIt = xAnchorsMm.constBegin() + 1; - - for (size_t columnIdx = 0; columnIdx < pixels.size(); ++columnIdx) - { - // skip points with to the left from left line and to the right from - // right line - const auto columnX = int(columnIdx) - int(img_width / 2); - if (columnX < xAnchors.first() || columnX > xAnchors.last()) - { - continue; - } - - if (columnX > *xAnchorIt) - { - ++xAnchorIt; - ++xAnchorMmIt; - } - const auto xLeft = *(xAnchorIt - 1); - const auto xRight = *(xAnchorIt); - - if (columnX < xLeft || columnX > xRight) - { - if (rawProfile.counters.encoderPosition >= 0) - { - qWarning() - << "x anchor not found" << xLeft << columnX << xRight; - continue; - } - } - - const auto& pixelValue = pixels.at(columnIdx); - const uint16_t discretePixelValue{ - uint16_t(pixelValue * discretesInRage / img_height) - }; - - Q_ASSERT_X( - discretePixelValue > 0 && - discretePixelValue < calibrationColumnHeight, - Q_FUNC_INFO, - ("got ivalid discrete value " + - QString::number(discretePixelValue) + ". pixelValues is " + - QString::number(pixelValue) + ". calc result is " + - QString::number(pixelValue * discretesInRage / img_height)) - .toStdString() - .c_str() - ); - - const auto xLineLen = xRight - xLeft; - const auto xLeftMm = *(xAnchorMmIt - 1); - const auto xRelative = float(columnX - xLeft) / xLineLen; - const auto xMmValue = xLeftMm + xRelative * (triangleBaseMm / 2.); - - auto& calibrationColumn = (*result)[columnIdx]; - calibrationColumn[discretePixelValue] = xMmValue; - } - } - - return result; -} - bool initLaser() { const QLatin1String pwmChip{"pwmchip2"}; @@ -1568,162 +1230,3 @@ bool initLaser() return true; } - -static QImage calibrationTableToImage( - const QSharedPointer& calibrationTable -) -{ - QImage result( - QSize(calibrationTable->size(), calibrationTable->at(0).size()), - QImage::Format::Format_Indexed8 - ); - - // QImage image(QSize(imageWidth, imageHeight), QImage::Format_Indexed8); - - QColor color(Qt::green); - auto r = color.redF(); - auto g = color.greenF(); - auto b = color.blueF(); - - for (int c = 0; c < 256; c++) - { - QRgb col = qRgb(int(c * r), int(c * g), int(c * b)); - result.setColor(c, col); - } - - int notNull = 0; - - for (size_t columnIdx = 0; columnIdx < calibrationTable->size(); - ++columnIdx) - { - const auto& column = calibrationTable->at(columnIdx); - - for (size_t rowIdx = 0; rowIdx < column.size(); ++rowIdx) - { - // if (!qFuzzyIsNull(column.at(rowIdx))) - // { - // qDebug() << "here"; - // } - - bool hasValue = !qFuzzyIsNull(column.at(rowIdx)); - - if (hasValue) - { - // qDebug() << "x/y" << columnIdx << rowIdx; - ++notNull; - } - - result.setPixel(columnIdx, rowIdx, hasValue ? 255 : 0); - } - } - qDebug() << "not null count" << notNull; - - return result; -} - -static void interpolate(QSharedPointer& table) -{ -#ifdef FIRST_COLUMN_ONLY - interpolate(table->at(0)); -#else - std::for_each( - std::execution::par, - table->begin(), - table->end(), - [](auto& column) { interpolate(column); } - ); -#endif -} - -static void interpolate(CalibrationColumn& column) -{ - size_t counter = 0; - // qDebug() << "AZAZA" << 0; - -#ifdef FIRST_COLUMN_ONLY - { - QFile f("/tmp/column0.csv"); - f.open(QFile::WriteOnly); - - for (const auto& p : column) - { - f.write(QString::number(p).toUtf8()); - f.write(";\n"); - } - } -#endif - // qDebug() << "AZAZA" << 1; - auto firstNonZero = - std::find_if(column.begin(), column.end(), [](const auto& pixel) { - return !qFuzzyIsNull(pixel); - }); - // qDebug() << "AZAZA" << 2; - if (firstNonZero == column.end()) - { - return; - } - // qDebug() << "AZAZA" << 3; - for (auto it = firstNonZero; it != column.cend(); ++it) - { - auto firstZero = - std::find_if(it + 1, column.end(), [](const auto& pixel) { - return qFuzzyIsNull(pixel); - }); - - if (firstZero == column.end()) - { - // qDebug() << "AZAZA" << 4; - return; - } - - auto nextNonZero = - std::find_if(firstZero + 1, column.end(), [](const auto& pixel) { - return !qFuzzyIsNull(pixel); - }); - - if (nextNonZero == column.end()) - { - // qDebug() << "AZAZA" << 5 << it - firstNonZero; - return; - } - - auto prevNonZero = firstZero - 1; - - auto diff = *nextNonZero - *prevNonZero; - auto size = nextNonZero - prevNonZero; - auto stepDiff = float(diff) / size; - - // qDebug) << *prevNonZero << *nextNonZero << size << stepDiff; - - for (auto zero = firstZero; zero < nextNonZero; ++zero) - { - *zero = (zero - firstZero + 1) * stepDiff; - // qDebug() << "set zero to" << *zero; - } - - it = nextNonZero; - } - // qDebug() << "AZAZA" << 6; -#ifdef FIRST_COLUMN_ONLY - { - QFile f("/tmp/column0_filled.csv"); - if (!f.open(QFile::WriteOnly)) - { - qDebug() << "AZAZA: cannot open file" << f.fileName(); - qDebug() << "AZAZA" << 7; - exit(0); - } - else - { - qDebug() << "AZAZA: ok"; - } - - for (const auto& p : column) - { - f.write(QString::number(p).toUtf8()); - f.write(";\n"); - } - } -#endif - // qDebug() << "AZAZA" << 8; -} -- cgit v1.2.3-70-g09d2