Skip to content
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

model quality? #4

Closed
zvezdochiot opened this issue Jan 20, 2023 · 35 comments
Closed

model quality? #4

zvezdochiot opened this issue Jan 20, 2023 · 35 comments
Assignees
Labels
complete Performed dispute Debate enhancement New feature or request help wanted Extra attention is needed

Comments

@zvezdochiot
Copy link
Member

zvezdochiot commented Jan 20, 2023

Hi @plzombie .

New model BG/FG quality.

Old [0,100] {default = 75}:

mfbdjvu/src/mfbdjvu.cpp

Lines 155 to 163 in fb7f456

n = (n < 0) ? 0 : (n < 100) ? n : 100;
keys->quality = sqrt(n) * 0.1f;
vector<int> nf, nb;
nb.push_back((int)(keys->quality * 100.5f) + 5);
nb.push_back((int)(keys->quality * 110.5f) + 5);
nb.push_back((int)(keys->quality * 125.5f) + 5);
keys->slices_bg = nb;
nf.push_back((int)(keys->quality * 125.5f) + 5);
keys->slices_fg = nf;

New [0,Inf] {default = 100};

                n = (n < 0) ? 0 : n;
                keys->quality = sqrt(n) * 0.1f;
                vector<int> nf, nb;
                nb.push_back((int)(keys->quality * 76.0f + 0.5f) + 5);
                nb.push_back((int)(keys->quality * 84.0f + 0.5f) + 5);
                nb.push_back((int)(keys->quality * 95.0f + 0.5f) + 5);
                keys->slices_bg = nb;
                nf.push_back((int)(keys->quality * 95.0f + 0.5f) + 5);
                keys->slices_fg = nf;

⚠️ Both models are non-linear (sqrt)!

PS: I don't like the upper limit of the old model.

@zvezdochiot zvezdochiot self-assigned this Jan 20, 2023
@zvezdochiot zvezdochiot added enhancement New feature or request help wanted Extra attention is needed labels Jan 20, 2023
@plzombie
Copy link
Contributor

plzombie commented Jan 20, 2023

-slice 100 is like jpeg 70-90%. -slice 130 is close to lossless when transcoding from jpeg. With default djvulibre coefficients jpeg images I tested may look blurry. So I don't know which coefficients will be better

@zvezdochiot
Copy link
Member Author

zvezdochiot commented Jan 20, 2023

@plzombie say:

-slice 100 is like jpeg 70-90%

А вот здесь ты не путай. В PDF-ках JPEG в районе "At this writing the default JPEG quality level of 75" и ниже при DPI 150. А качество выше подпадает в категорию prepress. Надо понимать, что из-за DPI в типографии "немного" иная шкала качества. В то время как в jpeg-recompress -quality 75 не всёгда попадает даже в LOW, а зачастую оказывается в DIRTY. Такие вот дела.

Ежели совсем не нравится -slice 100, то можно сговориться на 130. Главное, чтобы шкала была одинаковой у нас с тобой. Потому как твоя линейная шкала ни в какие ворота не гожа. Сохрани в ряд -quality = 0, 25, 50, 75, 100, и визуально оцени.

PS: К тому же я верхнюю границу открываю. Делай хоть -quality 500 (я то сделал, только вряд ли кому такое нужно, жирнее исходной JPG получается).

PS2: Так то по логике надо брать логарифмическую шкалу вида slices = m+S*log(1+quality/100)/log(2), вот только с логарифмами связываться не охота, поэтому взял корень.

PS3: Прошёлся по имеющимся djvu-шкам. Все как один slices = 100, у BG бывает меньше.

@zvezdochiot
Copy link
Member Author

Hi @plzombie .

Я тут заметил, что ежели использовать логарифмическую модель:

                n = (n < 0) ? 0 : n;
                keys->quality = (float)n;
                float lq = log10(1.0f + keys->quality * 0.09f);
                vector<int> nf, nb;
                nb.push_back((int)(lq * 76.0f + 0.5f) + 5);
                nb.push_back((int)(lq * 84.0f + 0.5f) + 5);
                nb.push_back((int)(lq * 95.0f + 0.5f) + 5);
                keys->slices_bg = nb;
                nf.push_back((int)(lq * 95.0f + 0.5f) + 5);
                keys->slices_fg = nf;

то качество, которое "хочешь" ты будет соответствовать -quality 200. Интересное кино. Никаких не 130 или другой непонятной цифири. В совпадения не верю ни разу.

@plzombie
Copy link
Contributor

plzombie commented Jan 21, 2023

Я сохранял со своей. Скорее всего, твоя степенная функция будет равномернее качество давать, потому что после 50 там менее явные изменения (если не сравнивать пиксель-в-пиксель)
На счёт, почему 100 соответствует -slice 130, вот например скан манускрипта войнича
изображение
Видно что c44 слишком сильно пережимает chroma. Хотя в настройках по умолчанию там должно быть всё норм.
Плюс я с этой же метрикой хочу сохранять фотоальбомы, например. И там уже картинка выглядит мыльной со -slice 100
DPI тут это просто подсказка для djview для отображения, оно на сжатие не влияет

@zvezdochiot
Copy link
Member Author

zvezdochiot commented Jan 21, 2023

@plzombie say:

Плюс я с этой же метрикой хочу сохранять фотоальбомы

Слегка перебор. Дефолтное качество не для фоток. Для фоток качество должно быть явно выше дефолтного. И в этом плане твоё искусственное ограничение шкалы quality сверху мне совсем не нравится. Ничуть не меньше, чем линейность самой твоей шкалы. Что мешает для фоток устанавливать -quality 200? Можешь даже preset-ы себе сделать.

@plzombie say:

DPI тут это просто подсказка для djview для отображения, оно на сжатие не влияет

Ну как сказать. Картинка в 600 DPI сжимается гораздо хуже, чем картинка в 100 DPI (общий размер), но выглядит гораздо лучше, даже ежели quality ниже. :)

@plzombie
Copy link
Contributor

Я -quality 100 рассматриваю не как дефолтное значение, а как "отличное" качество. А по умолчанию можно и -quality 75 сделать. -bgs 3 -fgs 2 же тоже совершенно не подходит для -dpi 200 например

Ну как сказать. Картинка в 600 DPI сжимается гораздо хуже, чем картинка в 100 DPI, но выглядит гораздо лучше. :)

Это уже скорее особенности c44/cjb2. Ну и если изображение сначала сделать чб потом даунскейлить в 6 раз, естественно результат будет лучше, чем если наоборот

@zvezdochiot
Copy link
Member Author

zvezdochiot commented Jan 21, 2023

@plzombie say:

А по умолчанию можно и -quality 75

Так и стоит.

@plzombie say:

не подходит для -dpi 200 например

Где то в описании DjVu жирными буквами написано "не менее 300".

Так всё-таки, что делать со шкалой? Ты меня ни разу не убедил. Исскуственность 130 глаза режет. Предлагаю ещё раз пользовать нелинейную шкалу (sqrt, log10) с 100 в качестве дефолта (ака как у всех), а к всем "особо ценным" материалам применять значения более 100 или пресеты без ограничений сверху.

PS: В depress ты в качестве дефолта можешь пользовать quality > 100. Главное, чтобы шкала была одинаковой.

PS2: Логарифмицеская шкала выдаёт:

  • quality = 50, slices fg = 75, slices bg = {61,67,75}
  • quality = 100, slices fg = 100, slices bg = {81,89,100}
  • quality = 200, slices fg = 126, slices bg = {102,112,126}

@zvezdochiot
Copy link
Member Author

zvezdochiot commented Jan 21, 2023

@plzombie say:

Плюс я с этой же метрикой хочу сохранять фотоальбомы

Я бы не советовал сегментацию и IW4 (downsample) для фоток. DjVu позволяет использовать JPG в качестве цветной компоненты. Подробности смотри в djvujpgpack (режим lossless). Плюс к этому фотоальбомы я лично клепаю либо в jpeg2pdf, либо 7z: ZIP {images + description.txt} rename to CBZ (перед упаковкой рекомендую пройтись jpeg-recompress).

