Comments 26
Ещё, как гипотеза, от паттернов может помочь добавление некоторой доли случайности в матрицу распределения ошибки
case 1: mask = ((x ^ y * 149) * 1234& 511)/511.0; break;
case 2: mask = (((x+c*17) ^ y * 149) * 1234 & 511)/511.0; break;
case 3: mask = ((x + y * 237) * 119 & 255)/255.0; break;
case 4: mask = (((x+c*67) + y * 236) * 119 & 255)/255.0; break;

Вычисление матрицы дизеринга - сама по себе непростая и интересная задача. Алгоритм Noise shaping должен удовлетворять двум противоречивым требованиям: максимальное подавление нижних частот и равномерность распределения значений в интервале [0; 1). Если просто поочерёдно применять операции highpass и remap, то профиль шума может всё равно получиться неоднородным (см. статью). Хороший шум можно получить только путём параметрической оптимизации.
Приведу примеры дизеринга последовательностью R2 (той, что по вашей ссылке)


Код
use image::io::Reader as ImageReader;
use image::Pixel;
fn main() {
for path in ["1.png", "2.png"] {
let img = ImageReader::open(path).unwrap().decode().unwrap();
let mut imgbuf = img.to_luma8();
for (x, y, pixel) in imgbuf.enumerate_pixels_mut() {
pixel.apply(|v| {
let value = (v as f32) / 255.0;
let linear = value * value;
if linear < r2(x, y) {
0
} else {
255
}
});
}
let name = format!("{path}_golden.png");
imgbuf.save(name).unwrap();
}
}
fn r2(x: u32, y: u32) -> f32 {
let a1 = 0.7548776662;
let a2 = 0.56984029;
let t = (x as f32 * a1 + y as f32 * a2).fract();
if t < 0.5 {
2.0 * t
} else {
2.0 - 2.0 * t
}
}
Дизеринг до сих пор актуален для E-Ink экранов. Не помню точно какой алгоритм использовали в YotaPhone 2, но на нём можно было вполне комфортно работать в Android приложениях и даже смотреть youtube!
Интересная статья. Немного перекликается с полиграфической темой. Там рипы решают аналогичные задачи. И например изображение по алгоритму Аткинсона очень похоже на стохастическое растрирование (так оно у полиграфистов называется). Еще есть интересные растры - например линейный. Думаю на экране он бы смотрелся очень интересно.
по роду службы часто необходим дизеринг и я использую отличный сервис dither me.
единственное что могу отмеить - независимо от алгоритма, изображение всегда приходится притемнять. (я обычно использую палитру из 3 или 4х цветов)
Я не знаю, та ли это статья, что упоминается здесь, но перевод статьи (точнее, поста на форуме) по реализации дизеринга в Return of the Obra Dinn есть на хабре.
при разглядывании картинок возникал эффект догрузки изображения: к примеру градиент вначале статьи. Через секунду после втыкания в градиент, при движении глаз вдоль по полоске, он скачкообразно становился более размытым и появлялись границы рисунка. Аналогично с остальными картинками из статьи - они как-то пляшут. Скажите, это только я вижу или кто-то еще?
Это та статья о дизеренге которую я давно хотел почитать. Спасибо!
интересно, понятно, познавательно. большое спасибо за труд!
Мне больше нравится телеграм-бот @ZXRasterBot от камрада @Error1024 делающий вот такое прекрасное. Там можно часами подбирать подходящие под конкретную картинку параметры.

Если рисовать дизеринг вручную для статичной картинки, будет нелегко следовать алгоритмам.
Познакомился с ними еще давно благодаря Corel Photo-Paint. Жаль, что про мой любимый алгоритм - Stucki - не написали.
Не очень понял пассаж про sRGB и RGB. Особенно в контексте ч/б. RGB - пространство цветное и аппаратно-зависимое. Любое RGB устройство не способно отображать внеохватные цвета. sRGB-то в полном объеме далеко не все экраны поддерживают, я уж молчу про AdobeRGB и ProPhotoRGB.
Если говорить про монохромность черная, среднесерая и белая точки так же будут для каждого монитора свои.
Вот кстати, в статье я не вижу, чем вроде как "более точный" пример градиента лучше "неправильного". С моей точки зрения, как раз неправильный больше похож на оригинал
Картинки градиентов из публикации проверяют как хорошо откалиброван ваш монитор по гамме, ха.
Но, на самом деле, тут есть и палка о двух концах. С гамма-коррекцией дизеринг сохраняет яркость, но теряет в детализации темных областей и визуальной равномерности (простыми словами - редкие белые точки в тенях становятся ещё более редкими).
Из собственной практики (подготовка изображений для лазерной гравировки или текстур для фрезерования) могу добавить, что собственно dithering, как его ни крути, очень редко дает действительно хороший результат. Весьма часто приходится сначала довольно сильно искажать изображение путем wavelet-фильтрации, имитируя довольно агрессивный tone mapping, добиваясь более высокого локального контраста вместо глобального.
Дизерпанк — статья о дизеринге изображений, которую мне хотелось бы прочитать