<?php header("Content-Type: text/html; charset=utf-8"); ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
       "http://www.w3.org/TR/xhtml1/DTD/xhtml11.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">

<head>
   <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
   <meta name="GENERATOR" content="vim" />
   <meta name="Author" content="sam@zoy.org (Sam Hocevar)" />
   <meta name="Description" content="Libcaca study - 1. Colour quantisation" />
   <meta name="Keywords" content="libcaca, ASCII, ASCII ART, console, text mode, ncurses, slang, AAlib, dithering, thresholding" />
   <title>Libcaca study - 1. Colour quantisation</title>
   <link rel="icon" type="image/x-icon" href="/favicon.ico" />
   <link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" />
   <link rel="stylesheet" type="text/css" href="/main.css" />
</head>

<body>

<?php include($_SERVER["DOCUMENT_ROOT"]."/header.inc"); ?>

<p> <span style="color: #aa0000; font-weight: bold;">Warning</span>: this
document is still work in progress. Feel free to send comments but do not
consider it final material. </p>

<div style="float: right;">
   <a href="part2.html">&gt;&gt;&gt; Halftoning</a>
</div>
<div style="text-align: center;">
   <a href="index.html">^^^ Index</a>
</div>

<h2> 1. Colour quantisation </h2>

<p> The process of reducing the number of colours used in an image is called
<b>colour quantisation</b>. It is a very old and common computer graphics
problem. Many methods exist to do the task, and their efficiency depends on
several parameters: </p>

<ul>
  <li> the input image: is it a photograph? a vector drawing? a composition
       of both? </li>
  <li> the target media: is it a computer screen? if so, what are the size
       and the position of the pixels? is it a printed document? if so,
       what kind of paper?  what kind of ink? or maybe the conversion should
       be optimised for both targets? </li>
  <li> the quality requirements: for instance, can contrast be raised for
       a more appealing result at the expense of accuracy?
  <li> the allowed computation time: do we need 50fps or can we afford to
       wait 10 seconds for a better result? </li>
</ul>

<h3> 1.1. Black and white thresholding </h3>

<p> Since a greyscale pixel has a value between 0 and 1, a fast method
to convert the image to black and white is to set all pixels below 0.5
to black and all pixels above 0.5 to white. This method is called
<b>thresholding</b> and, in our case, results in the following image: </p>

<p style="text-align: center;">
  <img src="out/lena1-1-1.png" width="256" height="256"
       class="inline" alt="50% threshold" />
  <img src="out/grad1-1-1.png" width="32" height="256"
       class="inline" alt="50% threshold gradient" />
</p>

<p> Not that bad, but we were pretty lucky: the original image’s brightness
was rather well balanced. A lot of detail is lost, though. Different results
can be obtained by choosing “threshold values” other than 0.5, for instance
0.4 or 0.6, resulting in a much brighter or darker image: </p>

<p style="text-align: center;">
  <img src="out/lena1-1-2.png" width="256" height="256"
       class="inline" alt="40% threshold" />
  <img src="out/grad1-1-2.png" width="32" height="256"
       class="inline" alt="40% threshold gradient" />
  <img src="out/lena1-1-3.png" width="256" height="256"
       class="inline" alt="60% threshold" />
  <img src="out/grad1-1-3.png" width="32" height="256"
       class="inline" alt="60% threshold gradient" />
</p>

<p> Choosing the best thresholding value for a given image is called
<b>average dithering</b>. But even with the best value, the results will
not improve tremendously. </p>

<h3> 1.2. Greyscale thresholding </h3>

<p> Better results can be achieved with a slightly bigger palette. Here is
thresholding applied to a 3-colour and to a 5-colour palette: </p>

<p style="text-align: center;">
  <img src="out/lena1-2-1.png" width="256" height="256"
       class="inline" alt="3-colour threshold" />
  <img src="out/grad1-2-1.png" width="32" height="256"
       class="inline" alt="3-colour threshold gradient" />
  <img src="out/lena1-2-2.png" width="256" height="256"
       class="inline" alt="5-colour threshold" />
  <img src="out/grad1-2-2.png" width="32" height="256"
       class="inline" alt="5-colour threshold gradient" />
