首页 > 技术文章 > Bayer抖动表

yanye0xff 2022-03-29 18:32 原文

M1

  0,   2,
  3,   1,

M2

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

M3

  0,  32,   8,  40,   2,  34,  10,  42,
 48,  16,  56,  24,  50,  18,  58,  26,
 12,  44,   4,  36,  14,  46,   6,  38,
 60,  28,  52,  20,  62,  30,  54,  22,
  3,  35,  11,  43,   1,  33,   9,  41,
 51,  19,  59,  27,  49,  17,  57,  25,
 15,  47,   7,  39,  13,  45,   5,  37,
 63,  31,  55,  23,  61,  29,  53,  21,

M4

  0, 128,  32, 160,   8, 136,  40, 168,   2, 130,  34, 162,  10, 138,  42, 170,
192,  64, 224,  96, 200,  72, 232, 104, 194,  66, 226,  98, 202,  74, 234, 106,
 48, 176,  16, 144,  56, 184,  24, 152,  50, 178,  18, 146,  58, 186,  26, 154,
240, 112, 208,  80, 248, 120, 216,  88, 242, 114, 210,  82, 250, 122, 218,  90,
 12, 140,  44, 172,   4, 132,  36, 164,  14, 142,  46, 174,   6, 134,  38, 166,
204,  76, 236, 108, 196,  68, 228, 100, 206,  78, 238, 110, 198,  70, 230, 102,
 60, 188,  28, 156,  52, 180,  20, 148,  62, 190,  30, 158,  54, 182,  22, 150,
252, 124, 220,  92, 244, 116, 212,  84, 254, 126, 222,  94, 246, 118, 214,  86,
  3, 131,  35, 163,  11, 139,  43, 171,   1, 129,  33, 161,   9, 137,  41, 169,
195,  67, 227,  99, 203,  75, 235, 107, 193,  65, 225,  97, 201,  73, 233, 105,
 51, 179,  19, 147,  59, 187,  27, 155,  49, 177,  17, 145,  57, 185,  25, 153,
243, 115, 211,  83, 251, 123, 219,  91, 241, 113, 209,  81, 249, 121, 217,  89,
 15, 143,  47, 175,   7, 135,  39, 167,  13, 141,  45, 173,   5, 133,  37, 165,
207,  79, 239, 111, 199,  71, 231, 103, 205,  77, 237, 109, 197,  69, 229, 101,
 63, 191,  31, 159,  55, 183,  23, 151,  61, 189,  29, 157,  53, 181,  21, 149,
255, 127, 223,  95, 247, 119, 215,  87, 253, 125, 221,  93, 245, 117, 213,  85,

标准图案的算法

由Limb在1969年提出:

C语言实现

#include <cstdio>
#include <cstring>
#include <cmath>

static void calcDitherTable(int level);
static void matrixAdd(int *a, int *b, int n);
static void matrixMulti(int *a, int *b, int n);
static void matrixScale(int s, int *a, int n);
static void matrixFill(int *a, int n, int val);
static void copyMatrix(int *dest, int dn, int dx, int dy, int *src, int sn);
static void printMatrix(const int *mat, int n);

const int M1[4] = {0, 2,3, 1};

int main(int argc, char *argv[]) {
    calcDitherTable(4);
    return 0;
}

static void calcDitherTable(int level) {
    int rn, sn;
    int lastRn;

    int *resultMatrix;
    int *lastResultMatrix;

    int *scaleMatrix;
    int *onesMatrix;

    for(int i = 1; i <= level; i++) {
        rn = (int)pow(2, i);
        sn = (int)pow(2, (i - 1));
        if(i == 1) {
            resultMatrix = (int *) malloc(sizeof(int) * (rn * rn));
            memcpy(resultMatrix, M1, sizeof(int) * (rn * rn));
            lastResultMatrix = resultMatrix;
            lastRn = rn;
        }else {
            resultMatrix = (int *) malloc(sizeof(int) * (rn * rn));
            scaleMatrix = (int *)malloc(sizeof(int) * sn * sn);
            onesMatrix = (int *)malloc(sizeof(int) * sn * sn);

            copyMatrix(scaleMatrix, sn, 0, 0, lastResultMatrix, lastRn);
            matrixScale(4, scaleMatrix, sn);
            copyMatrix(resultMatrix, rn, 0, 0, scaleMatrix, sn);

            matrixFill(onesMatrix, sn, 2);
            matrixAdd(onesMatrix, scaleMatrix, sn);
            copyMatrix(resultMatrix, rn, sn, 0,onesMatrix, sn);

            matrixFill(onesMatrix, sn, 3);
            matrixAdd(onesMatrix, scaleMatrix, sn);
            copyMatrix(resultMatrix, rn, 0, sn,onesMatrix, sn);

            matrixFill(onesMatrix, sn, 1);
            matrixAdd(onesMatrix, scaleMatrix, sn);
            copyMatrix(resultMatrix, rn, sn, sn,onesMatrix, sn);

            free(scaleMatrix);
            free(onesMatrix);
            free(lastResultMatrix);
            lastResultMatrix = resultMatrix;
            lastRn = rn;
        }
    }
    printMatrix(lastResultMatrix, lastRn);
    free(lastResultMatrix);
}

static void matrixAdd(int *a, int *b, int n) {
    int *aline;
    int *bline;
    for (int i = 0; i < n; ++i) {
        aline = (a + n * i);
        bline = (b + n * i);
        for (int j = 0; j < n; ++j) {
            aline[j] += bline[j];
        }
    }
}

static void matrixMulti(int *a, int *b, int n) {
    int *aline;
    int *bline;
    for (int i = 0; i < n; ++i) {
        aline = (a + n * i);
        bline = (b + n * i);
        for (int j = 0; j < n; ++j) {
            aline[j] *= bline[j];
        }
    }
}

static void matrixScale(int s, int *a, int n) {
    int *aline;
    for (int i = 0; i < n; ++i) {
        aline = (a + n * i);
        for (int j = 0; j < n; ++j) {
            aline[j] *= s;
        }
    }
}

static void matrixFill(int *a, int n, int val) {
    int *aline;
    for (int i = 0; i < n; ++i) {
        aline = (a + n * i);
        for (int j = 0; j < n; ++j) {
            aline[j] = val;
        }
    }
}

static void copyMatrix(int *dest, int dn, int dx, int dy, int *src, int sn) {
    if((dx + sn > dn) || (dy + sn > dn)) {
        return;
    }
    int *dline;
    int *sline;
    for (int i = 0; i < sn; i++) {
        dline = (dest + (dy + i) * dn);
        sline = (src + i * sn);
        for (int j = 0; j < sn; j++) {
            dline[dx + j] = sline[j];
        }
    }
}

static void printMatrix(const int *mat, int n) {
    int *line;
    for(int i = 0; i < n; i++) {
        line = (int *)(mat + i * n);
        for(int j = 0; j < n; j++) {
            printf("%3d, ", line[j]);
        }
        printf("\n");
    }
    printf("\n");
}

推荐阅读