有序抖动 - 每通道的颜色值

问题描述 投票:0回答:1

在推进我的Ordered Dithering算法时,我遇到了一个问题,主要是我真的不知道col[levels]可能是什么。

下面是伪代码

enter image description here

k - 每个通道的色值数量

n - 阈值贝叶斯矩阵的大小

我的代码在K=2的情况下可以正常工作,但是当K=3,K=4等情况下,它不能返回正确的结果图像。

更新后的代码

class OrderedDithering
{
    private float[,] bayerMatrix;

    private float[,] dither2x2Matrix =
        new float[,] { { 1, 3 },
                    { 4, 2 } };

    private float[,] dither3x3Matrix =
        new float[,] { { 3, 7, 4 },
                    { 6, 1, 9 },
                     { 2, 8, 5 } };

    public BitmapImage OrderedDitheringApply(BitmapImage FilteredImage, int valuesPerChannel, int thresholdSize)
    {
        Bitmap bitmap = ImageConverters.BitmapImage2Bitmap(FilteredImage);

        if (thresholdSize == 2)
        {
            bayerMatrix = new float[2, 2];
            for (int i = 0; i < 2; ++i)
                for (int j = 0; j < 2; ++j)
                    bayerMatrix[i,j] = dither2x2Matrix[i,j] / 5;
        }
        else
        {
            bayerMatrix = new float[3, 3];
            for (int i = 0; i < 3; ++i)
                for (int j = 0; j < 3; ++j)
                    bayerMatrix[i, j] = dither3x3Matrix[i, j] / 10;
        }

        for (int i = 0; i < bitmap.Width; ++i)
            for(int j = 0; j < bitmap.Height; ++j)
            {

                Color color = bitmap.GetPixel(i, j);
                double r = Scale(0, 255, 0, 1, color.R);
                double g = Scale(0, 255, 0, 1, color.G);
                double b = Scale(0, 255, 0, 1, color.B);

                int counter = 0;
                counter += Dither(valuesPerChannel, r, thresholdSize, i, j);
                counter += Dither(valuesPerChannel, g, thresholdSize, i, j);
                counter += Dither(valuesPerChannel, b, thresholdSize, i, j);

                if (counter == 0)
                    bitmap.SetPixel(i, j, Color.FromArgb(0,0,0));
                else
                    bitmap.SetPixel(i, j, Color.FromArgb(255/counter, 255/counter, 255/counter));
            }

        return ImageConverters.Bitmap2BitmapImage(bitmap);
    }

    public int Dither(int valuesPerChannel, double colorIntensity, int thresholdSize, int i, int j)
    {
        double tempValue = (double)(Math.Floor((double)((valuesPerChannel - 1) * colorIntensity)));
        double re = (valuesPerChannel - 1) * colorIntensity - tempValue;

        if (re >= bayerMatrix[i % thresholdSize, j % thresholdSize])
            return 1;
        else
            return 0;
    }

    public double Scale(double a0, double a1, double b0, double b1, double a)
    {
        return b0 + (b1 - b0) * ((a - a0) / (a1 - a0));
    }
}
c# image-processing dithering
1个回答
1
投票

如果你只是需要一个能和 System.Drawing 并支持有序的抖动,可以随意使用 开采. 它有一个易于使用的 OrderedDitherer 类。

但如果你只是出于好奇,想改进你的算法,这里有一些意见。

  • 你现在总是将像素设置为黑色或白色(顺便说一下,你可以只用 "黑 "或 "白 "来设置)。Color.Black 而不是 FromArgb(0, 0, 0)例如,),所以它不能用于更多的颜色。
  • 从提供的代码来看,不清楚目标调色板是否属于 colorsNum 但基本上你需要将所有抖动的像素量化到最接近的变换颜色。
  • 因此,你应该对每个像素的每个颜色通道(在0...255范围内)应用有序矩阵,并从目标调色板中挑选一种颜色作为结果。最接近的颜色 "可以有更多的解释,但一般来说,欧几里得搜索就可以了。
  • 尽量避免 Bitmap.SetPixelGetPixel 因为它们慢得可怕,而且 SetPixel 甚至对有索引调色板的位图也不适用。PixelFormat.
  • 你的代码没有显示矩阵的值,但这些值也应该为你使用的调色板进行校准。典型的默认值对于黑白调色板来说是很好的,但对于256色调色板来说可能太强了(抖动会 "跳过 "更多的色调,并引入更多的噪音,而不是漂亮的渐变)。请看 这个 页面获取更多信息。

欢迎探索链接的代码库。该 抖动 扩展方法是抖动的起点。Bitmap 原地踏步,而这里是 OrderedDitherer构造函数జజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజ 强度校准 矩阵的最小值和最大值,以及一个相当快的。最近的颜色搜索 无论是按RGB通道还是按亮度。

© www.soinside.com 2019 - 2024. All rights reserved.