-
Notifications
You must be signed in to change notification settings - Fork 4
research: distortion model not working? #47
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
Comments
Так она ж тут явно не цилиндрическая. Отгиб сверху из-за подкладки - это вообще отдельная деформация, ее в общий цилиндр не затолкать. Поверх все заполировано явно видимым перспективным искажением (заметно по буквам вдоль левой границы: на нижние мы смотрим вертикально вниз, а на верхние - сильно наискосок, и они по высоте выглядят сплющенными). По-простому можно разве что по боковым сторонам тоже точек добавить, чтобы хоть как-то исправлять середину. А по-честному такое, видимо, только триангуляцией плоскости надо восстанавливать, и подбирать деформации треугольников плюс параметры расположения камеры плюс искажения объектива, чтобы точно воспроизвести форму изгиба бумаги и положение фотоаппарата. Как в Блендере в режиме трассировки камеры, чтобы 3D в видео встраивать. Подозреваю, что это простыми алгоритмами типа "размыть-бинаризировать" не лечится, они заглавные буквы от строчных не отличают, и текст от чертежа, и горизонтальные линии от наклонных. Нужно что-то, что умеет различать буквы и линии. OpenCV или вообще самодельный ИИ, обученный конкретно на сканах. Но я туда точно не полезу, не по специальности оно мне. |
Hi @noobie-iv . Всё не так печально. На данный момент имеется линейныый расчёт "промежуточных" линий прямо: scantailor-experimental/src/dewarping/CylindricalSurfaceDewarper.cpp Lines 113 to 151 in f0e124c
и обратно: scantailor-experimental/src/dewarping/CylindricalSurfaceDewarper.cpp Lines 160 to 202 in f0e124c
в координатах от 0 до 1 между верхей и нижней кривой. Краевые точки кривых имеют ключевое значение и образуют координатный квадрат (0,0)-(1,1). Ежели бы в этой конструкции присутствовала бы ещё одна линия (именно линия, не кривая), то можно было бы заменить линейность на параболу (то, что нужно прямо и обратно, для параболы не проблема, для кубической уже проблематичней, а дальше уже и лезть не стоит). Но вот GUI. Ну не дружу я с ним. И реализовать эту линию (как вариант двумя точками на вертикальных линиях четырёхугольника) - не моё, ну никак. Я из-за GUI бросил идею добавления TrimBox в "2. Разрезка страниц", хотя на "подкапотной" части у меня всё работало (поэкспериментировал и удалил, чтоб не печалиться). Такие вот дела. |
Hi @noobie-iv . Чисто "подкапотно" добавил даже не линию, а отклонение от середины (0.5) слева и справа: CylindricalSurfaceDewarper::Generatrix
CylindricalSurfaceDewarper::mapGeneratrix(double crv_x, State& state) const
{
double const pln_x = m_arcLengthMapper.arcLenToX(crv_x, state.m_arcLengthHint);
double const lin_y1 = -0.007;
double const lin_y2 = 0.007;
double const lin_y = lin_y1 + (lin_y2 - lin_y1) * pln_x;
Vector2d const pln_top_pt(pln_x, 0);
Vector2d const pln_bottom_pt(pln_x, 1);
QPointF const img_top_pt(toPoint(m_pln2img(pln_top_pt)));
QPointF const img_bottom_pt(toPoint(m_pln2img(pln_bottom_pt)));
QLineF const img_generatrix(img_top_pt, img_bottom_pt);
ToLineProjector const projector(img_generatrix);
QPointF const img_directrix1_pt(
m_imgDirectrix1Intersector.intersect(img_generatrix, state.m_intersectionHint1)
);
QPointF const img_directrix2_pt(
m_imgDirectrix2Intersector.intersect(img_generatrix, state.m_intersectionHint2)
);
double const pln_straight_line_y = (fabs(m_plnStraightLineY - 0.5) > 0.45) ? 0.5 : m_plnStraightLineY;
double const img_directrix1_proj(projector.projectionScalar(img_directrix1_pt));
double const img_directrix2_proj(projector.projectionScalar(img_directrix2_pt));
double const img_directrix12f_proj = (1.0 - pln_straight_line_y) * img_directrix1_proj
+ pln_straight_line_y * img_directrix2_proj;
double const img_directrix12fd_proj = img_directrix12f_proj - pln_straight_line_y;
//double const curve_coef = 1.0 + 0.5 * (m_curveCorrect - 2.0);
double const curve_coef = (m_curveCorrect < 2.0) ? (1.0 / (3.0 - m_curveCorrect)) : (m_curveCorrect - 1.0);
double const img_directrix12fds_proj = img_directrix12fd_proj * curve_coef;
double const img_directrix12fs_proj = img_directrix12fds_proj + pln_straight_line_y + lin_y;
QPointF const img_straight_line_pt(toPoint(m_pln2img(Vector2d(pln_x, img_directrix12fs_proj))));
double const img_straight_line_proj(projector.projectionScalar(img_straight_line_pt));
boost::array<std::pair<double, double>, 3> pairs;
pairs[0] = std::make_pair(0.0, img_directrix1_proj);
pairs[1] = std::make_pair(1.0, img_directrix2_proj);
pairs[2] = std::make_pair(pln_straight_line_y, img_straight_line_proj);
HomographicTransform<1, double> H(threePoint1DHomography(pairs));
return Generatrix(img_generatrix, H);
} Просто линия без всяких там парабул. И получил такую вот картину: PS: Так то по уму вообще использовать третью (среднюю) кривую, а не вычислять её как среднуюю из верхней и нижней. Но как получить её из RANCAS? PS: Ежели я ползунок отряжу полностью под эту линию, забив болт на глубину и кривизну? Это как? Не очень нагло будет? Но было бы менее плохо, ежели бы всё-таки по регулировочной точке на левой и правой прямой. |
Вот развернуто вручную в блендере по сетке 5x3, 5x5, 5x9 линий. Cтроки чуть кривоваты (легкая синусоида по длине строки), потому что развертка из отрезков, а не из сплайнов. И перспективу я не пытался починить, хотя покрутить камеру можно. Во всех версиях верхняя, нижняя и одна средняя строки ровные. Однако между ними кривизна таки видна, и каждое дополнительное деление пополам улучшает дело. То есть лучший результат получился в варианте 5x9=45 точек, но подбирать их вручную на каждой странице нереально. А для автоматики нужно таки трассировать по горизонтали строки, а по вертикали буквы. Или, как вариант, подсвечивать найденные строки и давать пользователю ткнуть в нужные мышкой. Но это уже переделка всей математики с разверткой и всего гуя. |
Hi @noobie-iv . Вариант с тыканьем - не вариант, ибо напрочь минусует автоматику. Вариант с трассировкой каждой строки - не вариант, ибо убивает сглаживание и модель становится суперкривой. Чем не устраивает вариант с корректировкой наклона вычисляемой средней линии (см. пост выше) "избранных" страниц? Надо то добавить две точки по бокам, на крайняк использовать для регулировки ползунок (минусовав при этом глубину и кривизну). Текущее исправление искажений: После указанной в посте выше "подкапотной" корекции наклона средней линии: PS: Хотелось бы конечно использовать RANCAS для обнаружения средней линии и использовать её для создания этих самых двух боковых точек. Но как? PS2: Нахождение пары верхней и нижней кривой в RANCAS: scantailor-experimental/src/dewarping/DistortionModelBuilder.cpp Lines 252 to 273 in f0e124c
А как среднюю то найти? Делить список линий пополам? Или сначала найти верхнюю и нижнюю кривую, после чего делить диапазон между ними пополам? Тоже "слегка" геммороно и ненадежно ни разу. Более того, существует возможность дефектных страниц (и на одну из них я уже напоролся - нижняя часть страниц была спошным шумом), на которых наблюдается немеренное кол-во линий. На такой странице схватил SEGFAULT. Это конечно "уникальный" случай, но подумываю разветвить схему составления списка пар для RANCAS на Тулон-новскую и мою по ограничению кол-ва линий (например, 200). А после этого всё станет ещё гемморойней. |
Тем, что конкретно в этой версии книги из-за подкладки схема деформации явно состоит из двух независимых частей: И средняя линия тут - это середина основной страницы. А деформации в правом верхнем углу - сами по себе, их через среднюю линию не вычислить. Собственно это и видно в той развертке, которую STEX делает - строки кривые там, где одна деформация переходит в другую, а STEX их пытается по средней посчитать. Я такую кривую страницу где-то тут уже выкладывал. Специально держал книгу левой, а фотал правой, и внизу такой же загиб получался. |
Hi @noobie-iv . Ясен красен на такой кривой странице я какого то "суперварианта" никак не получу. Но вариант с коррекцией наклона средней линии меня уже устраивает (в отличии от текущего). А ежели появится "средняя" кривая в явном виде, так я вообще расчёт разверну: буду использовать "среднюю" кривую как среднюю линию, а проекционное перспективное положение этой линии как значение для составления пары вместо 0.5. Такие вот дела. |
Как пользователь, я бы предпочел водить мышкой и видеть подсвеченные трассированные строки. Ткнув в наиболее кривую - разбить развертку на две по этой линии, тогда строки и выровняются, потому что кривая строка учтется уже как граница в двух половинах. А если внутри половин останутся кривые - щелкнуть и там, порезав половины на четвертины. Это не то же самое, что вручную точки двигать, и такое даже на большом числе страниц можно быстро сделать. А щелкать мышью пользователь вынужден оттого, что автоматика сама эти строки не нашла. А как программист - понимаю, что тут дофига работы выходит, которую лично я не знаю как сделать. У меня все еще минимальный проект в отложенных делах болтается, до появления свободного времени; раньше него я все равно ничего серьезного сделать не возьмусь, только по мелочи помочь. Так что ничего против волшебной середины сказать не могу, раз уж она есть. Лучше кривая прямая в программе, чем прямая кривая в фантазиях 😄. |
Так как мне эти две точки в ГУИ получить, чтобы с сигналами (аналогично точкам верхней и нижней кривой)? Без них у меня только один вариант - отдать ползунок полностью под коррекцию наклона средней линии. А это не айс ибо не удобно и на глубину и кривизну положить придётся (хотя я уже сам подумываю отключит кривизну от ползунка ибо не айс 2 параметра на одном регуляторе). Сам я эти 2 точки "победить" не смогу, тупо не осилю, ибо копипаста на такой замудренной системе сигналов не работает. |
Это хороший вопрос. Я целый mvst замутил, чтобы отследить, как там этот гуй работает. Та пара тысяч строк, что есть в нем сейчас - это путь одного щелчка через два фильтра, причем только по главной картинке. Там и какие-то самодельные цепочки задач, и сами задачи ничего не делают, кроме засовывания каких-то промежуточных результатов в параметры обратного вызова, и многократные заныривания в многопоточную часть QT, и непойми что еще. И где-то там по дороге эти задачи несколько раз дергают за ST за гуй. Я даже вырезал несколько уровней вложений типа ID-PageID-HalfPageID; какую-то петлю с обратным возвратом по фильтрам назад, и еще много чего. Но даже оставшееся наизусть уже не могу воспроизвести, в оконцовке придется еще диаграммы порисовать, кто с кем связан. Сейчас путь обрывается в кеше превьюшек. Я думал, там чуть-чуть осталось, но внутри оказался еще один такого же размера клубок из задач, списков задач, приоритетов задач, запусков списков задач, отмен задач и списков задач, возврата превьюшек в несколько заходов через создание разных типов задач, и.т.п. Если я когда-нибудь вообще продерусь через эти болота с задачами, то смогу подсказать, как кнопочку приделать, чтобы хотя бы не поломать картинку с превьюшками, как в STD. |
Hi @noobie-iv . Хоть я ковыряю по "вершине айсберга", но точно так же воспринимаю эту "шкатулку". Переключился с корекции наклона средней линии на нахождение третьей кривой (m_midCurve). Вряд ли доведу дело до результата (как и во многих других случаях), но пока как то так. |
Hi @noobie-iv . Неплохая идея была с третьей кривой. Ой неплохая. Она устраняла необходимость и "корекции кривизны" и "корекции наклона средней линии". Но не судьба. Не нашёл я как эту третью кривую пропихнуть в На том возвращаемся к корекциям. Не подсобишь ли с ещё двумя ползунками, по образу |
Я СЬДЕЛЯЛЬ ЭТО!!!! Три ползунка для корректировки модели: "глубина", "кривизна" и "наклон" средней кривой! Плюс вернул метод составления пар кривых от @Tulon , только размерность выборки поменял с 5 на 16. Такие вот дела. |
Hi @plzombie , @trufanov-nok , @noobie-iv .
В первую очередь данный вопрос будет интересен (помимо меня) наверное @noobie-iv .
Подкинули мне на DWG.RU фото-материальчик:
Ничего вроде особенного. Накладываем на него "Кривые":
Верхняя кривая на месте, нижняя - на месте. Но вот средние режут текст наискосок (коррекция кривизны в данном случае вообще никак не помогает).
И встаёт вопрос: Почему так? И нет ли какой возможности регулирования цилиндрической модели так, чтобы "побеждать" и такие вот случаи? Что то типа "добавления эксцентриситета"?
PS: Я готов пожертвовать "Коррекцией глубины и кривизны", отдав ползунок полностью под этот "эксцентриситет".
The text was updated successfully, but these errors were encountered: