-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Wrong proportions of dewarped images #5
Comments
Hi @noobie-iv . В STEX эта проблема по большей части решается режимом "Уместить" (Affine) в "Макетировании страницы". Но здесь такого нет, так что решать надо как то "на месте". Хоть корректировку пропорции ручную вводить: float delta = 0.0f; /* params */
float scale_X = 1.0f + delta;
float scale_Y = 1.0f / scale_X; |
Ручную корректировку же после прикручивать надо, потому что сразу ее не видно. А это как раз новая стадия нужна. Но это даже не главное. Я тут подумал, что можно ведь вообще нарендерить в Блендере тестовых картинок со страницами заранее известной формы. Тогда точно известно, что должна развертка получить обратно. Например, вот квадрат, вид наискосок: ПерспективаРазвертка"Какие тут уши, тут бы пальцы не обжечь (с)" |
@noobie-iv , сразу (рефлекторно) возникает мысль о необходимости новый репы: Но сама идея верная. Попробуй для начала исходить из перспективной прокции:
а потом уже будем ковырять псевдоцилиндрическую проекцию. PS: Твоя модель понятна и во всех смыслах интересна. Но! Явно теряется общий масштаб. Это будет проблемой? Ещё как. Здесь тоже надо покумекать. Равенство площадей? |
Вот набор тестов под перспективу: |
@noobie-iv say:
В STEX автомат только на 4х из 13 сработал (причём на одной криво). И да. Пропорции не особо алё. |
Автомату явно текст получше нужен, попробую подобрать. Но и без него квадрат обвести несложно. А результаты выходят один другого хуже. |
@noobie-iv say:
Вы будете смеяться с моей истории, но в STU автомат сработал на 8ми из 13. Сделал всё ровно, но пропорции никакущие. В STA тестить не хочу - он частенько падает на этом. PS: Искривления же "на ровном месте" в STEX связаны уже не с автоматом, а с DistorsionModel. Она генериться из трёх линий: верхней, нижней и "средней", в координатах от 0 до 1. Надо трассировать её в |
Hi @noobie-iv . Вставил в |
Набор тестов под развертку: WarpTestSet.zip |
@noobie-iv say:
С исправленным XSpline там, где сработал автомат:
PS: STU выпрямил полностью без кривизы (по краям кое-где чуть-чуть): 1-0001, 1-0003, 1-0004, 1-0005, 1-0008, 1-0010, 1-0011, 2-0001, 2-0003, 2-0004, 2-0008, 2-0010. Но пропорции (не только наружные, но и внутренние) просто ни к чёрту. |
И это еще точный цилиндр. А ему еще можно перекос устроить, чтобы 4 вершины из плоскости закрутились. То, что автоматика не работает - это, видимо, от нестандартных размеров букв или слишком сильного перекоса, на реальных сканах все равно такого не будет. В тестовых проектах один раз можно и вручную точки выставить, не в этом проблема. А вот то, что гладкие кривые разворачиваются во что-то ломано-перекошенное - это явно бага формул. На реальных сканах она, видимо, и проявляется как видимые искажения размеров. |
@noobie-iv say:
Да я уже "ручками пошалил" и увидел. Как и сказал ранее - DistortionModel сбоит. Попробую конечно разобраться, но... там же сплошные плюсы! X( PS: А DataSet хорош! Давно надо было его сделать. PS2: "По секрету" расскажу: походу |
@noobie-iv say:
С исправленным |
Примитивный тест с перспективой. Беру две камеры - длиннофокусную и короткофокусную . Обе навожу каждую на свой на квадрат, чтобы он закрыл поле зрения. А потом поворачиваю квадрат вокруг нижней стороны. От этого дальняя сторона уменьшается, а боковые начинают указывать в точку схода. Для поворота боковых сторон зрительно на один и тот же угол сами квадраты у разных камер надо повернуть по-разному: у короткофокусной послабее, у длиннофокусной посильнее. Но в любом случае легко подобрать повороты так, чтобы боковые стороны совпали. А вот расположение дальней стороны при этом не совпадет. Но и его можно подогнать, просто удлинив квадрат у длиннофокусной камеры. В результате вид из обеих камер одинаковый: А реальные пропорции разные: При этом равномерная сетка на обоих "листах" в камеру тоже выглядит одинаково, фокус с "восприятием глубины" не прокатит. Похоже, просто по координатам вершин восстановить пропорции не получится: они завязаны на фокус камеры. Возможно, фокус должен быть параметром фильтра, который можно независимо копировать с листа на лист - это подразумевает, что все листы сфотографированы одной камерой, и если попался лист, где камера смотрела ровно, то по нему можно узнать правильные пропорции, и подогнать фокус для самого кривого листа, а у остальных фокус принять такой же. |
@noobie-iv say:
Просто по координатам углов нет. Но ты забыл про псевдоцилиндр. Ежели в blender рассматривать не лист, а цилиндр, то кое что с этого выжать можно. Да потребуется допущение: ты должен как будто бы знать форму цилиндра (откуда?). Но то, что по одному снимку нельзя восстановить объёмную картину - это известно изначально. |
Hi @noobie-iv . Тестирование бэтки.Правда не самой бэтки, а current. Материал для тестированияset0002 из scantailor-testing ТестированиеСлишком часто что то обнуляет На этом тестирование прекратил. Результата нет.
Данный результат отражает все текущие недостатки и недоработки STD.
Без постабработки в GraphicsMagick и GIMP. |
Hi @noobie-iv . Первый более-менее вменяемый отклик по тестированию на Руборде. |
Я заглядываю туда иногда. Смотрю, уже целое стадо ишаков завести можно, починки с моей скоростью на год наберется. (Кстати, для потерявших на руборде стили под виндами - совет: стили выбираются там же, где и темная тема). А мне для начала надо эскизы допилить и с пропорциями разверток что-то сделать, чтобы минимально рабочий вариант был. На остальные пожелания - не знаю даже, хватит ли сил вообще. Статейка попалась про подбор положения камеры, как раз по двум точкам схода, для перспективы в самый раз будет: |
@noobie-iv , про стили в соседний "Bug report" (ха-ха) сказануть не хочешь? 😄 PS: Залью ка сюда: Camera_calibration_using_two_or_three_vanishing_points.pdf PS2: А что по моему тестированию? Вопросы то должны быть. Али нет? |
Со стилями все просто. То, что можно поменять через QSS - я поменял. А текст в эскизах - это элементы типа QGraphicsSimpleTextItem, они в Qt, судя по гуглу, стилями не настраиваются в принципе, потому что не наследники от QWidget. И их цвета тупо захардкожены в ThumbnailSequence.cpp, под светлую тему, потому и на стили не реагируют. Со ссылками на главной странице та же фигня была, их пришлось заменить на кнопки из-за этого, одним из первых коммитов перед применением стилей. И, чтобы "просто починить текст", надо устраивать целую городильню с новым самодельным классом-наследником, ручными свойствами и отловом событий (paint-hover-хз-что-еще), чтобы вовремя менять цвета, типа такого: С тестами геометрии пока не возился. Меня устраивает, как автоопределяются сплайны, там, я бы сказал, нет претензий. Бага дальше сидит, на стадии развертки, слишком уж кривые ответы выходят по красивым исходным сплайнам. Подозреваю, что весь тамошний алгоритм надо просто заменить, на что-то типа формул из статьи. Но после эскизов. И, главное, в свободные дни праздников оно уже не войдет. |
А вот формулы, по которым развертка сейчас считается - это наверняка реализация какого-нибудь из известных алгоритмов, где коэффициенты матриц для преобразований через камеру более-менее в лоб подбирают: Краткий обзор формул: Список методов вообще: |
@noobie-iv say:
Залью сюда же: camera_calibration-habr.com.pdf PS: Плохо, что формулы в виде изображений, а не SVG. |
Конкретно на хабре еще и в формулах опечатки. Оригиналы, судя по виду, из справки по OpenCV притырены. В OpenCV вообще эти функции в комплекте идут. Не знаю как в линуксах, а под виндами эти библиотеки что-то весят несуразно много, такие к программе в три мегабайта не приложить. |
@noobie-iv . Не-не-не! Не лезь в OpenCV! "Оно" конечно вполне себе "забавно", но помимо того, что всё "это" немеренно жрущее память и процессор, так ещё и с версионностью ещё хуже чем у Qt. Но решать тебе. Ежели хочешь 2 головные боли вместо одной, то вперёд. 😄 PS: Залью ка сюда: OpenCV-Camera_Calibration_and_3D_Reconstruction.pdf ("распечатка" не очень, но уж как получилось). |
Про память был хороший вопрос в багтрекерах какого-то из тейлоров. "Почему при 100G оперативки нужно постоянно ждать перезагрузки одних и тех же файлов?" Могу от себя добавить, что на современных мониторах эскизов на экране помещается больше, чем у ST в кеше (там 40 элементов ограничение стоит), и тот все время по диску шарит. Старенький он уже, мало что помнит 😄 Но CV я, конечно, никуда прикручивать не буду, мне бы то, что взялся, как-нибудь закончить. Просто там, возможно, формулы подсмотреть получится. Либо в исходниках, либо в списке литературы, я не шарил еще. |
@noobie-iv say:
Короче. Есть код: scantailor-deviant/src/dewarping/CylindricalSurfaceDewarper.cpp Lines 254 to 288 in e31f878
Это не что иное, как нахождение коэффициентов аффинного преобразования четырёхугольника в квадрат. И используется QR-разложение из Eigen. Но матрица 8x8 на треть состоит из нулей. И это не очень хорошо. Да, проверка на валидность вроде есть, но проверка проверке рознь. А прикрутить SVD из того же Eigen на место QR я чего то не смог (не понимаю я эту плюсовую дичь). То же самое и с кривыми, только там матрица попроще (3x3): scantailor-deviant/src/dewarping/CylindricalSurfaceDewarper.cpp Lines 290 to 320 in e31f878
Такие вот дела. |
Поможет или нет - не знаю, но пусть будет. Это dewarp, вырезанный из STEX в отдельную программу. Все проще, чем из ST запускать. Не проверял, насколько он рабочий. Можно сдать в поликлинику для опытов. |
Hi @noobie-iv . Хмм. При трассировке Аномалия явным образом существует. Но возникает она походу не на этапе расчёта "Чем дальше, тем чуднее и чуднее....". И где теперь искать эту "падлу"? PS: Перспективу проверил соответствующим режимом - аномалии нет. Ещё вариант, что аномалия возникает при комбинировании этих двух трансформаций: перспективы и кривизны внутри квадрата. |
Выглядит так, как будто за краями текстового блока деварпер пытается по экстраполяции дорисовать цилиндр. А из-за большой кривизны левый край при трассировке сползает по цилиндру совсем далеко вниз, потому черная часть так опухает: деварпер считает, что она огромная, просто под таким углом выглядит маленькой, но если ее честно развернуть, получится ого-го сколько: |
Никому нельзя верить, даже книжкам из тырнета. Все формулы с гомографиями, видимо, приводят под калибровку, когда размеры образца известны. А в ST гомография вычисляется на условный единичный квадрат. Чтобы привести его к прямоугольнику, надо сначала смасштабировать его. Получаются формулы:
Гомография тогда записывается:
И формула для нахождения фокуса (из условия ортогональности R11·R12 + R21·R22 + R31·R32 = 0):
Формулы для нахождения размеров листа (из условия единичности векторов R11² + R21² + R31² = 1 и R12² + R22² + R32² = 1):
Если бы последний коэффициент в гомографии принимать не условную единицу, а прямо расстоянию от камеры до нулевого угла в миллиметрах, то Sx и Sy тоже сразу вышли бы в миллиметрах. Это, кстати, вариант определения размеров листа: если камера была закреплена, и все листы от нее были на одном расстоянии, его тоже можно копировать с листа на лист, подогнав сначала только для одного листа. |
@noobie-iv say:
Что указывает на недоопределённость системы. Я бы "боролся" с этим "злоупотреблением" определёнными величинами. А именно: есть исходный четырёхугольник и есть единичный квадрат (он свободен от пропорций и в данном случае это хорошо). Я бы пытался вычленить из этой связки углы, как будто бы в реальности имеется некий квадрат, который мы повернули так, что наблюдается этот самый четырёхугольник. Используя эти самые углы искал бы пересечения линий, направленных "вглубь" от точек кривых до прямой, соединяющей концы кривой. Отношение отрезка от кривой до прямой к длине прямой и брать как глубину в единичном квадрате. Недоопределённость системы в этом случае резко падает. Не всё учтено в данной схеме и длину линии надо брать не непосредственную, а приведённую (в зависимости от положения на единичном квадрате), но это уже "мелочи". @noobie-iv say:
Уж не прямое ли это "указание" попытаться перейти от F к FOV? |
Сейчас алгоритм как раз и работает пересечением линий, как в учебниках по начерталке для архитектора с кульманом. Не вижу только фишки с проецированием размеров на горизонтальную линейку, чтобы убрать перспективу - взамен в программе матриц накручено. Для улучшения развертки нужно вынести на фото нормаль к листу - это она должна подвинуть образующую в правильное положение. Проблема плохих ракурсов - то, что на них реальную нормаль плохо видно. Как только у нормали одна или две проекции малы на фото - все вспомогательные линии слипаются в кашу, пересечения начинают сильно ошибаться, элементы матриц улетают в бесконечность. И назначить границу между "OK" и "ERR" проблематично. Я неделю искал варианты "небольших правок" - поворачивал плоскость, масштабировал по вертикали, делал условную гомографию для четырехугольника, огибающего все точки профиля на обратной гомографии. И все варианты - на стадии окончательного построения пересечений - тонут в каше из линий. Забавно, но в учебниках начерталки для метода архитекторов есть примечание. Бывают точки, которые тяжело получить построением. Для них архитекторы делают исключение: их не строят, а вычисляют. Вот переход в 3D, видимо, и будет таким исключением. Планирую концы образующей выносить на фото из 3D. А уж полученная образующая всегда под хорошим углом пойдет - так же, как линия в плоскости листа в алгоритме сейчас. Возможен, конечно, вариант, что и образующая пройдет сквозь камеру, когда книга в лягушачьей перспективе сфотографирована - если фотограф работал лежа на столе. Придется этот случай в руководстве пользователя оговаривать как недопустимый 😄
F и FOV - почти две взаимно обратные величины. F мог бы быть в интерфейсе, но к нему размер матрицы надо знать, а ее в рекламе вряд ли пишут. А FOV - это и есть размер матрицы, деленный на фокус, причем его легко измерить, и для этого матрицу выковыривать не надо. Пользователю, видимо, FOV узнать проще. А внутри программы все они - просто коэффициенты, и без разницы, кого использовать. Главное, что у меня в голове число неизвестных с размером гомографии сошлись, наконец - после добавления масштабов в уравнения. |
@noobie-iv say:
То ли я чего то не вдупляю, то ли что то ещё... Но никаких пересечений сейчас не ищется. Сейчас производится проецирование изображения в единичный квадрат. После чего "глубина" определяется как уклонение масштаба вертикального столбца между кривыми от единицы. Где здесь какое пересечение? Только вот на единичном квадрате в принципе искать глубину - доаольно бесполезное занятие. Другое дело наоборот - по гомографии вычленить углы поворотов вокруг 3х осей (как будто такой квадрат реально существует) и уже на исходном четырёхугольнике строить линии от кривых по направлению "оси z" этого квадрата к линии, соединяющей концы кривой. Я вижу это как то так. Но глубоко не копал. |
Внутри mapGeneratrix образующая выносится на фото, пересекается с трассировками, переносится обратно для уточнения середины. Нет только построения поправки на смещение из плоскости листа. Из-за этого лист обрабатывается почти как плоский. Только образующие чуть сдвигают к краям через Mapper - но это учитывает только разность длин, и не учитывает перспективных искажений. Можно посмотреть set0004 - там видно, что идеально разворачивается сине-белая подложка, которая лежит в плоскости углов. Это потому что строятся нормали по черным стрелкам, а надо по красным: По черным стрелкам ArcMapper считывает свое сечение, и оно получается неправильной формы, сползшее вбок. По черным стрелкам mapGeneratrix наносит образующую на фото, и точки при развертке считываются с неправильного положения.
На исходном четырехугольнике ось Z будет точкой. А вот на фото она видна линией, и там уже можно пересекаться. Но это не сработает для плохих ракурсов, где Z опять выродится - то в точку, то в линию углов. Потому и идея восстанавливаться из 3D, потому что 2D бывает вырожденной. |
@noobie-iv say:
Неверно, это в квадрате она будет точкой. Но после поворота квадрата вокруг 3х осей до совпадения с исходным четырёхугольником это будет совсем уже не точка, а более чем линия, что то вроде стрелок Z на первой части твоего рисунка. При этом не интересует ни верхняя, ни нижняя кривая в отдельности, а интересует самое что ни на есть среднее из двух кривых, потому как "глубина" в псевдоцилиндрической модели относится к столбцу целиком. Такие вот дела. 😄 |
Если поворачивать квадрат в 3D - он станет параллелограммом, а не произвольным четырехугольником. Надо не поворачивать, а проецировать в камеру. Тем более, что это можно сделать. Если восстановить полную матрицу преобразования из гомографии - то да, единичный куб можно будет перенести на фото. И там - да, Z превратсятся в линии. Причем правильные - красные, а не глюкавые черные. Именно для этого я и пытаюсь эти формулы получить. Одна мелочь тормозит меня уже не первую неделю - на неудачных ракурсах красные стрелки вырождаются, и становятся хуже черных с точки зрения вычислений, тогда "честный" алгоритм просто разваливается.
Если считать, что сечения могут быть разными - можно вычислять верхнее и нижнее смещение, а в середине брать среднее. Но в модели, а на на фото переносить из 3D - тогда они правильные получатся. Но я так делать не буду. Если два сечения отличаются, то на виде сверху углы образуют не прямоугольник, а трапецию. И надо гомографию делать либо с единичной трапеции, либо в квадрате образующие наклонять. И формулы фокуса больше не работают - условие ортогональности для сторон трапеции не выполняется. И длины сторон трапеции сначала найти надо, а они нелинейно от выгиба зависят - это уже нелинейные итерации гонять надо. Для начала меня устроит Mapper с сохраненными fx. Потом поправлю его под красные стрелки по лучшему из двух сечений - тогда вертикальный масштаб будет снят с фото, а не назначен как попало через DepthPerseption (да еще с грубой обрезкой под +-0.5, как сейчас). |
@noobie-iv say:
Так там значения сейчас в пределах до 0.1 (максимум до 0.15). Я трассировал, так что знаю. 😄 |
CylindricalSurfaceDewarper::initArcLengthMapper(...)
{
...
double elevation = m_depthPerception * (1.0 - (y2 - y1));
elevation = qBound(-0.5, elevation, 0.5);
...
} Как я понимаю, не я один додумался предельным значением выгиба профиля считать освежитель воздуха 😄 |
И еще про фокус. В формуле квадрат фокуса может стать отрицательным. Например, если нарисовать четырехугольник как попало. Или обрезать фото до обработки. Вот размеры Sx, Sy стабильны - там строго сумма квадратов. Даже ноль не получится, потому что суммируются проекции единичного вектора. А фокус придется вписывать в допуск MIN-MAX. Важно: фокус портится и в случае, когда координаты на фото отсчитываются не от центра, а от края. Вот на тех гомографиях, что вычисляются сейчас, фокус легко улетает в минус. Но model должна вернуть пользователям гомографию "от угла", а внутри пусть считает как хочет. Пользователи - это dewarper, thumnail, imageview, и никому не интересно добавлять-вычитать центры туда-сюда на каждый пиксель. Так что понадобятся переходы центр-угол. Если есть исходная гомография:
то координаты по ней вычисляются так:
А если я добавляю к координате x на фото смещение Δx, то получится:
Аналогично для y:
Значит, если гомография посчитана для угла, то для центра повторно обращать матрицы не понадобится, достаточно сделать так:
Аналогично, для полной матрицы преобразований перенос начала координат по фото делается так:
|
@noobie-iv say:
В этом ничего "страшного" нет. Ибо изначально фокус - нефизический. То есть ты можешь приложить линейку, чтобы померить его, но без линейки его физически нет. Фокус же в квадрате - это физическая величина. Только я не знаю, как менее плохо сделать аналогию. В оптике принято оперировать лучами, но это математика, а для физики такое не очень. Другое дело оперировать неким сечением, через которое проходит поток лучей, вот это уже точно очень "по-физически". Наименее плохое определение: фокус в квадрате - это оношение площади линзы к её кривизне. Только так. Все остальные "упрощения" и взятие корней - это уже математика, а не физика. |
Итого идея такая:
Это общая идея. Надо еще просчитать тестовый пример. Сдается, там половину действий сократить можно. На выходе у меня есть 3D-модель листа (Sx, Sy, Sz - его размеры, arcLengthMapper хранит профиль сечения). Размеры получены исходя из условной единицы в гомографии. Т.е. таким был бы лист на фото, если бы находился на расстоянии 1 от камеры. А mdl2img позволяет любую точку с модели спроецировать на фото. Так что mapGeneratrix:
Он найден из уравнения "Оси x,y на фото перепендикулярны в модели". Если минус - значит, "такой проекции не может быть физически". В реале - обрезанное фото, или линзовые искажения, или еще что - надо тестить. При отрицательном фокусе отрицательные размеры вылезут, кривые нормали и т.п. Расчет пойдет вразнос. Так что либо коррекция, либо вылет. |
@noobie-iv say:
Вот здесь мне показалось странным: "поделив на F... и домножением на F". А оно точно надо? @noobie-iv say:
Не говори ГОП, ... сначала "прыгни". |
Это все математик, укушенный единицей. Из-за единицы вместо F в гомографии не все элементы умножены на F. А третий орт восстанавлиивается только умножением чистых R. Приходится частично делить и частично умножать, формулы где-то выше. Главное, вроде идея устаканилась, осталось формулы дотестить и уже программить наконец, а то месяц простоя.
На выходных попрыгал в Ёкселе. И в бесконечность фокус умеет, и в минусы. А как выглядит 3D-модель, у которой квадрат ширины положительный, а высоты - отрицательный? Это пришелец из 4 измерения? |
@noobie-iv say:
Нет. Это означает, что кто то из Откуда это исходит? А от туда же: ежели взять z, нормированные не по 1, а по F, то получим:
Такие вот дела. 😄 |
Нельзя поменять знак одной из них. Они все - элементы матрицы поворота. У нее 9 значений, но только 3 независимых. Остальные связаны единичностью и взаимной ортогональностью. Обязательно нужно получить 3 единичных взаимно ортогональных вектора на выходе. F, Sx, Sy из этих дополнительных условий и выведены. Стоит поменять что-то одно - сломается что-то другое. Вот h11·h12 + h21·h22 + h31·h32 = 0 - это условие ортогональности осей X,Y. И если его удается выполнить только с отрицательными квадратами - значит, значения вычислены не через "масштаб-поворот-смещение-проекция", а каким-то другим способом, который игнорировал дополнительные ограничения. Навскидку - искажения или обрезание. Может, бывает еще что-то. Вот когда я выше тестировал координаты, посчитанные предварительно через матрицы - ни разу глюк не насчитал: А как выдумал контур из головы - сразу минусы и огреб. |
@noobie-iv say:
Верно. И добавление сюда нормировочного коэффициента |
Формулы вроде контачат. Единичный куб восстанавливается по фото, и вставляется обратно. Во вложении - xlsx, gnumeric должен открывать, если отлаживаться понадобится: H2H3.zip Из оригинального - ось Z в этих формулах получается направлена от камеры, так что выгиб листа вверх считается отрицательным. Возможно, это лечится отрицательным фокусом. Осталось еще мнимый фокус приспособить куда-нибудь 😄 Из приятного - от перемещений гомографий туда-обратно на пол-фото они не меняются. Так что надо всего один новый столбец вычислить. Коэффициенты h, смещенные к центру -> F,Sx,Sy - > столбцы R1,R2 -> столбец R3 -> столбец H3 -> смещение H3 к углу -> вставка в mdl2img, и готово. Делов на одну дополнительную функцию. |
@noobie-iv say:
Да, вполне открывает. |
Дополнительная функция может быть оптимизирована. Если эти умножения-деления на F сократить, то третий столбец по центральной гомографии проще вычислить прямо через два первых, без промежуточных поворотов: PerspectiveTransform
CylindricalSurfaceDewarper::calcMdlToImgTransform(
HomographicTransform<2, double> const& pln2img,
QPointF const& img_center)
{
Matrix<double, 3, 3> const& hmat = pln2img.mat();
double const& dx = img_center.x();
double const& dy = img_center.y();
double const h00 = hmat(0, 0) - hmat(2, 0) * dx;
double const h10 = hmat(1, 0) - hmat(2, 0) * dy;;
double const& h20 = hmat(2, 0);
double const h01 = hmat(0, 1) - hmat(2, 1) * dx;
double const h11 = hmat(1, 1) - hmat(2, 1) * dy;;
double const& h21 = hmat(2, 1);
double const F_square_min = 1 * 1;
double const F_square_max = 1000 * 1000;
double const F_square = qBound(
F_square_min,
- (h00 * h01 + h10 * h11) / (h20 * h21),
F_square_max
);
double const F = std::sqrt(F_square);
double const Sx_square = h20 * h20 + (h00 * h00 + h10 * h10) / F_square;
double const Sx = std::sqrt(Sx_square);
double const Sy_square = h21 * h21 + (h01 * h01 + h11 * h11) / F_square;
double const Sy = std::sqrt(Sy_square);
double const Sz = Sx;
double const k = Sz / (Sx * Sy);
double const h02 = (h10 * h21 - h11 * h20) * k;
double const h12 = (h01 * h20 - h00 * h21) * k;
double const h22 = (h00 * h11 - h01 * h10) * k / F_square;
Matrix<double, 3, 1> const hvec(
h02 + h22 * dx,
h12 + h22 * dy,
h22
);
return PerspectiveTransform(hmat, hvec);
} Интересно, что для вычисления полной матрицы по гомографии вычислять корень по дороге и не требуется, потому что тут он просто в исходном квадратном виде сидит. Но для перехода в минус надо пройти точку нуля, и тут деление на ноль надо отслеживать. В явном виде корень нужен только для определения размеров. Как бы тут физику подхимичить? 😄 |
@noobie-iv say:
Ты накладываешь ограничения на квадрат фокуса. Но может стоит накладывать ограничение не на него, а на второй элемент размеров? Что то типа от 0.1 до 10.0 в долях от первого элемента? Да и не стоит ли подвергнуть анализу эти самые элементы (первый и второй) по отдельности на вполне конкретном |
Размеры будут использованы для вычисления пропорций листа, и больше нигде не понадобятся. А вот фокус, так или иначе, попадает в нормаль к листу. И, если он, например, 1e-16, то нормаль оказывается какой-то великоватой. По такой нормали точки с модели будут проецироваться за пределы фото, и вся развертка будет битая. Или наоборот, в точку стянется. И я все не могу въехать, физически тут фокус бывает кривой, или я где в формулах накосячил. Я несколько книжек по машинной графике бегло пролистал, но нигде подробностей не нашел. |
@noobie-iv say:
Ты не уловил смысл, сказанного мной. Попробую разжевать. Предлагаемое тобой отсечение фоеуса понятно, но и только. В тоже время, если отсечение производить по размерам (а их 2), то какую то логику ты можешь навести. Ежели сработало отсечение какого то размера, то значит расчитанный фокус негож. Ну негож, так негож, значит надо "придумать" такой фокус, который даст приемлемые результаты по обоим размерам. При таком подходе "придуманный" фокус будет давать как минимум результат не хуже отсечённого. |
Прикольно. Вот тут смещение снизу больше, чем сверху - и дефолтный алгоритм считает, что лист вогнутый: Необходимо править и алгоритм построения сечения. И тут обратно возникает вопрос - как снять сечение с фото, если будут два плохих ракурса. Бывают "мусорные ветки", которые можно временно залить, чтобы просто показать, а потом стереть? |
Пока ты не решил данный вопрос, ты можешь хоть каждый день делать новую ветку, а на следующий - удалять и делать новую. Был бы прок только с этого. А ежели нужно показать что то на материале, тогда пользуй scantailor-testing, которрый всегда можно удалить и создать по новой с обнулённой историей. Или вообще новую репу, типа |
Ок, тогда вот демка: change_dewarp_model С дефолтным построителем глючит. Но если я вбиваю фиксированное сечение: CylindricalSurfaceDewarper::initArcLengthMapper(...)
{
m_arcLengthMapper.addSample(0.00, 0.00);
m_arcLengthMapper.addSample(0.25, 0.08);
m_arcLengthMapper.addSample(0.50, 0.10);
m_arcLengthMapper.addSample(0.75, 0.08);
m_arcLengthMapper.addSample(1.00, 0.00);
m_directrixArcLength = m_arcLengthMapper.totalArcLength();
m_arcLengthMapper.normalizeRange(1);
} То в принципе получаю то, что хотел: Остается только научиться правильно снимать сечение с фото. Есть идеи - как. Но нет идей, где граница между правильным и неправильным сечением, чтобы резкого скачка не было. И где фокус неправильно ловится (одноосевой поворот) - сетка ложится немного мимо. Это, видимо, выносом фокуса в настройки починить можно будет. |
@noobie-iv say:
Роман, не дели на 2, когда |
Добавил тестовое чтение профиля с фото: 895d0fd Базовая идея простая: из модели я выношу на фото единичные габариты профиля (0,0,0)(0,1,0)(0,0,1)(0,1,1), строю обратную гомографию по 4 точкам, и по ней переношу трассировку обратно в габарит - получается сечение с фотографии. На первой картинке единичные габариты отрендерены пунктиром. Set0001 проходится на тех тестах, где есть двойной поворот. Где одинарный - битый фокус портит нормаль, и вслед за ним профиль. Перекошенные тесты, разумеется, не восстанавливаются. В этой простой идее есть места для спотыканий:
|
Hi @noobie-iv . На всякий. Устранение неправильной растеризации: scantailor-deviant/src/dewarping/RasterDewarper.cpp Lines 405 to 430 in dfd0a39
заменить на: // Called for points where pixel density reaches the lower or upper threshold.
auto const processCriticalPoint =
[&generatrix, &dst_y_range, model_domain_top, model_domain_height]
(double model_y, bool upper_threshold)
{
/*
if (!generatrix.pln2img.mirrorSide(model_y))
{
double const dst_y = model_domain_top + model_y * model_domain_height;
double const second_deriv = generatrix.pln2img.secondDerivativeAt(model_y);
if (std::signbit(second_deriv) == upper_threshold)
{
if (dst_y > dst_y_range.first)
{
dst_y_range.first = std::min((int)std::ceil(dst_y), dst_y_range.second);
}
}
else
{
if (dst_y < dst_y_range.second)
{
dst_y_range.second = std::max((int)std::floor(dst_y), dst_y_range.first);
}
}
}
*/
}; отключив этим неправильную растеризацию при выходе разрешения за лимиты. |
Круто, это минус несколько дней поисков. Боюсь только, что на стадии прикручивания границ все это придется переделывать с нуля. А пока что дело движется, и не движется. Чувствую себя как Ахиллес, догоняющий черепаху. Сколько бы я шагов не сделал - до конца остается еще бесконечное количество. Любая строчка кода через несколько дней обязательно оказывается неправильной. Любое изменение обязательно ломает что-то в нескольких абсолютно неожиданных местах, и требует переделки или полного отката. Любимый неисправленный глюк на сегодня - в коммите a40f54c (.2.14: rename from STU to STD). После замены "universal" на "deviant" слетел UI: плавающие панели перестали плавать и прилипли, а стили по умолчанию больше не грузятся - это то, на что в руборде жаловались "стиль win98". У меня даже нет идей, что вообще могло сломаться. |
Sample images:
Results:
The width should increase when unfold curved image, but it doesn’t:
The width should not decrease when unfold flat image, but it does:
The text was updated successfully, but these errors were encountered: