ImageProcessing-ElectronicPublications / scantailor-experimental

Scan Tailor Experimental is an interactive post-processing tool for scanned pages.
https://github.com/Tulon/scantailor/tree/experimental
GNU General Public License v3.0
30 stars 0 forks source link

feature: block #18

Open zvezdochiot opened 7 months ago

zvezdochiot commented 7 months ago

Приветствую @noobie-iv .

Я понял решение вашей концепции в рамках струтуры ST:

Для реализации нужного вам, необходим ещё один этап между "Page Layout" и "Output": "Block". Примитивнейший этап, решающий постановку задачи. По умолчанию включает только нулевой блок (то бишь всё). Поверх него плодишь другие блоки (просто блоки, без всяких свойств) ровно таким же образом, как зоны в "Picture Zones" или "Fill Zones". А вот на этапе "Output" прописывается динамический селектор "Block". И в зависимости от выбранного блока формируется маска путём вычитания из маски текущего блока масок всех последующих. Параметры же будут относиться (применяться по вычтенной маске блока и прописываться в xml) не к этапу "Output", а к текущему блоку.

Да это потребует перетрубации "Output": внедрение как самих блоков, так и масок на их основе. Но это решение полностью укладывается в концепцию ST и достигает ваших целей. И не совсем ясно, как копировать свойства между страницами, но это решаемо.

См. также:

noobie-iv commented 7 months ago

Разносить выделение и его свойства на два разных этапа - это усложнение работы. Неудобно будет переключаться туда-сюда, чтобы посмотреть, какую рамку я сейчас настраиваю. Надо тыкать в рамку, и сразу видеть ее свойства. По мне логично нарисовать контур, и сразу ему прописать "это картинка, тут просто уровнями jpeg-шум обрезаем", а в этой рамке "дополнительно палитру назначаем с принудительным белым фоном".

А вообще, прежде чем пришивать внешние программы, мне надо сначала тумбочки починить. Они сейчас и в STD не работают, и в STEX через раз. Весь прикол в том, что картинки опознаются по ImageId, который просто содержит путь до исходного файла и номер страницы. Этот Id при обработке передается по цепочке через все фильтры. В исходном ST это оптимизация: все фильтры меняют только матрицу преобразований и контур подрезки, кроме последней output-стадии. Даже имена файлов для кеширования картинок вычисляются на основе пути к файлу. А после развертки надо, чтобы у той же исходной картинки превьюшка поменялась. Значит, надо менять Id и логику его обработки по всей программе - и в фильтрах, и в видах, и в кешах. С основным изображением сработала грубая подмена - на стадии Deskew я генерирую изображение развертки и передаю его в следующий фильтр. А с тумбочками этот трюк не помогает: они грузятся не из фильтра, а независимо по начальному Id, и после подмены они уже не подгружается правильно.

В STEX эта проблема через костыль решена: вместо матрицы преобразований создан собственный класс трансформации, который для случая развертки по запросу умеет вернуть изображение; для этого в нем и все настройки развертки хранить приходится. То есть как бы и старая логика с передачей Id сохранена, и новая логика-подменка срабатывает когда надо. От этого код основных видов и тумбочек STEX уже несовместим с STU/STD; если я и его начну копипастить, это будет уже откат к ветке STEX. Плюс у STEX где-то в цепочках вызовов для обновления тумбочек что-то зевнуто, и тумбочки через раз не обновляются.

А мне надо будет еще и вызов внешних программ в цепочку вставить. Например, вызов фотошопа и ручную правку с заморозкой результата. Для этого нужно ему файл страницы передать, и сохраненный результат где-то в кеш положить, чтобы дальше по цепочке фильтров уже его передавать, а не исходное изображение. Тут копипаста логики из STEX уже не поможет, и логика STU/STA не подойдет. А я пока даже через отладчик все цепочки обновления превью отследить не смог, я же ни под Qt не писал, ни многопоточных программ не отлаживал. Начальная копипаста шла сильно быстрее, чем я рассчитывал, а теперь разбираться в логике получается сильно дольше, чем сначала казалось. Плюс у меня свободное время вышло. Как бы не пришлось теперь отложить релиз до пенсии.

