Ignore:
Timestamp:
08/03/08 20:36:17 (5 years ago)
Author:
sam
Message:
  • dbs.c: improve the DBS human visual system kernel by adding two Gaussian kernels.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • libpipi/trunk/pipi/dither/dbs.c

    r2651 r2663  
    2525#include "pipi_internals.h" 
    2626 
    27 #define N 5 
     27#define N 7 
    2828#define NN ((N * 2 + 1)) 
    2929 
    30 /* FIXME: use a better HVS than a simple gaussian; adding two gaussians 
    31  * seemed to be a lot more efficient. Get rid of pipi_gaussian_blur calls 
    32  * at the same time. */ 
    3330/* FIXME: though the algorithm is supposed to stop, we do not have a real, 
    3431 * guaranteed stop condition here. */ 
    3532 
    36 static void makegauss(double mat[NN][NN], double sigma) 
     33pipi_image_t *pipi_dbs(pipi_image_t *src) 
    3734{ 
    38     double t = 0; 
    39     int i, j; 
    40  
    41     sigma = 2. * sigma * sigma; 
     35    double kernel[NN * NN]; 
     36    double t = 0.; 
     37    pipi_image_t *dst, *tmp1, *tmp2; 
     38    pipi_pixels_t *srcp, *dstp, *tmp1p, *tmp2p; 
     39    float *srcdata, *dstdata, *tmp1data, *tmp2data; 
     40    int i, j, w, h; 
    4241 
    4342    for(j = 0; j < NN; j++) 
     
    4645            double a = (double)(i - N); 
    4746            double b = (double)(j - N); 
    48             mat[i][j] = pow(M_E, - (a * a + b * b) / sigma); 
    49             t += mat[i][j]; 
     47            kernel[j * NN + i] = 
     48                    1.0 * exp(-(a * a + b * b) / (2. * 1.5 * 1.5)) 
     49                  + 0.1 * exp(-(a * a + b * b) / (2. * 0.6 * 0.6)); 
     50            t += kernel[j * NN + i]; 
    5051        } 
    5152 
    5253    for(j = 0; j < NN; j++) 
    5354        for(i = 0; i < NN; i++) 
    54             mat[i][j] /= t; 
    55 } 
    56  
    57 pipi_image_t *pipi_dbs(pipi_image_t *src) 
    58 { 
    59     double mat[NN][NN]; 
    60     double sigma = 1.2; 
    61     pipi_image_t *dst, *tmp1, *tmp2; 
    62     pipi_pixels_t *srcp, *dstp, *tmp1p, *tmp2p; 
    63     float *srcdata, *dstdata, *tmp1data, *tmp2data; 
    64     int w, h; 
    65  
    66     makegauss(mat, sigma); 
     55            kernel[j * NN + i] /= t; 
    6756 
    6857    w = src->w; 
     
    7261    srcdata = (float *)srcp->pixels; 
    7362 
    74     tmp1 = pipi_gaussian_blur(src, sigma); 
     63    tmp1 = pipi_convolution(src, NN, NN, kernel); 
    7564    tmp1p = pipi_getpixels(tmp1, PIPI_PIXELS_Y_F); 
    7665    tmp1data = (float *)tmp1p->pixels; 
    7766 
    7867    /* The initial dither is an empty image. So is its blurred version, 
    79      * but I leave the pipi_gaussian_blur() call here in case we choose 
     68     * but I leave the pipi_convolution() call here in case we choose 
    8069     * to change the way to create the initial dither. */ 
    8170    dst = pipi_new(w, h); 
     
    8372    dstdata = (float *)dstp->pixels; 
    8473 
    85     tmp2 = pipi_gaussian_blur(dst, sigma); 
     74    tmp2 = pipi_convolution(dst, NN, NN, kernel); 
    8675    tmp2p = pipi_getpixels(tmp2, PIPI_PIXELS_Y_F); 
    8776    tmp2data = (float *)tmp2p->pixels; 
     
    9079    { 
    9180        int changes = 0; 
    92         int x, y, i, j, n; 
     81        int x, y, n; 
    9382 
    9483        for(y = 0; y < h; y++) 
     
    114103                        continue; 
    115104 
    116                     m = mat[i + N][j + N]; 
     105                    m = kernel[(j + N) * NN + i + N]; 
    117106                    p = tmp1data[(y + j) * w + x + i]; 
    118107                    q1 = tmp2data[(y + j) * w + x + i]; 
     
    153142                        if(i - idx + N < 0 || i - idx + N >= NN) 
    154143                            continue; 
    155                         ma = mat[i + N][j + N]; 
    156                         mb = mat[i - idx + N][j - idy + N]; 
     144                        ma = kernel[(j + N) * NN + i + N]; 
     145                        mb = kernel[(j - idy + N) * NN + i - idx + N]; 
    157146                        p = tmp1data[(y + j) * w + x + i]; 
    158147                        q1 = tmp2data[(y + j) * w + x + i]; 
     
    183172            for(i = -N; i < N + 1; i++) 
    184173            { 
    185                 double m = mat[i + N][j + N]; 
     174                double m = kernel[(j + N) * NN + i + N]; 
    186175                if(y + j >= 0 && y + j < h 
    187176                    && x + i >= 0 && x + i < w) 
    188177                { 
    189                     double t = tmp2data[(y + j) * w + x + i]; 
     178                    t = tmp2data[(y + j) * w + x + i]; 
    190179                    tmp2data[(y + j) * w + x + i] = t + m * (d2 - d); 
    191180                } 
     
    193182                                && x + opx + i >= 0 && x + opx + i < w) 
    194183                { 
    195                     double t = tmp2data[(y + opy + j) * w + x + opx + i]; 
     184                    t = tmp2data[(y + opy + j) * w + x + opx + i]; 
    196185                    tmp2data[(y + opy + j) * w + x + opx + i] 
    197186                            = t + m * (d - d2); 
Note: See TracChangeset for help on using the changeset viewer.