source: libpipi/trunk/examples/edd.c @ 2902

Last change on this file since 2902 was 2902, checked in by Sam Hocevar, 11 years ago

Support C99 types on Win32 through the same hacks as in libcaca.

File size: 3.0 KB
RevLine 
[2644]1/*
2 *  edd           error diffusion displacement
3 *  Copyright (c) 2008 Sam Hocevar <sam@zoy.org>
4 *                All Rights Reserved
5 *
6 *  $Id$
7 *
8 *  This program is free software. It comes without any warranty, to
9 *  the extent permitted by applicable law. You can redistribute it
10 *  and/or modify it under the terms of the Do What The Fuck You Want
11 *  To Public License, Version 2, as published by Sam Hocevar. See
12 *  http://sam.zoy.org/wtfpl/COPYING for more details.
13 */
14
15/* This program computes the Floyd-Steinberg error diffusion algorithm's
16 * displacement on the given input image. Error diffusion displacement is
17 * introduced in the paper "Reinstating Floyd-Steinberg: Improved Metrics
18 * for Quality Assessment of Error Diffusion Algorithms.", ICISP 2008
19 * Proceedings. Lecture Notes in Computer Science 5099 Springer 2008, ISBN
20 * 978-3-540-69904-0.
21 *
22 * The resulting dx/dy values are usually around 0.16/0.26 for images that
23 * are not entirely black and white. */
24
25#include "config.h"
26
27#include <stdio.h>
28#include <stdlib.h>
29#include <string.h>
30
31#include <pipi.h>
32
33#define Z 3
34
35int main(int argc, char *argv[])
36{
37    double sigma = 1.2, precision = 0.001, step = 2.;
38    double best = 1., fx = -1., fy = -1., bfx = 0., bfy = 0.;
[2647]39    double e, e0, e1;
[2759]40    pipi_image_t *img, *kernel, *gauss, *dither, *tmp;
[2644]41    int dx, dy;
42
43    if(argc < 2)
44    {
45        fprintf(stderr, "%s: too few arguments\n", argv[0]);
46        fprintf(stderr, "Usage: %s <image>\n", argv[0]);
47        return EXIT_FAILURE;
48    }
49
50    /* Load image, convert it to grayscale, dither it with Floyd-Steinberg */
51    img = pipi_load(argv[1]);
52    pipi_getpixels(img, PIPI_PIXELS_Y_F);
53    gauss = pipi_gaussian_blur(img, sigma);
[2759]54    kernel = pipi_load("ediff:fs");
55    dither = pipi_dither_ediff(img, kernel, PIPI_SCAN_RASTER);
56    pipi_free(kernel);
[2644]57    pipi_free(img);
58
59    /* Compute the standard error */
60    tmp = pipi_gaussian_blur(dither, sigma);
[2657]61    e0 = pipi_measure_msd(gauss, tmp);
[2644]62    pipi_free(tmp);
63
[2647]64    /* Compute the fast error */
[2715]65    tmp = pipi_gaussian_blur_ext(dither, sigma, sigma, 0.0, 0.16, 0.26);
[2657]66    e1 = pipi_measure_msd(gauss, tmp);
[2647]67    pipi_free(tmp);
68
[2644]69    /* Compute displacement */
70    while(step > precision)
71    {
72        for(dy = 0; dy <= Z; dy++)
73            for(dx = 0; dx <= Z; dx++)
74            {
[2715]75                tmp = pipi_gaussian_blur_ext(dither, sigma, sigma, 0.0,
[2644]76                                             fx + step * dx / Z,
77                                             fy + step * dy / Z);
[2657]78                e = pipi_measure_msd(gauss, tmp);
[2644]79                pipi_free(tmp);
80                if(e < best)
81                {
82                    best = e;
83                    bfx = fx + step * dx / Z;
84                    bfy = fy + step * dy / Z;
85                }
86            }
87
88        fx = bfx - step / Z;
89        fy = bfy - step / Z;
90        step = step * 2 / Z;
91    }
92
[2647]93    printf("E: %g E_fast: %g E_min: %g dx: %g dy: %g\n", e0, e1, best, fx, fy);
[2644]94
95    pipi_free(dither);
96    pipi_free(gauss);
97
98    return 0;
99}
100
Note: See TracBrowser for help on using the repository browser.