• Проективное преобразование (поиск относительного положения точки)

    Nashev
    @Nashev
    Мы для своего проекта Krutoscope искали решение проблемы коррекции перспективных искажений при вырезании изображения прямоугольного листа из фотографии этого листа. Везде реализации выпрямления четырёхугольника в прямоугольник попадались только через линейные пропорции! Прям везде, где искали!

    И вот, благодаря этому Вашему вопросу, мы (Евгений Берёзкин, Никита Трубкин и я) таки написали на dart функцию, успешно выбирающую цвета точек для вырезанного листа из оригинальной фотки по координатам углов этого листа, и при этом, кажется, перспективные искажения успешно исправляющую!

    import 'package:image/image.dart' as imglib;
    
    class PerspectiveRectifier {
      late num a, b, c;
      late num a1, b1, c1;
      late num d, e, f;
    
      PerspectiveRectifier(imglib.Point topLeft, imglib.Point topRight,
          imglib.Point bottomLeft, imglib.Point bottomRight) {
        final x1 = topLeft.x;
        final y1 = topLeft.y;
        final x2 = topRight.x;
        final y2 = topRight.y;
        final x3 = bottomRight.x;
        final y3 = bottomRight.y;
        final x4 = bottomLeft.x;
        final y4 = bottomLeft.y;
    
        a = ((y4 - y3) * (x1 + x3 - x2 - x4) - (x4 - x3) * (y1 + y3 - y2 - y4)) /
            ((y4 - y3) * (x2 - x3) - (x4 - x3) * (y2 - y3));
        b = (x1 + x3 - x2 - x4 - (x2 - x3) * a) / (x4 - x3);
        c = 1;
        a1 = x2 * a + x2 - x1;
        b1 = x4 * b + x4 - x1;
        c1 = x1;
        d = y2 * a + y2 - y1;
        e = y4 * b + y4 - y1;
        f = y1;
      }
    
      Offset calculateSourceOffset(Offset relativeTargetOffset) {
        return Offset(
            (a1 * relativeTargetOffset.dx + b1 * relativeTargetOffset.dy + c1) /
                (a * relativeTargetOffset.dx + b * relativeTargetOffset.dy + c),
            (d * relativeTargetOffset.dx + e * relativeTargetOffset.dy + f) /
                (a * relativeTargetOffset.dx + b * relativeTargetOffset.dy + c));
      }
    }
    
      imglib.Image copyRectifyWithPerspectiveCorrection(
          imglib.Image src, PerspectiveRectifier r, imglib.Image? toImage) {
        final dst = toImage ?? imglib.Image.from(src);
    
        for (int y = 0; y < dst.height; ++y) {
          for (int x = 0; x < dst.width; ++x) {
            final srsOffset =
                r.calculateSourceOffset(Offset(x / dst.width, y / dst.height));
            final srcPixel =
                src.isBoundsSafe(srsOffset.dx.toInt(), srsOffset.dy.toInt())
                    ? src.getPixel(srsOffset.dx.toInt(), srsOffset.dy.toInt())
                    : src.getColor(0, 0, 0);
            dst.setPixel(x, y, srcPixel);
          }
        }
        return dst;
      }


    Собираюсь сделать PR в package:image
    Ответ написан
    Комментировать
  • Как получать котировки с биржи?

    Nashev
    @Nashev
    В комментах к https://habrahabr.ru/post/332700/ (Программный сбор данных о котировках) упомянут sib-algo.ru/quotes-updater
    Ответ написан
    Комментировать
  • Где сдать Li-ion аккумулятор в Москве?

    Nashev
    @Nashev
    eco2eco.ru/utilizaciya/battery пишут что они единственные в России, кто перерабатывает батарейки, и предлагают искать пункт приёма на карте getboxy.ru/map
    Ответ написан
    Комментировать
  • Как работать Excel-документами в Delphi?

    Nashev
    @Nashev
    Вам уже не надо, но пусть ответ тут будет для читателей:
    Если писать через OLE Automation, то вся работа с самим экселем получится ровно такой же, как на встроенном в него Visual Basic for Application, на котором свои макросы он сам предлагает писать, лишь отягчённая особенностям типов данных в Delphi. Более того, чтобы отладить эту часть, проще всего сначала написать её на самом VBA именно как макрос, отладить и лишь потом уже переносить в Delphi, меняя лишь мелочи синтаксиса.

    Главное, что хочу сказать: если в рамках этого кода не понадобятся ничего такого, чего не мог бы сделать VBA, то скорее всего нет никакого смысла этот макрос переносить в Delphi. "Макросы" VBA могут многое.
    Ответ написан
    Комментировать
  • Тостер, а почему многие БД - не иерархичные?

    Nashev
    @Nashev
    Потому что в реляционной добавляешь в таблицу колонку idParent - и она становится иерархичной
    Ответ написан
    Комментировать
  • Есть готовые библиотеки для Delphi с реализацией типовых структур данных через generics?

    Nashev
    @Nashev Автор вопроса
    fundementals.sourceforge.net ещё нашёл, похоже на decal но, говорят, в чём-то сильно лучше.

    UPD: Spring4D довольно мощный вариант
    Ответ написан
  • Как безболезненно уйти с Delphi?

    Nashev
    @Nashev

    Проблему отсутствия общедоступного движка, который все знают и любят, вместе с проблемой обучения ему, а заодно вместе с проблемой улучшения и поддержки своего движка, можно решить одним смелым ходом:

    Откройте свой движок сообществу, с исходниками, на гитхабе, и пиарьте его на всех углах! Уверен, народ подтянется и будут и изучать, и развивать, и документировать, и использовать. Если он и правда так хорош, как пишите.

    Ответ написан
    2 комментария
  • Алгоритм эффективного распределения заявок

    Nashev
    @Nashev
    А что мешает дать открытый список неразобранных — и пусть сами берут, переводя заявку на себя?
    Ответ написан
    Комментировать
  • Как организовать проект или два репозитория в одну папку?

    Nashev
    @Nashev
    Пока у вас всего 2 компонента запланировано, пользователю возможно разрешите иметь ещё одну для своих доработок. Каждый из них может подменить своими некоторые файлы более глубокого слоя, и пользоваться этими перекрытыми в случае необходимости. Лучше, когда код разных уровней не смешивается.

    Наверняка можно сделать в фреймворке папки для этих «перекрытий», по сути повторяющие оригинальную структуру, и одну функцию для определения пути для любого используемого файла, который ищет в этих трёх (а не 100500) возможных местах… И пользоваться всеми файлами через неё…

    Хотя — это вариант переделать фреймворк, а это может быть невозможно. Можно попробовать держать в одной папке два репозитория РАЗНЫХ СКВ — git и hg, например, или git и svn. И для каждой из этих систем держать свой комплект списка игноров и вести его… С другой стороны, если CMS вносит свои изменения в файлы (те же шаблоны, например) фреймворка — то один файл в двух версиях Вам понадобится, а в одной папке этого точно не сделать.

    Есть вариант разные ветки одного репозитория иметь, и время от времени в ветку с CMS мёржить без слияния правки из ветки фреймворка… Тоже возможный вариант, да… Может, даже лучший в описанной ситуации. Вы про этот вариант в UPD писали?
    Ответ написан
    2 комментария
  • Новая терминология для новой технологии – кто подскажет?

    Nashev
    @Nashev
    система отслеживания перемещения объектов — СОПА
    Ответ написан
    4 комментария