我正在尝试使用 Wikipedia 页面https://en.wikipedia.org/wiki/Floyd%E2%80%93Steinberg_dithering上的伪代码在 MATLAB 中实现 Floyd Steinberg Dithering
我的代码如下
image = double(imread("dithering.jpg")) ./ 255;
levels = 2;
image_quantised = round(image .* (levels - 1)) ./ (levels - 1);
error = image - image_quantised;
height = size(image(:, :, 1), 1);
width = size(image(:, :, 1), 2);
image_dithered = image_quantised;
for y = 1:height - 1
for x = 2:width - 1
image_dithered(y , x + 1, :) = image_dithered(y , x + 1, :) + error(y, x, :) .* 7 / 16;
image_dithered(y + 1, x - 1, :) = image_dithered(y + 1, x - 1, :) + error(y, x, :) .* 3 / 16;
image_dithered(y + 1, x , :) = image_dithered(y + 1, x , :) + error(y, x, :) .* 5 / 16;
image_dithered(y + 1, x + 1, :) = image_dithered(y + 1, x + 1, :) + error(y, x, :) .* 1 / 16;
end
end
imshow(image_dithered) % Image 1
imshow(dither(mean(image, 3))) % Image 2
图 1
图 2
我期待图像 2 中的结果,但我得到的是图像 1。看起来算法没有做任何事情。有任何想法吗?:)
编辑:我尝试image_dithered
使用不同的值进行初始化;全零,量化图像和原始图像。它们都不能正常工作
编辑2:我现在计算循环内的误差和量化越来越近了。然而,仍然没有发现。
for y = 1:height - 1
for x = 2:width - 1
new_pixel = round(image_dithered(y, x, :) .* (levels - 1)) ./ (levels - 1);
image_dithered(y, x, :) = new_pixel;
error = image(y, x, :) - new_pixel;
image_dithered(y , x + 1, :) = image_dithered(y , x + 1, :) + error .* 7 / 16;
image_dithered(y + 1, x - 1, :) = image_dithered(y + 1, x - 1, :) + error .* 3 / 16;
image_dithered(y + 1, x , :) = image_dithered(y + 1, x , :) + error .* 5 / 16;
image_dithered(y + 1, x + 1, :) = image_dithered(y + 1, x + 1, :) + error .* 1 / 16;
end
end
编辑 3:感谢@saastn 和@Cris Luengo,这两个答案都帮助我找出了哪里出错了,现在它似乎正在按预期工作!
为了完整起见,固定代码如下。
height = size(image(:, :, 1), 1);
width = size(image(:, :, 1), 2);
image_dithered = image;
for y = 1:height - 1
for x = 2:width - 1
old_pixel = image_dithered(y, x, :);
new_pixel = round(image_dithered(y, x, :) .* (levels - 1)) ./ (levels - 1);
image_dithered(y, x, :) = new_pixel;
error = old_pixel - new_pixel;
image_dithered(y , x + 1, :) = image_dithered(y , x + 1, :) + error .* 7 / 16;
image_dithered(y + 1, x - 1, :) = image_dithered(y + 1, x - 1, :) + error .* 3 / 16;
image_dithered(y + 1, x , :) = image_dithered(y + 1, x , :) + error .* 5 / 16;
image_dithered(y + 1, x + 1, :) = image_dithered(y + 1, x + 1, :) + error .* 1 / 16;
end
end
imshow(image_dithered)
imshow(dither(mean(image, 3)))