<?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">>>> 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">>>> 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>