В результате видно полосы, т.к. этот чистый градиент без дизеринга.
Это можно посмотреть, просто открыв pgm-файл в текстовом редакторе.
Не работают методы потому, что плохо написаны. Конкретнее, выбран неправильный тип данных для пикселя исходного градиента: целочисленный вместо с плавающей (или фиксированной) точкой.
В методах ordered_dither и random_dither есть такой код:
int requiredShade = some_value;
if ((requiredShade > 0) && (requiredShade < 1))
Здесь условие никогда не сработает, т.к. переменная requiredShade - целочисленная.
В методах fs_dither и jjn_dither result - вектор целочисленных переменных:
int oldpixel = result[i][j];
int newpixel = round(result[i][j]);
int quanterror = oldpixel - newpixel;
oldpixel и newpixel всегда совпадают, quanterror всегда оказывается нулём.
Думаю, проблемы можно решить, поменяв тип пикселя на float/double, а из функций дизеринга возвращать уже массив int'ов (или uint8_t), вроде такого:
vector<vector<int>> fs_dither(int height, int width, const vector<vector<float>> &input_gradient); // const & - чтобы вектор не копировался лишний раз
Соотвественно, в остальном коде тоже проверить и поменять типы переменных, где требуется.
Советую изучить базовые типы в C и освоить отладчик.