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.
 
 
 
 
 
 

382 rivejä
18 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 - 4. Model-based dithering" />
  10. <meta name="Keywords" content="libcaca, ASCII, ASCII ART, console, text mode, ncurses, slang, AAlib, dithering, thresholding" />
  11. <title>Libcaca study - 4. Model-based dithering</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. <style type="text/css">
  16. .score td, .score th { padding: 2px 8px; }
  17. .score th { background-color: #ddf; text-align: center; }
  18. .score tr { background-color: white; padding: 10px; }
  19. td.hi { background-color: #dfd; }
  20. table.score { padding: 0px; border: 0px; background-color: black;
  21. margin-left: auto; margin-right: auto; }
  22. </style>
  23. </head>
  24. <body>
  25. <?php include($_SERVER["DOCUMENT_ROOT"]."/header.inc"); ?>
  26. <p> <span style="color: #aa0000; font-weight: bold;">Warning</span>: this
  27. document is still work in progress. Feel free to send comments but do not
  28. consider it final material. </p>
  29. <div style="float: left;">
  30. <a href="part3.html">Error diffusion &lt;&lt;&lt;</a>
  31. </div>
  32. <div style="float: right;">
  33. <a href="part5.html">&gt;&gt;&gt; Greyscale dithering</a>
  34. </div>
  35. <div style="text-align: center;">
  36. <a href="index.html">^^^ Index</a>
  37. </div>
  38. <h2> 4. Model-based dithering </h2>
  39. <p> So far all dithering methods have relied on the assumption that carefully
  40. positioned black and white pixels gave the illusion of greyscales, but we
  41. have not stated exactly how the human eye reacted. Also, we do not have an
  42. automated way to compare the results of two different algorithms: judging that
  43. an algorithm is “better” has mostly been a subjective process so far. </p>
  44. <p> In order to figure out what the human eye really sees, we need a <b>human
  45. visual system</b> (HVS) model. Countless models exist, and we are only going to
  46. focus on simple ones for now. </p>
  47. <h3> 4.1. Gaussian human visual system model </h3>
  48. <p> One of the simplest models is the <b>gaussian HVS model</b>. It states
  49. that the human eye acts like a gaussian convolution filter, slightly blurring
  50. pixel neighbourhoods and therefore simulating what the eye sees as distance
  51. from the image increases. This model, a simplified <b>luminance spatial
  52. frequency response formula</b>, can be expressed using the two-dimensional
  53. <i>e<small><sup> -(x²+y²)/2σ²</sup></small></i> function. The <i>σ</i>
  54. parameter sort of introduces the viewing distance into the model. </p>
  55. <p> Here are the results of applying a gaussian HVS to an 8×8 Bayer dithered
  56. image, simply by convoluting the image with a gaussian blur filter. This
  57. process is also known as <b>inverse halftoning</b>. Different values of
  58. <i>σ</i> simulate what the eye sees from different distances. On the left
  59. <i>σ = 1</i>, on the right <i>σ = 2</i>: </p>
  60. <p style="text-align: center;">
  61. <img src="out/lena4-1-1.png" width="256" height="256"
  62. class="inline" alt="8×8 Bayer dither, gaussian HVS, σ = 1" />
  63. <img src="out/grad4-1-1.png" width="32" height="256"
  64. class="inline" alt="8×8 Bayer dither, gaussian HVS, σ = 1 gradient" />
  65. <img src="out/lena4-1-2.png" width="256" height="256"
  66. class="inline" alt="8×8 Bayer dither, gaussian HVS, σ = 2" />
  67. <img src="out/grad4-1-2.png" width="32" height="256"
  68. class="inline" alt="8×8 Bayer dither, gaussian HVS, σ = 2 gradient" />
  69. </p>
  70. <h3> 4.2. Direct binary search </h3>
  71. <p> We have already seen that standard error diffusion methods do not go back
  72. to pixels that have been set. <b>Direct binary search</b> [4] (DBS) is an
  73. iterative method that processes the image a fixed number of times, or until the
  74. error can no longer be minimised: </p>
  75. <ul>
  76. <li> Generate an initial dithered image </li>
  77. <li> Repeat until no changes can be applied:
  78. <ul>
  79. <li> Compute the global error between the original and the dithered
  80. images </li>
  81. <li> For each pixel in the dithered image:
  82. <ul>
  83. <li> Compute the effect on the error of toggling the value of the
  84. current pixel </li>
  85. <li> Compute the effect on the error of swapping the current pixel
  86. with one of its immediate neighbours </li>
  87. <li> If the error can be reduced, perform the corresponding
  88. action </li>
  89. </ul>
  90. </li>
  91. </ul>
  92. </li>
  93. </ul>
  94. <p> The efficiency and quality of DBS depend on many implementation details,
  95. starting with the HVS model it uses to compute the error. Also, the initial
  96. image used as iteration zero will give poor results if pattern artifacts are
  97. already present. The order in which pixels are processed is important, too.
  98. Unfortunately, despite its very high-quality results, DBS is usually a very
  99. slow algorithm. </p>
  100. <p> Below is an example of the algorithm results. The HVS uses a 11×11
  101. convolution kernel of the <i>e<small><sup> -sqrt(x²+y²)</sup></small></i>
  102. function. The initial image is randomly thresholded, and pixels are processed
  103. in raster order. Iterations 1, 2 and 5 are shown: </p>
  104. <p style="text-align: center;">
  105. <img src="out/lena4-2-1.png" width="256" height="256"
  106. class="inline" alt="direct binary search, iteration 0" />
  107. <img src="out/grad4-2-1.png" width="32" height="256"
  108. class="inline" alt="direct binary search, iteration 0 gradient" />
  109. <img src="out/lena4-2-2.png" width="256" height="256"
  110. class="inline" alt="direct binary search, iteration 1" />
  111. <img src="out/grad4-2-2.png" width="32" height="256"
  112. class="inline" alt="direct binary search, iteration 1 gradient" />
  113. </p>
  114. <p style="text-align: center;">
  115. <img src="out/lena4-2-3.png" width="256" height="256"
  116. class="inline" alt="direct binary search, iteration 2" />
  117. <img src="out/grad4-2-3.png" width="32" height="256"
  118. class="inline" alt="direct binary search, iteration 2 gradient" />
  119. <img src="out/lena4-2-4.png" width="256" height="256"
  120. class="inline" alt="direct binary search, iteration 5" />
  121. <img src="out/grad4-2-4.png" width="32" height="256"
  122. class="inline" alt="direct binary search, iteration 5 gradient" />
  123. </p>
  124. <p> Other HVS models can be used, giving very high quality results. Below are
  125. the results of DBS with the following HVS functions: </p>
  126. <ul>
  127. <li> <i>e<small><sup> -(x²+y²)/2</sup></small></i> </li>
  128. <li> <i>e<small><sup> -(x²+y²)/4.5</sup></small></i> </li>
  129. <li> <i>e<small><sup> -(x²+y²)/8</sup></small></i> </li>
  130. <li> <i>2e<small><sup> -(x²+y²)/1.5</sup></small> + e<small><sup>
  131. -(x²+y²)/8</sup></small></i> </li>
  132. </ul>
  133. <p> The iteration shown is number 5. More iterations would have improved
  134. the results even slightly more, but that would have been at the expense of
  135. performance: </p>
  136. <p style="text-align: center;">
  137. <img src="out/lena4-2-5.png" width="256" height="256"
  138. class="inline" alt="direct binary search, sigma = 1, iteration 5" />
  139. <img src="out/grad4-2-5.png" width="32" height="256"
  140. class="inline" alt="direct binary search, sigma = 1, iteration 5 gradient" />
  141. <img src="out/lena4-2-6.png" width="256" height="256"
  142. class="inline" alt="direct binary search, sigma = 1.5, iteration 5" />
  143. <img src="out/grad4-2-6.png" width="32" height="256"
  144. class="inline" alt="direct binary search, sigma = 1.5, iteration 5 gradient" />
  145. </p>
  146. <p style="text-align: center;">
  147. <img src="out/lena4-2-7.png" width="256" height="256"
  148. class="inline" alt="direct binary search, sigma = 2, iteration 5" />
  149. <img src="out/grad4-2-7.png" width="32" height="256"
  150. class="inline" alt="direct binary search, sigma = 2, iteration 5 gradient" />
  151. <img src="out/lena4-2-8.png" width="256" height="256"
  152. class="inline" alt="direct binary search, best HVS, iteration 5" />
  153. <img src="out/grad4-2-8.png" width="32" height="256"
  154. class="inline" alt="direct binary search, best HVS, iteration 5 gradient" />
  155. </p>
  156. <h3> 4.3 Comparing dithering algorithms </h3>
  157. <p> Using an HVS model, it is possible to classify previously seen algorithms
  158. simply by applying the model to both the source and the destination images,
  159. and computing their per-pixel <b>mean squared error</b>. This gives a better
  160. estimation of the dithering algorithm’s quality than simply computing a
  161. local, pixel-bound error. </p>
  162. <p> The following table shows that different HVS models give very different
  163. error values depending on the value of <i>σ</i>. Also, in the case of
  164. the DBS algorithm, a carefully crafted HVS function such as the last one,
  165. which combines two different HVS models, gives low error values at every
  166. <i>σ</i>, which means the dithered image is close to the original image at all
  167. corresponding viewing distances: </p>
  168. <table class="score" cellspacing="1">
  169. <tr><th>Chapter 1: Thresholding</th>
  170. <th>Error %<br />σ = 1</th><th>Error %<br />σ = 1.5</th><th>Error %<br />σ = 2</th></tr>
  171. <tr><td>0.5 thresholding</td>
  172. <td>8.60303</td><td>7.93554</td><td>7.42669</td></tr>
  173. <tr><td>0.4 thresholding</td>
  174. <td>9.78990</td><td>9.10994</td><td>8.61878</td></tr>
  175. <tr><td>0.6 thresholding</td>
  176. <td>10.77689</td><td>10.33373</td><td>10.00462</td></tr>
  177. <tr><td>dynamic thresholding</td>
  178. <td>10.31568</td><td>9.60749</td><td>9.09760</td></tr>
  179. <tr><td>uniform random dithering</td>
  180. <td class="hi">1.57895</td><td class="hi">0.69762</td><td class="hi">0.39713</td></tr>
  181. <tr><td>gaussian random dithering</td>
  182. <td>2.95590</td><td>2.34461</td><td>2.08792</td></tr>
  183. <tr><th>Chapter 2: Halftoning</th>
  184. <th>Error %<br />σ = 1</th><th>Error %<br />σ = 1.5</th><th>Error %<br />σ = 2</th></tr>
  185. <tr><td>25/50/75% patterns dithering</td>
  186. <td>0.56642</td><td>0.46490</td><td>0.41816</td></tr>
  187. <tr><td>2×2 Bayer dithering</td>
  188. <td>0.56694</td><td>0.46622</td><td>0.41956</td></tr>
  189. <tr><td>4×4 Bayer dithering</td>
  190. <td class="hi">0.20538</td><td>0.08060</td><td>0.05457</td></tr>
  191. <tr><td>8×8 Bayer dithering</td>
  192. <td class="hi">0.19691</td><td class="hi">0.06352</td><td class="hi">0.03354</td></tr>
  193. <tr><td>4×4 cluster dot dithering</td>
  194. <td>1.20026</td><td>0.14863</td><td>0.07100</td></tr>
  195. <tr><td>8×8 cluster dot dithering</td>
  196. <td>3.86236</td><td>0.85236</td><td>0.14443</td></tr>
  197. <tr><td>5×3 artistic line dithering</td>
  198. <td>2.75590</td><td>0.49420</td><td>0.11578</td></tr>
  199. <tr><td>perturbated 8×8 Bayer dithering</td>
  200. <td>0.40550</td><td>0.16971</td><td>0.09804</td></tr>
  201. <tr><td>random 3×3 dithering matrix selection</td>
  202. <td>0.60329</td><td>0.25055</td><td>0.16521</td></tr>
  203. <tr><td>“plus” pattern dithering</td>
  204. <td>0.43061</td><td>0.33540</td><td>0.29851</td></tr>
  205. <tr><td>“hex” pattern dithering</td>
  206. <td>0.26747</td><td>0.16119</td><td>0.13068</td></tr>
  207. <tr><td>“doubleplus” pattern dithering</td>
  208. <td>0.42852</td><td>0.12232</td><td>0.08904</td></tr>
  209. <tr><td>“hex2” pattern dithering</td>
  210. <td>0.35057</td><td>0.13046</td><td>0.09533</td></tr>
  211. <tr><td>4-wise supercell “plus” pattern dithering</td>
  212. <td class="hi">0.21903</td><td>0.07494</td><td>0.04423</td></tr>
  213. <tr><td>3-wise supercell “hex” pattern dithering</td>
  214. <td class="hi">0.21621</td><td>0.07356</td><td>0.04193</td></tr>
  215. <tr><td>4-wise supercell “doubleplus” pattern dithering</td>
  216. <td>0.40883</td><td>0.07051</td><td class="hi">0.03609</td></tr>
  217. <tr><td>6th order dragon curve dithering</td>
  218. <td class="hi">0.20503</td><td class="hi">0.06719</td><td class="hi">0.03539</td></tr>
  219. <tr><td>3-wise supercell “hex2” pattern dithering</td>
  220. <td>0.32643</td><td>0.07861</td><td>0.04061</td></tr>
  221. <tr><td>9-wise supercell “hex2” pattern dithering</td>
  222. <td>0.32336</td><td>0.07775</td><td>0.04087</td></tr>
  223. <tr><td>14×14 void-and-cluster dithering</td>
  224. <td class="hi">0.19726</td><td class="hi">0.06748</td><td class="hi">0.03663</td></tr>
  225. <tr><td>25×25 void-and-cluster dithering</td>
  226. <td class="hi">0.19248</td><td class="hi">0.06267</td><td class="hi">0.03325</td></tr>
  227. <tr><th>Chapter 3: Error diffusion</th>
  228. <th>Error %<br />σ = 1</th><th>Error %<br />σ = 1.5</th><th>Error %<br />σ = 2</th></tr>
  229. <tr><td>naïve error diffusion</td>
  230. <td>0.33352</td><td>0.06372</td><td>0.01961</td></tr>
  231. <tr><td>Floyd-Steinberg error diffusion</td>
  232. <td class="hi">0.09249</td><td class="hi">0.01847</td><td class="hi">0.00859</td></tr>
  233. <tr><td>serpentine Floyd-Steinberg error diffusion</td>
  234. <td class="hi">0.09891</td><td class="hi">0.01849</td><td class="hi">0.00749</td></tr>
  235. <tr><td>Jarvis, Judice and Ninke dithering</td>
  236. <td>0.27198</td><td>0.06257</td><td>0.03472</td></tr>
  237. <tr><td>Fan dithering</td>
  238. <td class="hi">0.10220</td><td class="hi">0.01728</td><td class="hi">0.00705</td></tr>
  239. <tr><td>4-cell Shiau-Fan dithering</td>
  240. <td class="hi">0.11618</td><td class="hi">0.01785</td><td class="hi">0.00660</td></tr>
  241. <tr><td>5-cell Shiau-Fan dithering</td>
  242. <td class="hi">0.11550</td><td class="hi">0.01950</td><td class="hi">0.00708</td></tr>
  243. <tr><td>Stucki dithering</td>
  244. <td>0.19765</td><td>0.05373</td><td>0.03012</td></tr>
  245. <tr><td>Burkes dithering</td>
  246. <td>0.15831</td><td>0.04014</td><td>0.02178</td></tr>
  247. <tr><td>Sierra dithering</td>
  248. <td>0.23498</td><td>0.05415</td><td>0.03011</td></tr>
  249. <tr><td>Sierra 2 dithering</td>
  250. <td>0.22249</td><td>0.05121</td><td>0.02812</td></tr>
  251. <tr><td>Filter Lite</td>
  252. <td class="hi">0.09740</td><td class="hi">0.01605</td><td class="hi">0.00638</td></tr>
  253. <tr><td>Atkinson dithering</td>
  254. <td>0.47209</td><td>0.31012</td><td>0.27339</td></tr>
  255. <tr><td>Riemersma dithering on a Hilbert curve</td>
  256. <td>0.28224</td><td>0.06529</td><td>0.02693</td></tr>
  257. <tr><td>Riemersma dithering on a Hilbert 2 curve</td>
  258. <td>0.26622</td><td>0.06003</td><td>0.02492</td></tr>
  259. <tr><td>spatial Hilbert dithering on a Hilbert curve</td>
  260. <td>0.27289</td><td>0.06124</td><td>0.02184</td></tr>
  261. <tr><td>spatial Hilbert dithering on a Hilbert 2 curve</td>
  262. <td>0.22821</td><td>0.05246</td><td>0.01911</td></tr>
  263. <tr><td>dot diffusion</td>
  264. <td>0.38301</td><td>0.08063</td><td>0.01918</td></tr>
  265. <tr><td>dot diffusion with sharpen = 0.9</td>
  266. <td>0.78546</td><td>0.34941</td><td>0.23479</td></tr>
  267. <tr><td>dot diffusion with sharpen = 0.9 and zeta = 0.2</td>
  268. <td>2.91287</td><td>2.19398</td><td>1.99858</td></tr>
  269. <tr><td>serpentine Floyd-Steinberg with sharpen = 0.9</td>
  270. <td>0.62615</td><td>0.30851</td><td>0.22111</td></tr>
  271. <tr><td>omni-directional error diffusion</td>
  272. <td>0.23860</td><td>0.06821</td><td>0.03498</td></tr>
  273. <tr><td>Ostromoukhov’s variable error diffusion</td>
  274. <td class="hi">0.11203</td><td class="hi">0.01772</td><td class="hi">0.00593</td></tr>
  275. <tr><td>nearest block matching with 2×2 line tiles</td>
  276. <td>1.92430</td><td>1.34822</td><td>1.13685</td></tr>
  277. <tr><td>block error diffusion with 2×2 line tiles</td>
  278. <td>0.86807</td><td>0.22411</td><td>0.08901</td></tr>
  279. <tr><td>block error diffusion with 3×3 artistic tiles</td>
  280. <td>1.78626</td><td>0.56957</td><td>0.23000</td></tr>
  281. <tr><td>block error diffusion with all 2×2 tiles</td>
  282. <td>0.56466</td><td>0.15910</td><td>0.06946</td></tr>
  283. <tr><td>block error diffusion with all 2×2 tiles and<br />weighted intra-block error distribution</td>
  284. <td>0.37738</td><td>0.10434</td><td>0.04643</td></tr>
  285. <tr><td>sub-block error diffusion with all 2×2 tiles</td>
  286. <td>0.14697</td><td>0.02605</td><td class="hi">0.00894</td></tr>
  287. <tr><td>sub-block error diffusion with 2×2 line tiles</td>
  288. <td>0.35759</td><td>0.06081</td><td>0.01855</td></tr>
  289. <tr><td>sub-block error diffusion with all 3×3 tiles</td>
  290. <td>0.32802</td><td>0.06516</td><td>0.02165</td></tr>
  291. <tr><td>sub-block error diffusion with 3×3 artistic tiles</td>
  292. <td>1.03963</td><td>0.21839</td><td>0.06678</td></tr>
  293. <tr><th>Chapter 4: Model-based dithering</th>
  294. <th>Error %<br />σ = 1</th><th>Error %<br />σ = 1.5</th><th>Error %<br />σ = 2</th></tr>
  295. <tr><td>DBS with HVS <i>e<small><sup> -sqrt(x²+y²)</sup></small></i>, iteration 1</td>
  296. <td>0.25810</td><td>0.06780</td><td>0.03489</td></tr>
  297. <tr><td>DBS with HVS <i>e<small><sup> -sqrt(x²+y²)</sup></small></i>, iteration 2</td>
  298. <td>0.13762</td><td>0.03234</td><td>0.01939</td></tr>
  299. <tr><td>DBS with HVS <i>e<small><sup> -sqrt(x²+y²)</sup></small></i>, iteration 5</td>
  300. <td class="hi">0.10452</td><td>0.02745</td><td>0.01918</td></tr>
  301. <tr><td>DBS with HVS <i>e<small><sup> -(x²+y²)/2</sup></small></i>, iteration 5</td>
  302. <td class="hi">0.10344</td><td>0.03860</td><td>0.02669</td></tr>
  303. <tr><td>DBS with HVS <i>e<small><sup> -(x²+y²)/4.5</sup></small></i>, iteration 5</td>
  304. <td>0.18034</td><td class="hi">0.00984</td><td class="hi">0.00219</td></tr>
  305. <tr><td>DBS with HVS <i>e<small><sup> -(x²+y²)/8</sup></small></i>, iteration 5</td>
  306. <td>0.37804</td><td>0.02866</td><td class="hi">0.00295</td></tr>
  307. <tr><td>DBS with HVS <i>2e<small><sup> -(x²+y²)/1.5</sup></small> + e<small><sup> -(x²+y²)/8</sup></small></i>, iteration 5</td>
  308. <td class="hi">0.09838</td><td class="hi">0.00884</td><td class="hi">0.00263</td></tr>
  309. </table>
  310. <!--
  311. DBS, sqrt:
  312. 1.55543 0.68523 0.39111
  313. 0.25810 0.06780 0.03489
  314. 0.13762 0.03234 0.01939
  315. 0.10452 0.02745 0.01918
  316. DBS, sigma = 1:
  317. 1.55543 0.68523 0.39111
  318. 0.25379 0.09531 0.05629
  319. 0.13447 0.04785 0.03057
  320. 0.10344 0.03860 0.02669
  321. DBS, sigma = 1.5:
  322. 1.55543 0.68523 0.39111
  323. 0.34373 0.05932 0.02545
  324. 0.22412 0.01906 0.00560
  325. 0.18034 0.00984 0.00219
  326. DBS, sigma = 2:
  327. 1.55543 0.68523 0.39111
  328. 0.54240 0.09412 0.03133
  329. 0.41340 0.04324 0.00804
  330. 0.37804 0.02866 0.00295
  331. -->
  332. <p></p>
  333. <div style="float: left;">
  334. <a href="part3.html">Error diffusion &lt;&lt;&lt;</a>
  335. </div>
  336. <div style="float: right;">
  337. <a href="part5.html">&gt;&gt;&gt; Greyscale dithering</a>
  338. </div>
  339. <div style="text-align: center;">
  340. <a href="index.html">^^^ Index</a>
  341. </div>
  342. <?php $rev = '$Id$';
  343. include($_SERVER['DOCUMENT_ROOT'].'/footer.inc'); ?>
  344. </body>
  345. </html>