zvezdochiot commented 7 months ago

@noobie-iv say:

Разносить выделение и его свойства на два разных этапа - это усложнение работы.

Ни капли. Ещё раз повторяю: по блоку генерится маска путём вычитания из маски блока масок всех последующих блоков. Вы не собираетесь использовать маску для подсветки (точнее для оттенения всего не попадающего в маску)? Это совсем не соответсвует концепции ST.

PS: К тому же сами соглашаетесь, что ваши задумки плохо согласуются с механизмами ST. В то время как блоки полностью в эти механизмы укладываются.

PS2: Ежели так не нравиться доп. этап, то можно обойтись вкладышем "Block" по соседству с "Picture zones", но это ещё больше перегрузит "Output", что опять не соответствует концепции ST.

PS3: Я всё же считаю, что макетирование страницы (а это оно и есть) должно идти отдельным этапом от "Output".

@noobie-iv say:

я же ни под Qt не писал

Можете потренироваться на https://github.com/ImageProcessing-ElectronicPublications/photoquick и https://github.com/ImageProcessing-ElectronicPublications/photoquick-plugins . Он значительно проще. Я собственно с него Qt и начинал.

noobie-iv commented 7 months ago

@zvezdochiot

вычитания из маски блока масок всех последующих

А не факт, что маску надо вычитать. Например, на самой обычной странице с картинкой сначала выравнивается освещение целиком, а потом дополнительно отбеливается текст. Значит, есть :

  1. Автоматическая область "на всю страницу" с действием "освещение"
  2. Область "картинка", которая ничего не делает, а просто вырезается из последующей обработки
  3. Оставшаяся часть "текст", которая бинаризируется

Тут картинка вырезается из текста, но не вырезается из страницы целиком. Видимо, вырезаение - это опция области, а не автоматическое действие.

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

Но пока это все обсуждение шкуры недобытого медведя. Починю тумбочки - есть шанс, что и дальше справлюсь.

@zvezdochiot

Он значительно проще

Не поможет. Мне надо логику ST понять - а там сплошные прострелы через потоки/события/сигналы по десять раз туда-сюда на каждую тумбочку. А для этого надо несколько раз на полный день в отладчике зависнуть; вычитывать глазами уже пробовал - не помогает. Без опыта догадаться, что какой-нибудь метод "run" - это переопределение QT-шного управления потоками, который продолжится после выброса события вообще в другом месте от переопределения очередного неизвестного мне метода "stop", просто нереально. Может, на новогодних праздниках поиграю. Глядишь, и случится просветление. Или помутнение, уж как пойдет.

zvezdochiot commented 7 months ago

@noobie-iv say:

не факт, что маску надо вычитать.

Факт. Вы опять пытаетесь смешать всё в кучу. Пытайтесь конечно, но у вас получится совсем не то, на что вы расчитываете. Ещё раз повторюсь: макетирование страницы (разбивка на блоки) означает, что к каждому блоку будет применяться весь набор (фильтры, режим, зоны, удаление пятен) с индивидуальными параметрами, отличными от остальных блоков. И отсекаться всё это будет по маске блока. Простая система? Простая. Ваши цели достигаются? Достигаются.

Не поможет.

Поможет. Мне то помог.

noobie-iv commented 7 months ago

@zvezdochiot

к каждому блоку будет применяться весь набор

А мне не нужен весь набор. Мне нужны только определенные действия. И иногда они нужны одинаковые для разных блоков. Например, выравнивание яркости правильно определяестя по белой части страницы, а применить его надо и к цветной; если цветную вырезать отдельно - у нее яркость уже не настроить, нет точки белого. А иногда наоборот, картинку трогать не надо, потому что она плохим фото и так покалечена; только текст надо почистить.