@plzombie
Copy link
Contributor

Сегментацию для фоток, понятное дело, не имеет смысла.
Я всё-таки расцениваю quality как процент от 0 до 100, где ниже-выше в большинстве случаев не имеет смысла. А у тебя получается со 100% будет размываться цветность, какие-нибудь книги с иллюстрациями или комиксы придётся всё равно с 200 кодировать. Если логарифмическую функцию использовать.

@zvezdochiot
Copy link
Member Author

zvezdochiot commented Jan 21, 2023

@plzombie say:

расцениваю quality как процент от 0 до 100

Процент от чего? От 130? А 130 - это что? Вот хде вопрос.

Потестил я шкалку, а заодно поковырял свои djvu-шки и пришёл к следущим выводам:

  • "ноль" в твоей модели выбран неверный, он не "5" и не "30", а "20".
  • BG в большинсте книг 4х-компонентный.

Следовательно:

                n = (n < 0) ? 0 : n;
                keys->quality = (float)n * 0.01f;
                float lq = log10(1.0f + keys->quality * 9.0f);
                vector<int> nf, nb;
                nb.push_back((int)(lq * 57.0f + 0.5f) + 17);
                nb.push_back((int)(lq * 66.0f + 0.5f) + 18);
                nb.push_back((int)(lq * 69.0f + 0.5f) + 19);
                nb.push_back((int)(lq * 77.0f + 0.5f) + 20);
                keys->slices_bg = nb;
                nf.push_back((int)(lq * 80.0f + 0.5f) + 20);
                keys->slices_fg = nf;
  • quality = 0, slices fg = 20, slices bg = {17,18,19,20}
  • quality = 50, slices fg = 79, slices bg = {59,67,70,77}
  • quality = 100, slices fg = 100, slices bg = {74,84,88,97} ("как у всех")
  • quality = 200, slices fg = 122, slices bg = {90,102,107,118}

PS: Давай не "колхозить". Давай шкалу сделаем "как у всех", а вот дефолты и пресеты понапихаем свои. Здесь даже вопрос документации присутствует. Я вот запросто напишу, что общепринятое значение quality равно 100, но вот я пользую в проге 200 (200% от общепринятого). А ты что и как напишешь?

@zvezdochiot zvezdochiot added the dispute Debate label Jan 21, 2023
@zvezdochiot
Copy link
Member Author

zvezdochiot commented Jan 22, 2023

@plzombie . Надо к чему то приходить. Меня категорически не устраивает твоя шкала. Тебя чем то не устраивает моя. Предлагай тогда хоть что то более вменяемое. Будем посмотреть. Но так как щаз оставлять точно не следует.

PS: Предлагаемый вариант как минимум должен иметь возмость сделать "как у всех".

@plzombie
Copy link
Contributor

Что ты подразумеваешь под "как у всех"? Если стандартные параметры в djvulibre, то у меня это -quality 69

@zvezdochiot
Copy link
Member Author

zvezdochiot commented Jan 22, 2023

@plzombie say:

Что ты подразумеваешь под "как у всех"?

@zvezdochiot say:

slices fg = 100, slices bg = {74,84,88,97} ("как у всех")

И "это" никак не влияет на откровенную негодность линейной шкалы!

PS: Я щаз вожусь с mfbpdf на базе DjVuL и ppm2tiff(libtiff). Тот ещё геморой. Пока разобрался только с tiff-маской и jpeg-{bg,fg}. Теперь самое тяжкое: генератор PDF по заранее изготовленному шаблону (готовой MFB-pdf).

@plzombie
Copy link
Contributor

plzombie commented Jan 22, 2023

Это djvu solo такие параметры выдаёт?
Не знаю, чем тебе не нравится линейная шкала. У тебя при quality > 60 значения топчутся на месте с степенной функцией.
И мне кажется tiff сейчас такая же экзотика, как и netpbm. Сейчас даже "сканирование" в винде в png по умолчанию сохраняет

@zvezdochiot
Copy link
Member Author

@plzombie say:

Это djvu solo такие параметры выдаёт?

