source: libpipi/trunk/examples/edd.c

Last change on this file was 3342, checked in by Sam Hocevar, 12 years ago

Change _C pixel format suffixes into _U8 for more clarity.

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]);
[3342]52    pipi_set_colorspace(img, PIPI_PIXELS_Y_F32);
[2644]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.