aatrace - Yet another ASCII-art generator 1. Building $ make while (!works) tweak(Makefile); 2. Program usage Using convenience wrapper script: $ ./aaconvert.sh [OPTIONS] image.pgm Generates image.diff.pgm, image.ascii.txt and image.ascii.pgm files in the current directory. image.diff.pgm is an intermediate differentiated image output, image.ascii.txt is the text output and image.ascii.pgm is the image output. When one or more command line options are specified they are embedded in the output file names as additional suffixes before the final file type. $ ./aaconvert.sh -l 5 image.pgm generates image.diff.l5.pgm, image.ascii.l5.txt and image.ascii.l5.pgm. OPTIONS A. Differentiation options -l <scale> - differentiated image levels scaling Adjusts differential edge map "brightness". Specify small integer in the range of 1..20 (approx). 1 is "normalized" is the sense that it never clips the values (but is too dark for most images). The current default is 6. -d <kernel> - differentiation kernel (size) Adjust the detail/noise sensitivity. Available kernel sizes: 2, 3, 4. The default is 3 (Sobel operator). Specifying 1 skips the differentiation step entirely (aalib-style). -t <thresh> - differentiation map feature detection threshold Differentiation map features weaker than threshold are removed from the output. Adjust the detail/noise sensitivity. Thresholding is applied after scaling transform so that the output value range only depends on the threshold. Specify an integer in the range 0..255. The current default is 64. B. Matching options -m <id> - match method Selects the character matching algorithm used. Available options: 1 - Minimize SAD (sum of absolute differences) 2 - Minimize weighted SAD + ASD (absolute sum of differences) The current default is 2. Notes: * MIN(SAD) is the tried and proven method used in video motion compensation. * MIN(SAD + ASD) tries to preserve perceptible tile brightness as well as its shape. -W <sad>,<asd> - SAD/ASD weight ratio <sad> and <asd> parameters tune the SAD+ASD match algorithm. Specify two integers separated by comma ','. It's NOT a real number, but rather a ratio of weights <sad>/<asd>. Zeros are allowed and meaningful (0 and infinity). The matching algorithm looks for MIN(<sad>*SAD + <asd>*ASD). The default values are <sad> = 5 and <asd> = 1. C. Offset search options -s <id> - offset search method Selects the offset searching algorithm. Available options: 1 - No offset search is performed. The tiles are matched exactly where they are in the source image. 2 - Diamond search. Additionally checks whether better matches can be obtained by offsetting the source image tile by 1 pixel along any axis ("diamond" pattern). Runs match search 5 times. 3 - Box search. The same as diamond + the diagonal moves are checked ("box" pattern). Runs match search 9 times. 4 - Area search. Implements arbitrary size Box search. The search area size is specified with -r option. The current default is 1 - No search. -r (<px>|<hpx>,<vpx>) - area offset search range (pixels) Only affects the Area offset search method. Specifies the search range(s) in both directions. Different ranges in horizontal and vertical directions can be specified with a comma (<hpx>,<vpx>). The current default is <px> = 2 (<hpx> = 2, <vpx> = 2) - 5x5 pixel area. -c <1/0> - enable/disable search coverage test Only affects offset search strategy. Performs match score adjustment for off-center matches to improve source image feature coverage by the character tiles. Should only be disabled for search testing purposes. The current default is 1 - enabled. ENVIRONMENT VARIABLES AAFONT environment variable overrides the default the font image. 2.1 Using the test utilities (plumbing) Generate the differentiated image: $ ./testdiff [-l <scale>] [-d <kernel>] [-t <thresh>] image.pgm image.diff.pgm Generate ASCII text file from the differentiated image: $ ./testconv [OPTIONS] image.diff.pgm font/font8x16.pgm image.ascii.txt OPTIONS ::= [-m <id>] [-W <sad>,<asd>] [-s <id>] [-c <1/0>] [-r (<px>|<hpx>,<vpx>)] Render ASCII text back into an image: $ ./testrender image.ascii.txt font/font8x16.pgm image.ascii.pgm '-' supplied as an argument uses stdin or stdout for inputs and outputs respectively. '--' option separator is required to use '-'. font/font8x16.pgm is the VGA terminal font image supplied as a sample. The font bitmap characters are stacked vertically starting from the whitespace character (ASCII 0x20). All image files are in the Portable GrayMap (PGM) format. ImageMagick or netpbm may be used to generate compatible input(s) and convert output(s) into something more usable. 3. Tweaking Tweaking command line parameters: Changing -l <scale> adjusts the amount of detail (and noise) that makes it into the final ASCII picture. Check generated .diff.pgm file to see the effect of the adjustments. Changing -d <kernel> adjusts the detail sensitivity level. Heavily oversampled images require larger kernels (4), while vector drawing and pixel art details are better preserved by smaller kernels (2). 3 is a reasonable default. Changing -t <thresh> adjusts weak detail/noise sensitivity level. Raising the threshold over the default 64 results in cleaner image, but it retains less features. High threshold value can speed up conversion considerably by removing unnecessary detail and simplifying match decision process. Changing -m <method> affects the match search strategy: * SAD (1) looks for the most similar character representation. * SAD+ASD (2) tries to optimize for the overall perceptible similarity at the expense of larger small-scale errors. Tweaking -W <sad>,<asd> weights ratio tunes SAD+ASD method to pay more attention to shape (SAD) or overall brightness (ASD). Due to the nature of the minimization problem, only the ratio of the weights is significant, i.e. the default -W 5,1 is the same as -W 10,2. -W 1,0 is the same as -m 1, but slower, -W 0,1 is pure ASD (like aalib). Example: $ ./aaconvert.sh -l1 -d1 -W0,1 test.pgm Yields the result very similar to what aalib does. It skips the differentiation (codes levels rather than edges) and uses ASD (average level) for the match search. Enabling offset search via -s 2(3,4) allows for better character matches at the price of small spatial jitter. This usually results in visually "cleaner" image. However, the search algorithm tends to avoid thin lines at the edges of the image tiles by stepping away from them. Skipped lines are not included in the match search often resulting in smaller match errors. Search coverage test compensates for the edge skipping effect by including not matched parts of the source tile in the total match error. Stepping away from a feature results in the same match error as matching it with black level. The coverage test should always be enabled (default) when using offset search for best output quality. Note: Diamond search (-s 2) checks 5 possible offsets for each tile, resulting in 5x slowdown compared to direct matching. Box (-s 3) search analyzes 9 neighboring locations, making it 9x slower. Area (-s 4) search with the default range (-r 2) checks 25 tile locations.