Нет. DjVuSolo не умеет FG44.

@plzombie say:

Не знаю, чем тебе не нравится линейная шкала.

@zvezdochiot say:

Сохрани в ряд -quality = 0, 25, 50, 75, 100, и визуально оцени.

"Это" категорически не нравится моим глазам. И мне не нравится искусственный верхний предел.

@plzombie say:

И мне кажется tiff сейчас такая же экзотика, как и netpbm.

Уверен? Только вот именно он является частью PDF: CCITT Fax Group{3,4}, JBIG2.

@plzombie
Copy link
Contributor

plzombie commented Jan 22, 2023

"Это" категорически не нравится моим глазам. И мне не нравится искусственный верхний предел.

По мне, там явно есть прогресс между 0, 15, 25, 40, 50, 60, 70...

Уверен? Только вот именно он является частью PDF: CCITT Fax Group{3,4}, JBIG2.

Ну ок. То что в tiff запихнули zip(deflate), jpeg и jbig не отменяет того факта, что люди предпочитают png(deflate), jpeg и... где там используется jbig

@plzombie
Copy link
Contributor

plzombie commented Jan 22, 2023

По мне, там явно есть прогресс между 0, 15, 25, 40, 50, 60, 70...

Ну можно для quality < 70 как раз использовать степенную функцию. Но выше -slices 130 я не вижу смысла делать. И никто тебя не заставляет у себя в программе делать верхний предел

@zvezdochiot
Copy link
Member Author

zvezdochiot commented Jan 22, 2023

@plzombie say:

По мне, там...

Что у тебя со зрением? Или самовнущение? Тогда сравни с mfbdjvu в нынешнем состоянии шкалы.

@plzombie say:

люди предпочитают png(deflate)

Мне ненужен png(deflate)! Он не подходит для MFB! Мне нужен CCITT Fax Group4, JBIG2. (И кстати, в PDF нифига не PNG, а его извращённая страшным образом производная).

@plzombie say:

И никто тебя не заставляет у себя в программе делать верхний предел

Значит ты против того, чтобы наши шкалы совпадали? Или что ты сказал? А чего тогдя я здесь распинаюсь?

@plzombie
Copy link
Contributor

изображение
изображение
Ну и если приблизитьт 1:1, то разница между 50/60/70 будет конечно же больше

Мне ненужен png(deflate)! Он не подходит для MFB! Мне нужен CCITT Fax Group4, JBIG2. (И кстати, в PDF нифига не PNG, а его извращённая страшным образом производная).

Ты хочешь из tiff напрямую в djvu передавать jb2? Без перекодирования?

@zvezdochiot
Copy link
Member Author

@plzombie say:

то разница

Всё познаётся в сравнении:

Тогда сравни с mfbdjvu в нынешнем состоянии шкалы.

@plzombie say:

Ты хочешь из tiff напрямую в djvu передавать jb2? Без перекодирования?

Вообще то разговор был за PDF. Ежели вернуть всё на места, то да. Tiff и JPEG встраиваются в PDF без перекодирования (в отличии от PNG).

@plzombie
Copy link
Contributor

plzombie commented Jan 22, 2023

png - lossless. Все lossy алгоритмы для png основываются на том, что ты сначала применяешь квантование/постеризацию к исходному изображению

@zvezdochiot
Copy link
Member Author

zvezdochiot commented Jan 22, 2023

@plzombie say:

png - lossless.

Tiff тоже по большей части lossless. И? В PDF PNG находится в уродливом извращённом виде. Нах он там нужен? Почему? Потому что Adobe пользует "слегка" свой deflate.

@zvezdochiot
Copy link
Member Author

zvezdochiot commented Jan 23, 2023

Hi @plzombie .

Тестирование последней версии log_quality:
mona series
слева-направо, сверху-вниз: origin, quality 0, 5, 10,. .., 145, 150.

Представление метриками:
m

Согласно более направленной на человеческое восприятие VIFP1 шкала очень даже лаконична. Но! Она же позволяет сдвинуть шкалу на дефолтное значение 75 вместо 100 (см. график)

