在推进我的Ordered Dithering算法时,我遇到了一个问题,主要是我真的不知道col[levels]可能是什么。
下面是伪代码
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));
}
}
如果你只是需要一个能和 System.Drawing
并支持有序的抖动,可以随意使用 开采. 它有一个易于使用的 OrderedDitherer
类。
但如果你只是出于好奇,想改进你的算法,这里有一些意见。
Color.Black
而不是 FromArgb(0, 0, 0)
例如,),所以它不能用于更多的颜色。colorsNum
但基本上你需要将所有抖动的像素量化到最接近的变换颜色。Bitmap.SetPixel
GetPixel
因为它们慢得可怕,而且 SetPixel
甚至对有索引调色板的位图也不适用。PixelFormat
.欢迎探索链接的代码库。该 抖动 扩展方法是抖动的起点。Bitmap
原地踏步,而这里是 OrderedDitherer构造函数జజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజ 强度校准 矩阵的最小值和最大值,以及一个相当快的。最近的颜色搜索 无论是按RGB通道还是按亮度。