選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

edd.c 3.0 KiB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  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. /* This program computes the Floyd-Steinberg error diffusion algorithm's
  15. * displacement on the given input image. Error diffusion displacement is
  16. * introduced in the paper "Reinstating Floyd-Steinberg: Improved Metrics
  17. * for Quality Assessment of Error Diffusion Algorithms.", ICISP 2008
  18. * Proceedings. Lecture Notes in Computer Science 5099 Springer 2008, ISBN
  19. * 978-3-540-69904-0.
  20. *
  21. * The resulting dx/dy values are usually around 0.16/0.26 for images that
  22. * are not entirely black and white. */
  23. #include "config.h"
  24. #include <stdio.h>
  25. #include <stdlib.h>
  26. #include <string.h>
  27. #include <pipi.h>
  28. #define Z 3
  29. int main(int argc, char *argv[])
  30. {
  31. double sigma = 1.2, precision = 0.001, step = 2.;
  32. double best = 1., fx = -1., fy = -1., bfx = 0., bfy = 0.;
  33. double e, e0, e1;
  34. pipi_image_t *img, *kernel, *gauss, *dither, *tmp;
  35. int dx, dy;
  36. if(argc < 2)
  37. {
  38. fprintf(stderr, "%s: too few arguments\n", argv[0]);
  39. fprintf(stderr, "Usage: %s <image>\n", argv[0]);
  40. return EXIT_FAILURE;
  41. }
  42. /* Load image, convert it to grayscale, dither it with Floyd-Steinberg */
  43. img = pipi_load(argv[1]);
  44. pipi_set_colorspace(img, PIPI_PIXELS_Y_F32);
  45. gauss = pipi_gaussian_blur(img, sigma);
  46. kernel = pipi_load("ediff:fs");
  47. dither = pipi_dither_ediff(img, kernel, PIPI_SCAN_RASTER);
  48. pipi_free(kernel);
  49. pipi_free(img);
  50. /* Compute the standard error */
  51. tmp = pipi_gaussian_blur(dither, sigma);
  52. e0 = pipi_measure_msd(gauss, tmp);
  53. pipi_free(tmp);
  54. /* Compute the fast error */
  55. tmp = pipi_gaussian_blur_ext(dither, sigma, sigma, 0.0, 0.16, 0.26);
  56. e1 = pipi_measure_msd(gauss, tmp);
  57. pipi_free(tmp);
  58. /* Compute displacement */
  59. while(step > precision)
  60. {
  61. for(dy = 0; dy <= Z; dy++)
  62. for(dx = 0; dx <= Z; dx++)
  63. {
  64. tmp = pipi_gaussian_blur_ext(dither, sigma, sigma, 0.0,
  65. fx + step * dx / Z,
  66. fy + step * dy / Z);
  67. e = pipi_measure_msd(gauss, tmp);
  68. pipi_free(tmp);
  69. if(e < best)
  70. {
  71. best = e;
  72. bfx = fx + step * dx / Z;
  73. bfy = fy + step * dy / Z;
  74. }
  75. }
  76. fx = bfx - step / Z;
  77. fy = bfy - step / Z;
  78. step = step * 2 / Z;
  79. }
  80. printf("E: %g E_fast: %g E_min: %g dx: %g dy: %g\n", e0, e1, best, fx, fy);
  81. pipi_free(dither);
  82. pipi_free(gauss);
  83. return 0;
  84. }