Логарифмическая шкала с дефолтом в 75:

                n = (n < 0) ? 0 : n;
                keys->quality = (float)n * 0.01f;
                float lq = log10(1.0f + keys->quality * 12.0f); // == 1.0 for quality 75
                vector<int> nf, nb;
                nb.push_back((int)(lq * 57.0f + 0.5f) + 17);
                nb.push_back((int)(lq * 66.0f + 0.5f) + 18);
                nb.push_back((int)(lq * 69.0f + 0.5f) + 19);
                nb.push_back((int)(lq * 77.0f + 0.5f) + 20);
                keys->slices_bg = nb;
                nf.push_back((int)(lq * 80.0f + 0.5f) + 20);
                keys->slices_fg = nf;
  • quality = 25, slices fg = 68, slices bg = {51,58,61,66}
  • quality = 50, slices fg = 88, slices bg = {65,74,77,85}
  • quality = 75, slices fg = 100, slices bg = {74,84,88,97} ("как у всех")
  • quality = 100, slices fg = 109, slices bg = {80,92,96,106}
  • quality = 125, slices fg = 116, slices bg = {86,97,102,113}
ls -l *.djvu
  701768  mona.ppm.q025.djvu
  722521  mona.ppm.q050.djvu
  777396  mona.ppm.q075.djvu
  892305  mona.ppm.q100.djvu
 1039080  mona.ppm.q125.djvu

m75

@plzombie
Copy link
Contributor

Я визуально их почти не отличаю с конца второго ряда. Могу, допустим, в свою программу добавить выбор метрики для quality

@zvezdochiot
Copy link
Member Author

zvezdochiot commented Jan 23, 2023

@plzombie say:

Могу, допустим, в свою программу добавить выбор метрики для quality

Не обязательно. Главное, чтобы они как то и в чём то пересекались. Особенно в ключевых точках. Какие slices выдаёт твоя метрика для quality 75 и 100? Ежели более-менее будут "похожи", то и пёс с ним.

PS: Или найди на своей шкале значение наиболее похожее на мои quality 75.

@zvezdochiot zvezdochiot added the complete Performed label Jan 23, 2023
@plzombie
Copy link
Contributor

67-70 примерный аналог твоего 75

@zvezdochiot
Copy link
Member Author

@plzombie say:

67-70

Всё гуд. Сборочку сделаешь?

@plzombie
Copy link
Contributor

Ок, сейчас

@plzombie
Copy link
Contributor

@zvezdochiot Посмотри здесь варнинги, связанные с неявным приведением типов plzombie/depress@05c6d45

Строки 351,359,613,621 - не совсем понятно, зачем ты к float приводишь, если обе переменные - int, и результат будет приведён к int

@zvezdochiot
Copy link
Member Author

zvezdochiot commented Jan 25, 2023

@plzombie say:

Строки 351,359,613,621

unsigned long int fgsum[DJVUL_IMAGE_CHANNELS], bgsum[DJVUL_IMAGE_CHANNELS];

Твою ж мать. А ведь накопители должны быть в float (оберег для больших изображений). И ведь делал же вроде. Ну как так то? Хотя и long-и сойдут. Тогда действительно запарился и перенедокумекал. Уберу. Спасибо.

PS: Можешь так же писать в дискуссии. Они есть и для отдельных реп и общие для организации.

@zvezdochiot
Copy link
Member Author

@zvezdochiot
Copy link
Member Author

zvezdochiot commented Jan 26, 2023

@zvezdochiot
Copy link
Member Author

Привет @plzombie .

Сделаешь, как будет время, сборку https://github.com/ImageProcessing-ElectronicPublications/mfbdjvu/releases/tag/2.1 ? А то на ru-board смог сослаться только на 2.0.

@plzombie
Copy link
Contributor

@zvezdochiot
Готово

@zvezdochiot
Copy link
Member Author

@plzombie
Огромное сенкс.
Только наверное (я не уверен) надо win32 на win заменить в названиях архивов. Но я хз, может всё и верно.
👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
complete Performed dispute Debate enhancement New feature or request help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

2 participants