C# Floyd Steinberg错误扩散到灰度级别对于级别不正常>=4.

C# Floyd Steinberg错误扩散到灰度级别对于级别不正常>=4.,c#,image-processing,C#,Image Processing,所以我想让用户选择偶数个灰度作为输出图像, 我在wikipedia上找到了伪代码并实现了它(我认为这是正确的),如果我使用2个灰度(黑色和白色),效果很好,但是如果我选择4个或更多的灰度,而不是实际改进它,它会降低质量 将在评论中再发布2张图片(1.4次灰度抖动后的奇怪结果,2.4grayscales的正确结果),因为我没有超过2个链接的名声 这是我的密码: public static byte Truncate(byte a, int b) { if (a + b

所以我想让用户选择偶数个灰度作为输出图像, 我在wikipedia上找到了伪代码并实现了它(我认为这是正确的),如果我使用2个灰度(黑色和白色),效果很好,但是如果我选择4个或更多的灰度,而不是实际改进它,它会降低质量

将在评论中再发布2张图片(1.4次灰度抖动后的奇怪结果,2.4grayscales的正确结果),因为我没有超过2个链接的名声

这是我的密码:

public static byte Truncate(byte a, int b)
    {
        if (a + b < 0)
            return 0;
        else if (a + b > 255)
            return (byte)255;
        else
            return (byte)(a + b);
    }

public static Color FindNearestColor(Color color, Color[] palette)
    {
        int minDistanceSquared = 255 * 255 + 255 * 255 + 255 * 255 + 1;
        int bestIndex = 0;
        for (int i = 0; i < palette.Length; i++)
        {
            int Rdiff =(color.R) - (palette[i].R);
            int Gdiff =(color.G) - (palette[i].G);
            int Bdiff =(color.B) - (palette[i].B);
            int distanceSquared = Rdiff * Rdiff + Gdiff * Gdiff + Bdiff * Bdiff;
            if (distanceSquared < minDistanceSquared)
            {
                minDistanceSquared = distanceSquared;
                bestIndex = i;
            }
        }
        return palette[bestIndex];
    }
公共静态字节截断(字节a,int b)
{
如果(a+b<0)
返回0;
否则,如果(a+b>255)
返回(字节)255;
其他的
返回(字节)(a+b);
}
公共静态颜色FindNearestColor(颜色、颜色[]调色板)
{
int minDistanceSquared=255*255+255*255+255*255+1;
int-bestIndex=0;
for(int i=0;i
这是我的抖动函数

public static Bitmap Dither(Bitmap image,int grayshades)
    {
        Color[] palette = new Color[grayshades];
        double start = 0;
        for (int i = 0; i < palette.Length; i++)
        {
           double x = start;
            Color a =Color.FromArgb(255,(int)x, (int)x, (int)x);
            start += 255 / (grayshades - 1);
            palette[i] = a;
        }
        Color b = Color.FromArgb(255, 255, 255, 255);
        palette[palette.Length - 1] = b;
        int height = image.Height;
        int width = image.Width;
        for (int y = 0; y < height; y++)
        {
            for (int x = 0; x < width;x++)
            {
                Color currentPixel = image.GetPixel(x, y);
                Color bestColor = FindNearestColor(currentPixel, palette);
                image.SetPixel(x, y, bestColor);

                int errorR = (currentPixel.R) - (bestColor.R);
                int errorG = (currentPixel.G) - (bestColor.G);
                int errorB = (currentPixel.B) - (bestColor.B);
                if (x + 1 < width)
                {
                    image.SetPixel(x + 1, y + 0, Color.FromArgb(
                        Truncate(image.GetPixel(x + 1, y + 0).R, (errorR * 7) >> 4),
                        Truncate(image.GetPixel(x + 1, y + 0).G, (errorG * 7) >> 4),
                        Truncate(image.GetPixel(x + 1, y + 0).B, (errorB * 7) >> 4)
                    ));
                }
                if (y + 1 < height)
                {
                    if (x - 1 > 0)
                    {
                        image.SetPixel(x - 1, y + 1, Color.FromArgb(
                            Truncate(image.GetPixel(x - 1, y + 1).R, (errorR * 3) >> 4),
                            Truncate(image.GetPixel(x - 1, y + 1).G, (errorG * 3) >> 4),
                            Truncate(image.GetPixel(x - 1, y + 1).B, (errorB * 3) >> 4)
                        ));
                    }
                    image.SetPixel(x , y + 1, Color.FromArgb(
                        Truncate(image.GetPixel(x , y + 1).R, (errorR * 5) >> 4),
                        Truncate(image.GetPixel(x , y + 1).G, (errorG * 5) >> 4),
                        Truncate(image.GetPixel(x , y + 1).B, (errorB * 5) >> 4)
                    ));
                    if (x + 1 < width)
                    {
                        image.SetPixel(x + 1, y + 1, Color.FromArgb(
                            Truncate(image.GetPixel(x + 1, y + 1).R, (errorR * 1) >> 4),
                            Truncate(image.GetPixel(x + 1, y + 1).G, (errorG * 1) >> 4),
                            Truncate(image.GetPixel(x + 1, y + 1).B, (errorB * 1) >> 4)
                        ));
                    }
                }
            }
        }
        return image;
    }
公共静态位图抖动(位图图像,整数灰度)
{
颜色[]调色板=新颜色[灰度];
双启动=0;
for(int i=0;i>4),
截断(image.GetPixel(x+1,y+0).G,(errorG*7)>>4),
截断(image.GetPixel(x+1,y+0).B,(errorB*7)>>4)
));
}
如果(y+1<高度)
{
如果(x-1>0)
{
image.SetPixel(x-1,y+1,Color.FromArgb(
截断(image.GetPixel(x-1,y+1).R,(error*3)>>4),
截断(image.GetPixel(x-1,y+1).G,(errorG*3)>>4),
截断(image.GetPixel(x-1,y+1).B,(errorB*3)>>4)
));
}
image.SetPixel(x,y+1,Color.FromArgb(
截断(image.GetPixel(x,y+1).R,(error*5)>>4),
截断(image.GetPixel(x,y+1).G,(errorG*5)>>4),
截断(image.GetPixel(x,y+1).B,(errorB*5)>>4)
));
如果(x+1<宽度)
{
image.SetPixel(x+1,y+1,Color.FromArgb(
截断(image.GetPixel(x+1,y+1).R,(error*1)>>4),
截断(image.GetPixel(x+1,y+1).G,(errorG*1)>>4),
截断(image.GetPixel(x+1,y+1).B,(errorB*1)>>4)
));
}
}
}
}
返回图像;
}
我已经看了很多次这个代码,不知道为什么它产生不好的结果灰度>=4,如果你能帮我找到问题,将不胜感激,也请原谅我,如果我打破了任何规则,这是我的第一篇文章在这里。
提前感谢您的帮助和好意。

[我的程序给出的4个灰度的奇怪结果][3][4个灰度的正确结果应该是什么样子][4][3]:[4]:这是我使用的维基百科伪代码: