You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

633 line
26 KiB

  1. <?php header("Content-Type: text/html; charset=utf-8"); ?>
  2. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
  3. "http://www.w3.org/TR/xhtml1/DTD/xhtml11.dtd">
  4. <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
  5. <head>
  6. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  7. <meta name="GENERATOR" content="vim" />
  8. <meta name="Author" content="sam@zoy.org (Sam Hocevar)" />
  9. <meta name="Description" content="Libcaca study - 3. Error diffusion" />
  10. <meta name="Keywords" content="libcaca, ASCII, ASCII ART, console, text mode, ncurses, slang, AAlib, dithering, thresholding" />
  11. <title>Libcaca study - 3. Error diffusion</title>
  12. <link rel="icon" type="image/x-icon" href="/favicon.ico" />
  13. <link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" />
  14. <link rel="stylesheet" type="text/css" href="/main.css" />
  15. </head>
  16. <body>
  17. <?php include($_SERVER["DOCUMENT_ROOT"]."/header.inc"); ?>
  18. <p> <span style="color: #aa0000; font-weight: bold;">Warning</span>: this
  19. document is still work in progress. Feel free to send comments but do not
  20. consider it final material. </p>
  21. <div style="float: left;">
  22. <a href="part2.html">Halftoning &lt;&lt;&lt;</a>
  23. </div>
  24. <div style="float: right;">
  25. <a href="part4.html">&gt;&gt;&gt; Model-based dithering</a>
  26. </div>
  27. <div style="text-align: center;">
  28. <a href="index.html">^^^ Index</a>
  29. </div>
  30. <h2> 3. Error diffusion </h2>
  31. <p> The idea behind error diffusion is to compute the error caused by
  32. thresholding a given pixel and propagate it to neighbour pixels, in order to
  33. compensate for the average intensity loss or gain. It is based upon the
  34. assumption that a slightly out-of-place pixel causes little visual harm.
  35. </p>
  36. <p> The error is computed by simply substracting the source value and the
  37. destination value. Destination value can be chosen by many means but does
  38. not impact the image a lot with most methods in comparison to the crucial
  39. choice of error distribution coefficients. </p>
  40. <p> This is the simplest error diffusion method. It thresholds the image
  41. to 0.5 and propagates 100% of the error to the next (right) pixel. It is
  42. quite impressive given its simplicity but causes important visual artifacts:
  43. </p>
  44. <p style="text-align: center;">
  45. <img src="out/lena3-0-1.png" width="256" height="256"
  46. class="inline" alt="Simple error diffusion" />
  47. <img src="out/grad3-0-1.png" width="32" height="256"
  48. class="inline" alt="Simple error diffusion gradient" />
  49. </p>
  50. <h3> 3.1. Floyd-Steinberg and JaJuNi error diffusion </h3>
  51. <p> The most famous error diffusion method is the <b>Floyd-Steinberg</b>
  52. algorithm [5]. It propagates the error to more than one adjacent pixels using
  53. the following coefficients: </p>
  54. <p style="text-align: center;">
  55. <img src="out/fig3-1-1.png" width="121" height="81" alt="Floyd-Steinberg" />
  56. </p>
  57. <p> The result of this algorithm is rather impressive even compared to the
  58. best ordered dither results we could achieve: </p>
  59. <p style="text-align: center;">
  60. <img src="out/lena3-1-1.png" width="256" height="256"
  61. class="inline" alt="Floyd-Steinberg error diffusion" />
  62. <img src="out/grad3-1-1.png" width="32" height="256"
  63. class="inline" alt="Floyd-Steinberg error diffusion gradient" />
  64. </p>
  65. <p> <b>Jarvis, Judice and Ninke dithering</b> [7] (sometimes nicknamed
  66. <b>JaJuNi</b>) was published almost at the same time as Floyd-Steinberg. It
  67. uses a much more complex error diffusion matrix: </p>
  68. <p style="text-align: center;">
  69. <img src="out/fig3-1-3.png" width="201" height="121"
  70. class="matrix" alt="Jarvis, Judice and Ninke" />
  71. <img src="out/lena3-1-3.png" width="256" height="256"
  72. class="inline" alt="Jarvis, Judice and Ninke error diffusion" />
  73. <img src="out/grad3-1-3.png" width="32" height="256"
  74. class="inline" alt="Jarvis, Judice and Ninke error diffusion gradient" />
  75. </p>
  76. <h3> 3.2. Floyd-Steinberg derivatives </h3>
  77. <p> Zhigang Fan came up with several Floyd-Steinberg derivatives. <b>Fan
  78. dithering</b> [8] just moves one coefficient around: </p>
  79. <p style="text-align: center;">
  80. <img src="out/fig3-2-1.png" width="161" height="81"
  81. class="matrix" alt="Fan" />
  82. <img src="out/lena3-2-1.png" width="256" height="256"
  83. class="inline" alt="Fan error diffusion" />
  84. <img src="out/grad3-2-1.png" width="32" height="256"
  85. class="inline" alt="Fan error diffusion gradient" />
  86. </p>
  87. <p> <b>Shiau-Fan dithering</b> use a family of matrices supposed to reduce
  88. the apparition of artifacts usually seen with Floyd-Steinberg: </p>
  89. <p style="text-align: center;">
  90. <img src="out/fig3-2-1b.png" width="161" height="81"
  91. class="matrix" alt="Shiau-Fan" />
  92. <img src="out/lena3-2-1b.png" width="256" height="256"
  93. class="inline" alt="Shiau-Fan error diffusion" />
  94. <img src="out/grad3-2-1b.png" width="32" height="256"
  95. class="inline" alt="Shiau-Fan error diffusion gradient" />
  96. </p>
  97. <p style="text-align: center;">
  98. <img src="out/fig3-2-1c.png" width="201" height="81"
  99. class="matrix" alt="Shiau-Fan 2" />
  100. <img src="out/lena3-2-1c.png" width="256" height="256"
  101. class="inline" alt="Shiau-Fan 2 error diffusion" />
  102. <img src="out/grad3-2-1c.png" width="32" height="256"
  103. class="inline" alt="Shiau-Fan 2 error diffusion gradient" />
  104. </p>
  105. <p> By the way, these matrices are covered by Shiau’s and Fan’s
  106. <a href="http://www.freepatentsonline.com/5353127.html">U.S. patent
  107. 5353127</a>. </p>
  108. <p> <b>Stucki dithering</b> [6] is a slight variation of Jarvis-Judice-Ninke
  109. dithering: </p>
  110. <p style="text-align: center;">
  111. <img src="out/fig3-2-3.png" width="201" height="121"
  112. class="matrix" alt="Stucki" />
  113. <img src="out/lena3-2-3.png" width="256" height="256"
  114. class="inline" alt="Stucki error diffusion" />
  115. <img src="out/grad3-2-3.png" width="32" height="256"
  116. class="inline" alt="Stucki error diffusion gradient" />
  117. </p>
  118. <p> <b>Burkes dithering</b> is yet another variation [10] which improves on
  119. Stucki dithering by removing a line and making the error coefficients fractions
  120. of powers of two: </p>
  121. <p style="text-align: center;">
  122. <img src="out/fig3-2-4.png" width="201" height="81"
  123. class="matrix" alt="Burkes" />
  124. <img src="out/lena3-2-4.png" width="256" height="256"
  125. class="inline" alt="Burkes error diffusion" />
  126. <img src="out/grad3-2-4.png" width="32" height="256"
  127. class="inline" alt="Burkes error diffusion gradient" />
  128. </p>
  129. <p> Frankie Sierra [11] came up with a few error diffusion matrices: <b>Sierra
  130. dithering</b> is a variation of Jarvis that is slightly faster because it
  131. propagates to fewer pixels, <b>Two-row Sierra</b> is a simplified version
  132. thereof, and <b>Filter Lite</b> is one of the simplest Floyd-Steinberg
  133. derivatives: </p>
  134. <p style="text-align: center;">
  135. <img src="out/fig3-2-5.png" width="201" height="121"
  136. class="matrix" alt="Sierra" />
  137. <img src="out/lena3-2-5.png" width="256" height="256"
  138. class="inline" alt="Sierra error diffusion" />
  139. <img src="out/grad3-2-5.png" width="32" height="256"
  140. class="inline" alt="Sierra error diffusion gradient" />
  141. </p>
  142. <p style="text-align: center;">
  143. <img src="out/fig3-2-6.png" width="201" height="81"
  144. class="matrix" alt="Sierra" />
  145. <img src="out/lena3-2-6.png" width="256" height="256"
  146. class="inline" alt="Sierra error diffusion" />
  147. <img src="out/grad3-2-6.png" width="32" height="256"
  148. class="inline" alt="Sierra error diffusion gradient" />
  149. </p>
  150. <p style="text-align: center;">
  151. <img src="out/fig3-2-7.png" width="121" height="81"
  152. class="matrix" alt="Sierra" />
  153. <img src="out/lena3-2-7.png" width="256" height="256"
  154. class="inline" alt="Sierra error diffusion" />
  155. <img src="out/grad3-2-7.png" width="32" height="256"
  156. class="inline" alt="Sierra error diffusion gradient" />
  157. </p>
  158. <p> <b>Atkinson dithering</b> [12] only propagates 75% of the error, leading
  159. to a loss of contrast around very dark and very light areas (also called
  160. <b>highlights and shadows</b>), but better contrast in the midtones. The
  161. original Macintosh software <i>HyperScan</i> used this dithering algorithm,
  162. still considered superior to other Floyd-Steinberg derivatives by many Mac
  163. zealots: </p>
  164. <p style="text-align: center;">
  165. <img src="out/fig3-2-8.png" width="161" height="121"
  166. class="matrix" alt="Atkinson" />
  167. <img src="out/lena3-2-8.png" width="256" height="256"
  168. class="inline" alt="Atkinson error diffusion" />
  169. <img src="out/grad3-2-8.png" width="32" height="256"
  170. class="inline" alt="Atkinson error diffusion gradient" />
  171. </p>
  172. <!-- XXX: Stevenson-Arce is for hexagonal cells!
  173. <p> <b>Stevenson-Arce dithering</b>: </p>
  174. <p style="text-align: center;">
  175. <img src="fig3-2-9.png" width="280" height="160"
  176. class="matrix" alt="Stevenson-Arce" />
  177. <img src="out/lena3-2-9.png" width="256" height="256"
  178. class="inline" alt="Stevenson-Arce error diffusion" />
  179. <img src="out/grad3-2-9.png" width="32" height="256"
  180. class="inline" alt="Stevenson-Arce error diffusion gradient" />
  181. </p>
  182. -->
  183. <h3> 3.3. Changing image parsing direction </h3>
  184. <p> While image parsing order does not matter with ordered dithering, it can
  185. actually be crucial with error diffusion. The reason is that once a pixel has
  186. been processed, standard error diffusion methods do not go back. </p>
  187. <p> The usual way to parse an image is one pixel after the other, following
  188. their order in memory. When reaching the end of a line, we automatically jump
  189. to the beginning of the next line. Error diffusion methods using this
  190. parsing order are called <b>raster error diffusion</b>: </p>
  191. <p style="text-align: center;">
  192. <img src="fig3-3-1.png" width="260" height="110"
  193. class="matrix" alt="Regular parsing" />
  194. </p>
  195. <p> Changing the parsing order can help prevent the apparition of artifacts in
  196. error diffusion algorithms. This is <b>serpentine parsing</b>, where every odd
  197. line is parsed in reverse order (right to left): </p>
  198. <p style="text-align: center;">
  199. <img src="fig3-3-2.png" width="260" height="110"
  200. class="matrix" alt="Serpentine parsing" />
  201. </p>
  202. <p> The major problem with Floyd-Steinberg is the <b>worm artifacts</b> it
  203. creates. Here is an example of an image made of grey 0.9 dithered with standard
  204. Floyd-Steinberg and with <b>serpentine Floyd-Steinberg</b> [13 pp.266—267].
  205. Most of the worm artifacts have disappeared or were highly reduced: </p>
  206. <p style="text-align: center;">
  207. <img src="out/lena3-3-1.png" width="256" height="256"
  208. class="inline" alt="Floyd-Steinberg on grey 90%" />
  209. <img src="out/lena3-3-2.png" width="256" height="256"
  210. class="inline" alt="serpentine Floyd-Steinberg on grey 90%" />
  211. </p>
  212. <p> And here are the results of serpentine Floyd-Steinberg on Lena. Only a
  213. very close look will show the differences with standard Floyd-Steinberg, but
  214. a few of the artifacts did disappear: </p>
  215. <p style="text-align: center;">
  216. <img src="out/lena3-1-2.png" width="256" height="256"
  217. class="inline" alt="serpentine Floyd-Steinberg" />
  218. <img src="out/grad3-1-2.png" width="32" height="256"
  219. class="inline" alt="serpentine Floyd-Steinberg gradient" />
  220. </p>
  221. <p> <b>Riemersma dithering</b> [26] parses the image following a plane-filling
  222. <b>Hilbert curve</b> and only propagates the error of the last <i>q</i> pixels,
  223. weighting it with an exponential rule. The method is interesting and inventive,
  224. unfortunately the results are disappointing: structural artifacts are worse
  225. than with other error diffusion methods (shown here with <i>q = 16</i> and <i>r
  226. = 16</i>): </p>
  227. <p style="text-align: center;">
  228. <img src="fig3-3-3.png" width="250" height="250"
  229. class="matrix" alt="Hilbert curve parsing" />
  230. <img src="out/lena3-3-3.png" width="256" height="256"
  231. class="inline" alt="Riemersma dither on Hilbert curve" />
  232. <img src="out/grad3-3-3.png" width="32" height="256"
  233. class="inline" alt="Riemersma dither on Hilbert curve gradient" />
  234. </p>
  235. <p> A variation of Riemersma dithering uses a <b>Hilbert 2 curve</b>, giving
  236. slightly better results but still causing random artifacts here and there:
  237. </p>
  238. <p style="text-align: center;">
  239. <img src="fig3-3-4.png" width="233" height="233"
  240. class="matrix" alt="Hilbert 2 curve parsing" />
  241. <img src="out/lena3-3-4.png" width="256" height="256"
  242. class="inline" alt="Riemersma dither on Hilbert 2 curve" />
  243. <img src="out/grad3-3-4.png" width="32" height="256"
  244. class="inline" alt="Riemersma dither on Hilbert 2 curve gradient" />
  245. </p>
  246. <p> An inherent problem with plane-filling curves is that distances on the
  247. curve do not mean anything in image space. Riemersma dithering distributes
  248. error to pixels according to their distance on the curve rather than their
  249. distance in the image. </p>
  250. <p> We introduce <b>spatial Hilbert dithering</b> that addresses this issue
  251. by distributing the error according to spatial coordinates. We also get rid
  252. of the <i>r</i> parameter, choosing to distribute 100% of the error. </p>
  253. <p> This is spatial Hilbert dithering on a Hilbert curve and on a Hilbert 2
  254. curve. The results show a clear improvement over the original Riemersma
  255. algorithm, with far less noise and smoother low-gradient areas: </p>
  256. <p style="text-align: center;">
  257. <img src="out/lena3-3-5.png" width="256" height="256"
  258. class="inline" alt="spatial Hilbert dither on Hilbert curve" />
  259. <img src="out/grad3-3-5.png" width="32" height="256"
  260. class="inline" alt="spatial Hilbert dither on Hilbert curve gradient" />
  261. <img src="out/lena3-3-6.png" width="256" height="256"
  262. class="inline" alt="spatial Hilbert dither on Hilbert 2 curve" />
  263. <img src="out/grad3-3-6.png" width="32" height="256"
  264. class="inline" alt="spatial Hilbert dither on Hilbert 2 curve gradient" />
  265. </p>
  266. <p> <b>Dot diffusion</b> [14] is an error diffusion method by Donald E. Knuth
  267. that uses tileable matrices just like ordered dithering, except that the cell
  268. value order is taken into account for error propagation. Diagonal cells get
  269. half as much error as directly adjacent cells: </p>
  270. <p style="text-align: center;">
  271. <img src="out/fig3-3-7b.png" width="121" height="121"
  272. class="matrix" alt="Dot diffusion" />
  273. </p>
  274. <p> For instance, in the following example, cell 25’s error is propagated to
  275. cells 44, 36, 30, 34 and 49. Given the diagonal cells rule, cells 44, 30 and
  276. 49 each get 1/7 of the error and cells 36 and 34 each get 2/7 of the error.
  277. Similarly, cell 63 gets 100% of cell 61’s error. </p>
  278. <p style="text-align: center;">
  279. <img src="fig3-3-7.png" width="240" height="240"
  280. class="matrix" alt="Dot diffusion matrix sample" />
  281. <img src="out/lena3-3-7.png" width="256" height="256"
  282. class="inline" alt="Dot diffusion" />
  283. <img src="out/grad3-3-7.png" width="32" height="256"
  284. class="inline" alt="Dot diffusion gradient" />
  285. </p>
  286. <p> The initial result is not extraordinary. But Knuth suggests applying a
  287. sharpen filter to the original image before applying dot diffusion. He also
  288. introduces a <i>zeta</i> value to deal with the size of laser printer dots,
  289. pretty similar to what we’ll see later as <b>gamma correction</b>. The
  290. following two images had a sharpening value of 0.9 applied to them. The image
  291. on the right shows <i>zeta = 0.2</i>: </p>
  292. <p style="text-align: center;">
  293. <img src="out/lena3-3-8.png" width="256" height="256"
  294. class="inline" alt="Dot diffusion sharpen 0.9" />
  295. <img src="out/grad3-3-8.png" width="32" height="256"
  296. class="inline" alt="Dot diffusion sharpen 0.9 gradient" />
  297. <img src="out/lena3-3-9.png" width="256" height="256"
  298. class="inline" alt="Dot diffusion sharpen 0.9 zeta 0.2" />
  299. <img src="out/grad3-3-9.png" width="32" height="256"
  300. class="inline" alt="Dot diffusion sharpen 0.9 zeta 0.2 gradient" />
  301. </p>
  302. <p> Do not get fooled by Knuth’s apparent good results. They specifically
  303. target dot printers and do not give terribly good results on a computer
  304. screen. Actually, a sharpening filter makes just any dithering method look
  305. better, even basic Floyd-Steinberg dithering (shown here with a sharpening
  306. value of 0.9, too): </p>
  307. <p style="text-align: center;">
  308. <img src="out/lena3-3-10.png" width="256" height="256"
  309. class="inline" alt="FS with sharpening" />
  310. <img src="out/grad3-3-10.png" width="32" height="256"
  311. class="inline" alt="FS with sharpening gradient" />
  312. </p>
  313. <p> Dot diffusion was reinvented 14 years later by Arney, Anderson and Ganawan
  314. without even citing Knuth. They call their method <b>omni-directional error
  315. diffusion</b>. Instead of using a clustered dot matrix like Knuth recommends
  316. for dot diffusion, they use a dispersed dot matrix, which gives far better
  317. results on a computer display. This is a 16×12 portion of that matrix: </p>
  318. <p style="text-align: center;">
  319. <img src="out/fig3-3-11b.png" width="320" height="240"
  320. class="matrix" alt="omni-directional ED matrix sample" />
  321. </p>
  322. <p> The preferred implementation of omni-directional error diffusion uses
  323. a slightly different propagation matrix, where top and bottom neighbours get
  324. more error than the others: </p>
  325. <p style="text-align: center;">
  326. <img src="out/fig3-3-11.png" width="121" height="121"
  327. class="matrix" alt="omni-directional ED" />
  328. <img src="out/lena3-3-11.png" width="256" height="256"
  329. class="inline" alt="omni-directional ED" />
  330. <img src="out/grad3-3-11.png" width="32" height="256"
  331. class="inline" alt="omni-directional ED gradient" />
  332. </p>
  333. <h3> 3.4. Variable coefficients error diffusion </h3>
  334. <p> Small error diffusion matrices usually cause artifacts to appear because
  335. the error is not propagated in enough directions. At the same time, such
  336. matrices also reduce the sharpened aspect common in error diffusion
  337. techniques. </p>
  338. <p> Ostromoukhov suggests error diffusion values that vary according to the
  339. input value. The list of 256 discrete value triplets for <i>d1</i>, <i>d2</i>
  340. and <i>d3</i> he provides [1] give pretty good results with serpentine parsing:
  341. </p>
  342. <p style="text-align: center;">
  343. <img src="out/fig3-4-1.png" width="121" height="81"
  344. class="matrix" alt="Ostromoukhov ED matrix" />
  345. <img src="out/lena3-4-1.png" width="256" height="256"
  346. class="inline" alt="Ostromoukhov ED" />
  347. <img src="out/grad3-4-1.png" width="32" height="256"
  348. class="inline" alt="Ostromoukhov ED gradient" />
  349. </p>
  350. <h3> 3.5. Block error diffusion </h3>
  351. <p> Sometimes, due to physical restrictions of the target media, output
  352. is limited to some combinations of pixel blocks, such as the ones shown
  353. below: </p>
  354. <p style="text-align: center;">
  355. <img src="fig3-5-1.png" width="613" height="80"
  356. class="matrix" alt="list of 2×2 pixel blocks" />
  357. </p>
  358. <p> It is still possible to dither the image, by doing it 4 pixels at a
  359. time and simply choosing the block from the list that minimises the global
  360. error within the 2×2 block: </p>
  361. <p style="text-align: center;">
  362. <img src="out/lena3-5-1.png" width="256" height="256"
  363. class="inline" alt="2×2 pixel block quantisation" />
  364. <img src="out/grad3-5-1.png" width="32" height="256"
  365. class="inline" alt="2×2 pixel block quantisation gradient" />
  366. </p>
  367. <p> Damera-Venkata and Evans introduce <b>block error diffusion</b> [23], which
  368. reuses traditional error diffusion methods such as Floyd-Steinberg but applies
  369. the same error value to all pixels of a given block. Only one error value is
  370. propagated, <i>a+b+c+d</i>, which is the global error within the block: </p>
  371. <p style="text-align: center; font-size: 2em;">
  372. <img src="out/fig3-1-1.png" width="121" height="81"
  373. class="math" alt="Floyd-Steinberg" />
  374. <img src="out/fig3-5-2b.png" width="81" height="81"
  375. class="math" alt="2×2 balanced matrix" />
  376. =
  377. <img src="out/fig3-5-2.png" width="241" height="161"
  378. class="math" alt="2×2-expanded Floyd-Steinberg" />
  379. </p>
  380. <p> Here are the results using the previous pixel blocks: </p>
  381. <p style="text-align: center;">
  382. <img src="out/lena3-5-2.png" width="256" height="256"
  383. class="inline" alt="2×2 block Floyd-Steinberg" />
  384. <img src="out/grad3-5-2.png" width="32" height="256"
  385. class="inline" alt="2×2 block Floyd-Steinberg gradient" />
  386. </p>
  387. <p> Carefully chosen blocks create constraints on the final picture that may
  388. be of artistic interest: </p>
  389. <p style="text-align: center;">
  390. <img src="fig3-5-3.png" width="354" height="207"
  391. class="matrix" alt="artistic 3×3 blocks" />
  392. <img src="out/lena3-5-3.png" width="256" height="256"
  393. class="inline" alt="3×3 block Floyd-Steinberg" />
  394. <img src="out/grad3-5-3.png" width="32" height="256"
  395. class="inline" alt="3×3 block Floyd-Steinberg gradient" />
  396. </p>
  397. <p> Using all possible pixel blocks is not equivalent to dithering the image
  398. pixel by pixel. This is due to both the block-choosing method, which only
  399. minimises the difference of mean values within blocks intead of the sum of
  400. local distances, and to the inefficient matrix coefficients, which propagate
  401. the error beyond immediate neighbours, causing the image to look sharpened.
  402. </p>
  403. <p> This example shows standard block Floyd-Steinberg using all possible 2×2
  404. blocks: </p>
  405. <p style="text-align: center;">
  406. <img src="fig3-5-4.png" width="200" height="200"
  407. class="matrix" alt="all possible 2×2 blocks" />
  408. <img src="out/lena3-5-4.png" width="256" height="256"
  409. class="inline" alt="full 2×2 block Floyd-Steinberg" />
  410. <img src="out/grad3-5-4.png" width="32" height="256"
  411. class="inline" alt="full 2×2 block Floyd-Steinberg gradient" />
  412. </p>
  413. <p> The results on the vertical gradient indicate poor block-choosing. In
  414. order to improve it, we introduce a modified, weighted intra-block error
  415. distribution matrix, still based on the original Floyd-Steinberg matrix: </p>
  416. <p style="text-align: center; font-size: 2em;">
  417. <img src="out/fig3-1-1.png" width="121" height="81"
  418. class="math" alt="Floyd-Steinberg" />
  419. <img src="out/fig3-5-5b.png" width="81" height="81"
  420. class="math" alt="weighted 2×2 matrix" />
  421. =
  422. <img src="out/fig3-5-5.png" width="241" height="161"
  423. class="math" alt="weighted 2×2 propagation matrix" />
  424. </p>
  425. <p> The result still looks sharpened, but shows considerably less noise: </p>
  426. <p style="text-align: center;">
  427. <img src="out/lena3-5-5.png" width="256" height="256"
  428. class="inline" alt="weighted full 2×2 block Floyd-Steinberg" />
  429. <img src="out/grad3-5-5.png" width="32" height="256"
  430. class="inline" alt="weighted full 2×2 block Floyd-Steinberg gradient" />
  431. </p>
  432. <h3> 3.6. Sub-block error diffusion </h3>
  433. <p> We introduce <b>sub-block error diffusion</b>, a novel technique improving
  434. on block error diffusion. It addresses the following observations: </p>
  435. <ul>
  436. <li> it is not a requirement to propagate the error beyond the immediate
  437. neighbours; since it causes a sharpen effect, we decide not to do it.
  438. </li>
  439. <li> the individual subpixels’ error should be propagated, not the
  440. global block error. </li>
  441. <li> subpixel <b>a</b>’s error is harder to compensate than subpixel
  442. <b>d</b>’s because its immediate neighbours are already in the block
  443. being processed, so we weight the sub-block matching in order to
  444. prioritise pixel <b>a</b>’s matching. </li>
  445. </ul>
  446. <p> We use <i>m⋅n</i> error diffusion matrices, one for each of the current
  447. block’s pixels. Here are four error diffusion matrices for 2×2 blocks,
  448. generated from the standard Floyd-Steinberg matrix: </p>
  449. <p style="text-align: center;">
  450. <img src="out/fig3-6-1a.png" width="161" height="121"
  451. class="math" alt="sub-block 0,0 Floyd-Steinberg" />
  452. <img src="out/fig3-6-1b.png" width="161" height="121"
  453. class="math" alt="sub-block 1,0 Floyd-Steinberg" />
  454. </p>
  455. <p style="text-align: center;">
  456. <img src="out/fig3-6-1c.png" width="161" height="121"
  457. class="math" alt="sub-block 0,1 Floyd-Steinberg" />
  458. <img src="out/fig3-6-1d.png" width="161" height="121"
  459. class="math" alt="sub-block 1,1 Floyd-Steinberg" />
  460. </p>
  461. <p> The results are far better than with the original block error diffusion
  462. method. On the left, sub-block error diffusion with all possible 2×2 blocks.
  463. On the right, sub-block error diffusion restricted to the tiles seen in
  464. 3.5: </p>
  465. <p style="text-align: center;">
  466. <img src="out/lena3-6-1.png" width="256" height="256"
  467. class="inline" alt="full 2×2 sub-block Floyd-Steinberg" />
  468. <img src="out/grad3-6-1.png" width="32" height="256"
  469. class="inline" alt="full 2×2 sub-block Floyd-Steinberg gradient" />
  470. <img src="out/lena3-6-2.png" width="256" height="256"
  471. class="inline" alt="2×2 lines sub-block Floyd-Steinberg" />
  472. <img src="out/grad3-6-2.png" width="32" height="256"
  473. class="inline" alt="2×2 lines sub-block Floyd-Steinberg gradient" />
  474. </p>
  475. <p> Similar error diffusion matrices can be generated for 3×3 blocks: </p>
  476. <p style="text-align: center;">
  477. <img src="out/fig3-6-3a.png" width="150" height="120"
  478. class="math" alt="sub-block 0,0/3×3 Floyd-Steinberg" />
  479. <img src="out/fig3-6-3b.png" width="150" height="120"
  480. class="math" alt="sub-block 1,0/3×3 Floyd-Steinberg" />
  481. <img src="out/fig3-6-3c.png" width="150" height="120"
  482. class="math" alt="sub-block 2,0/3×3 Floyd-Steinberg" />
  483. </p>
  484. <p style="text-align: center;">
  485. <img src="out/fig3-6-3d.png" width="150" height="120"
  486. class="math" alt="sub-block 0,1/3×3 Floyd-Steinberg" />
  487. <img src="out/fig3-6-3e.png" width="150" height="120"
  488. class="math" alt="sub-block 1,1/3×3 Floyd-Steinberg" />
  489. <img src="out/fig3-6-3f.png" width="150" height="120"
  490. class="math" alt="sub-block 2,1/3×3 Floyd-Steinberg" />
  491. </p>
  492. <p style="text-align: center;">
  493. <img src="out/fig3-6-3g.png" width="150" height="120"
  494. class="math" alt="sub-block 0,2/3×3 Floyd-Steinberg" />
  495. <img src="out/fig3-6-3h.png" width="150" height="120"
  496. class="math" alt="sub-block 1,2/3×3 Floyd-Steinberg" />
  497. <img src="out/fig3-6-3i.png" width="150" height="120"
  498. class="math" alt="sub-block 2,2/3×3 Floyd-Steinberg" />
  499. </p>
  500. <p> Here are the results with all the possible 3×3 blocks, and with the
  501. artistic 3×3 blocks seen in 3.5: </p>
  502. <p style="text-align: center;">
  503. <img src="out/lena3-6-3.png" width="256" height="256"
  504. class="inline" alt="3×3 sub-block Floyd-Steinberg" />
  505. <img src="out/grad3-6-3.png" width="32" height="256"
  506. class="inline" alt="3×3 sub-block Floyd-Steinberg gradient" />
  507. <img src="out/lena3-6-4.png" width="256" height="256"
  508. class="inline" alt="3×3 artistic sub-block Floyd-Steinberg" />
  509. <img src="out/grad3-6-4.png" width="32" height="256"
  510. class="inline" alt="3×3 artistic sub-block Floyd-Steinberg gradient" />
  511. </p>
  512. <div style="float: left;">
  513. <a href="part2.html">Halftoning &lt;&lt;&lt;</a>
  514. </div>
  515. <div style="float: right;">
  516. <a href="part4.html">&gt;&gt;&gt; Model-based dithering</a>
  517. </div>
  518. <div style="text-align: center;">
  519. <a href="index.html">^^^ Index</a>
  520. </div>
  521. <?php $rev = '$Id$';
  522. include($_SERVER['DOCUMENT_ROOT'].'/footer.inc'); ?>
  523. </body>
  524. </html>