</p>

<p> Using this method, shades of grey are evenly used. However, the global
error is far from optimal, as the following graphs show: </p>

<p style="text-align: center;">
  <img src="fig1-2-1.png" width="256" height="256"
       alt="mean error 0.138" />
  <img src="fig1-2-2.png" width="256" height="256"
       alt="mean error 0.075" />
</p>

<p> The following thresholding method minimises the error, at the cost of
underusage of pure black and white colours: </p>

<p style="text-align: center;">
  <img src="out/lena1-2-3.png" width="256" height="256"
       class="inline" alt="3-colour threshold, minimal error" />
  <img src="out/grad1-2-3.png" width="32" height="256"
       class="inline" alt="3-colour threshold gradient, minimal error" />
  <img src="out/lena1-2-4.png" width="256" height="256"
       class="inline" alt="5-colour threshold, minimal error" />
  <img src="out/grad1-2-4.png" width="32" height="256"
       class="inline" alt="5-colour threshold gradient, minimal error" />
</p>

<p style="text-align: center;">
  <img src="fig1-2-3.png" width="256" height="256"
       alt="mean error 0.125" />
  <img src="fig1-2-4.png" width="256" height="256"
       alt="mean error 0.0625" />
</p>

<p> This is a perfect example of a situation where colour accuracy does not
help achieve a better result. </p>

<h3> 1.3. Dynamic thresholding </h3>

<p> Dynamic thresholding consists in studying the image before selecting
the threshold values. One strategy, for instance, is to choose the median
pixel value. This is done simply by computing a histogram of the image. </p>

<p style="text-align: center;">
  <img src="out/lena1-3-1.png" width="256" height="256"
       class="inline" alt="2-colour dynamic threshold" />
  <img src="out/grad1-3-1.png" width="32" height="256"
       class="inline" alt="2-colour dynamic threshold gradient" />
  <img src="out/lena1-3-2.png" width="256" height="256"
       class="inline" alt="5-colour dynamic threshold" />
  <img src="out/grad1-3-2.png" width="32" height="256"
       class="inline" alt="5-colour dynamic threshold gradient" />
</p>

<h3> 1.4. Random dithering </h3>

<p> Instead of constantly using the same threshold value, one can use a
different random value for each pixel in the image. This technique is simply
called <b>random dithering</b>. </p>

<p> Here are two simple examples. On the left, threshold values are uniformly
chosen between 0 and 1. On the right, random dithering with threshold values
chosen with a <b>gaussian distribution</b> (mean 0.5, standard deviation 0.15):
</p>

<p style="text-align: center;">
  <img src="out/lena1-4-1.png" width="256" height="256"
       class="inline" alt="random dithering" />
  <img src="out/grad1-4-1.png" width="32" height="256"
       class="inline" alt="random dithering gradient" />
  <img src="out/lena1-4-2.png" width="256" height="256"
       class="inline" alt="gaussian (0.5, 0.15) dithering" />
  <img src="out/grad1-4-2.png" width="32" height="256"
       class="inline" alt="gaussian (0.5, 0.15) dithering gradient" />
</p>

<p> The images look very noisy, but they are arguably an improvement over
standard constant thresholding. </p>

<p> Finally, this is dynamic thresholding with 4 colours where threshold values
at every pixel are computed as usual, but then perturbated using a gaussian
distribution (mean 0, standard deviation 0.08): </p>

<p style="text-align: center;">
  <img src="out/lena1-4-3.png" width="256" height="256"
       class="inline" alt="4-colour dynamic thresholding, gaussian (0, 0.08)" />
  <img src="out/grad1-4-3.png" width="32" height="256"
       class="inline" alt="4-colour dynamic thresholding, gaussian (0, 0.08) gradient" />
</p>

<div style="float: right;">
   <a href="part2.html">&gt;&gt;&gt; Halftoning</a>
</div>
<div style="text-align: center;">
   <a href="index.html">^^^ Index</a>
</div>

<?php $rev = '$Id$';
      include($_SERVER['DOCUMENT_ROOT'].'/footer.inc'); ?>

</body>
</html>