Применение всего набора сейчас во всех тейлорах делается, и иногда бесит, потому что делает лишние действия, от которых только хуже. Можно прикручивать бегунки с силой, как сейчас в STEX, но по двадцать фильтров с нулевой силой на каждую область - это уже перебор. Такое можно простить, только когда это единичный временный костыль.

Так что моя идея просто воспроизводит ручную работу в любом редакторе: выделить область и применить несколько команд. Причем и области должны быть любые, и действия в областях надо назначать по выбору. Из простых действий всегда можно собрать сложное. А если базовые действия сразу сложные - каждый раз получается головоломка на ровном месте. Сейчас в STEX со всеми этими взаимоисключениям зон так; для добавления возможностей это тупиковый путь.

не соответствует концепции ST

Концепция ST - волшебная программа, которая одной кнопкой делает красиво. Эта концепция работает только с чистыми сканами. А в реальности даже сотни документов по специальности, которые мой родной Минстрой выкладывает, приходится реставрировать, я их после ST вынужден фотошопить дополнительно. Мне нужна другая концепция: где не справилась автоматика, там должна быть возможность ручной правки произвольной сложности. К счастью, большинство моих документов покалечено однообразно, что дает возможность автоматизировать работу хотя бы в пределах документа. К несчастью, я не знаю готовых программ, которые такое умеют, а ST из всех - ближайший к идеалу.

Отсюда и желание добавить сущую мелочь - вызов произвольной внешней программы для обработки выбранной области. Собственно, программа-минимум - просто добавить один пункт в обработку на стадии вывода: внешняя команда. Вообще, если забить на превью, то этот пункт с каким-нибудь GMIC или ImageMagic, скорее всего, уже можно приделать, и получить кривую, но рабочую программу, как в STD, где сейчас уже можно работать.

Поможет

Там нет многопоточной обработки. И если бы была, все равно в ST она другая. Почему одно переключение фильтра приводит к вызову CacheDrivenTask до полутора десятков раз, что такого сложного в обновлении превью, что его приходится многократно крутить по новой? Пока я не разберусь, что эти тавтологические вызовы делают, я не смогу их перевести в новую логику - ни починить превьюшки, ни внедрить вызов внешних программ.

А то, что я конкретно на Qt не писал - это мелочь. Я писал GUI на WinApi, VBA, C#. У них всех одни и те же идеи, только названы по разному, да синтаксис отличается. Это не сложно, это просто требует времени на выяснение, что конкретно где находится. Я не в Qt застрял, а в непонятной логике работы и сотнях мелких классов.

zvezdochiot commented 7 months ago

@noobie-iv say:

А мне не нужен весь набор. Мне нужны только определенные действия.

Только вот ньюанс. Достойные программы вёрстки построенны именно на макетировании страниц. По сравнении с ними всякие ворды - не более чем блокноты. Именно поэтому я имею интерес внедрить именно макетирование. По умолчанию блок всего один, включающий всё. И лишь мануально на отдельных страницах можно произвести любой сложности разбиение страницы. Такой подход намного превосходит всё описанное вами выше, сочетая в себе одновременно изначальную простоту и сложную обработку одновременно. Такие вот дела.

цветную вырезать отдельно - у нее яркость уже не настроить, нет точки белого.

Всё зависит от того, как ты будешь производить отсечение для конкретной функции. На функцию же будет подавться изображние целиком и маска. А как производить результат и применять маску - это ещё подумать надобно.

PS: Ежели не нравиться идея вычитания блоков, то блоки всё-таки могут иметь одно свойство со значениями: "AND", "OR", "XOR"...

noobie-iv commented 7 months ago

@zvezdochiot Мне не понятна идея вынести блоки в отдельную стадию. Самое простое - тыкать в зону, и сразу настраивать ее свойства, как во всех программах, где есть панели свойств для выбранных объектов. А зачем переключаться вперед-назад? У меня в документах по несколько разнотипных картинок на листе. Вот я на стадии "блоки" нарисовал 8 контуров. Перешел на следующую стадию, и как теперь из списка "блок 1, блок 2, ..." понять, кто какой картинке соответствует? Кто тут фото, кто черно-белый график, а кто малоцветная диаграмма? Сейчас зоны на отдельной вкладке выбираются - почему так не сделать? Только свойства не в контекстное меню толкать, а прямо на панели свойств фильтров выводить, при щелчке по зоне.

