【问题标题】:How to implement 24bit to 3bit ordered dither algorithm?如何实现 24 位到 3 位有序抖动算法?
【发布时间】:2016-07-05 08:45:02
【问题描述】:

我正在尝试实现拜耳有序抖动矩阵算法以将 24 位彩色图像转换为 3 位图像。我已经阅读了维基百科页面,以及有关该主题的几个教科书部分,并且有点困惑。这是我目前所拥有的:

for (int y = 0; x < image.Height; y++)
{  
    for (int x = 0; x < image.Width; x++)
    {
        Color color = image.GetPixel(x,y);  
        color.R = color.R + bayer4x4[x % 4, y % 4];  
        color.G = color.G + bayer4x4[x % 4, y % 4];  
        color.B = color.B + bayer4x4[x % 4, y % 4];  
        image[x][y] = SetPixel(x, y, GetClosestColor(color, bitdepth);  
    }  
}

但是,我没有办法实现 GetClosestColor... 我该怎么做?

另外,我没有定义 bayer4x4 矩阵,我相信它应该如下所示:

1,  9,  3, 11
13, 5, 15, 7
4, 12,  2, 10
16, 8, 14, 6

【问题讨论】:

  • GetClosestColor 会查看目标托盘,那么您有什么托盘?
  • 另外,当您从 256 色缩放到 8 色时,您需要不同的阈值图
  • @Lashane 是的,但他们说源是 24 位的,所以我认为他们至少需要 8x8 矩阵,因此大小匹配 256:1 的缩小率,但如果这是灰度,我不知道是否有不同的数学适用。
  • 这确实是灰度。我希望有 1 位红色、1 位绿色和 1 位蓝色。因此,有 16+1 种不同的灰度等级。
  • 1 bit red, 1 bit green, and 1 bit blue. 是 8 个级别

标签: c# image algorithm image-processing dithering


【解决方案1】:

这是我对拜耳 4x4 的实现。
输入和输出均为 24 位 BGR 格式(用于可视化目的)。
在输出中,每个像素平面的值都是 0 或 255。

const   int BAYER_PATTERN_4X4[4][4]     =   {   //  4x4 Bayer Dithering Matrix. Color levels: 17
                                                {    15, 195,  60, 240  },
                                                {   135,  75, 180, 120  },
                                                {    45, 225,  30, 210  },
                                                {   165, 105, 150,  90  }

                                            };

void    makeColorDitherBayer4x4( BYTE* pixels, int width, int height )  noexcept
{
    int col = 0;
    int row = 0;

    for( int y = 0; y < height; y++ )
    {
        row = y & 3;    //  % 4
        
        for( int x = 0; x < width; x++ )
        {
            col = x & 3;    //  % 4

            const pixel blue    = pixels[x * 3 + 0];
            const pixel green   = pixels[x * 3 + 1];
            const pixel red     = pixels[x * 3 + 2];

            pixels[x * 3 + 0]   = (blue  < BAYER_PATTERN_4X4[col][row] ? 0 : 255);
            pixels[x * 3 + 1]   = (green < BAYER_PATTERN_4X4[col][row] ? 0 : 255);
            pixels[x * 3 + 2]   = (red   < BAYER_PATTERN_4X4[col][row] ? 0 : 255);

        }

        pixels  += width * 3;
    }
}

如果你想将输出作为“压缩”数据,你应该替换这部分代码:

pixels[x * 3 + 0]   = (blue  < BAYER_PATTERN_4X4[col][row] ? 0 : 255);
pixels[x * 3 + 1]   = (green < BAYER_PATTERN_4X4[col][row] ? 0 : 255);
pixels[x * 3 + 2]   = (red   < BAYER_PATTERN_4X4[col][row] ? 0 : 255);

类似这样的:

output.writeBit( (blue  < BAYER_PATTERN_4X4[col][row] ? 0 : 1) );
output.writeBit( (green < BAYER_PATTERN_4X4[col][row] ? 0 : 1) );
output.writeBit( (red   < BAYER_PATTERN_4X4[col][row] ? 0 : 1) );

【讨论】:

  • 亲爱的 Svetlyo,在回答时,用来句介绍解决方案并留下 cmets 是一个好习惯,这将有助于其他人通过类比解决类似问题
猜你喜欢
  • 1970-01-01
  • 2011-08-21
  • 1970-01-01
  • 2012-07-23
  • 1970-01-01
  • 2021-08-27
  • 2012-07-25
  • 2018-05-29
  • 1970-01-01
相关资源
最近更新 更多