Насчет логики ничего не понял. Что значит "текст XOR фото AND диаграмма", что тут должно происходить? Как бинаризация с палитризацией XOR делают? По мне, максимум сложности - финализация зоны, когда в ней уже все что надо сделано, и дальше она в обработке не участвует. Зона "вся страница" - выравнивание яркости. Зона "диаграмма" - палитра, финализировать. Зона "вся страница" - бинаризация; диаграмма финализирована и уже не бинаризируется. Получаем выравнивание яркости и палитру для диаграммы, выравнивание и бинаризацию для текста.

Более сложные комбинации будет неудобно в виде окон и списков городить, тут нодовые редакторы нужны, но это уже совсем не ST.

zvezdochiot commented 7 months ago

@noobie-iv say:

Самое простое - тыкать в зону, и сразу настраивать ее свойства, как во всех программах

А вы упрямый. Только толку с вашего упрямства 0. Насчёт "во всех программах" - откройте XPress, Scribus или почитайте как "это" устроенно в LaTeX. Не то что не близко к вашему описанию, но вообще не рядом. А делается там именно по моему описанию. Почему так? Потому что мой вариант рабочий, а ваш - тупиковый. Даже ежели вы добъётесь своих целей (совсем не уверен), то кодить после вас не возьмётся никто. Такие вот дела.

Почему сам не сделаю, как описываю? Потому что не могу. Не хватает моих навыков на целый новый этап. Даже на новую вкладку скорее всего не хватит. Я же не прогер от слова совсем.

А то, что вы расписали про "AND", "OR"... Ну это вообще треш. Ежели вы в таком направлении ковыряете, то мне в данном вопросе ловить нечего.

как теперь из списка "блок 1, блок 2, ..." понять, кто какой картинке соответствует?

Вы всё-таки не собираетесь использовать маску блока для подсветки/оттенения? Это очень странно с вашей стороны.

noobie-iv commented 7 months ago

@zvezdochiot

Ежели вы в таком направлении ковыряете

В этом направлении и без меня наковыряно. Есть фильтры выбора в Автокаде, где из текстовых строк вида "начало блока OR" собирается сложная логика. Есть стиль а-ля фотошоп/gimp/и.т.п., где логика может применяться не только к маскам, но и к самим слоям. Есть нодовые редакторы, где маски подключаются на отдельный вход как множитель к силе эффекта. Но я предпочитаю не ковырять ничего вообще, а просто выполнять ряд заданных пользователем действий внутри выбранной рамки. По мне, это самый простой и логичный способ задать обработку. Нарисовал рамочку - тут же задал, что в ней делать. Разве что галочка "заморозить" по смыслу выполняет вычитание, и может рассматриваться как логика на уровне маски (и видимо, программно так и будет реализована).

Вы всё-таки не собираетесь использовать маску блока для подсветки/оттенения?

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

толку с вашего упрямства 0

Толку с меня и будет ноль, пока не разберусь с логикой работы программы - где лежат данные, куда они пересылаются, в каком порядке потоки бегают. Судя по первым безрезультатным попыткам понять это с наскока, мне понадобится несколько месяцев. Не зря же тумбочки глючат во всех версиях ST. Когда смогу тумбочки починить - можно будет планировать, что сделать дальше.

Я же не прогер от слова совсем

Вот, нас уже двое. Не справимся - так хотя бы весело посремся в комментах!

zvezdochiot commented 7 months ago

@noobie-iv say:

Вот, нас уже двое. Не справимся - так хотя бы весело посремся в комментах!

:+1: :sake: :sake: :sake: :+1:

Не видать мне макетирования, не сбудется "мечта идиота". ;)