Changeset 1936 for www


Ignore:
Timestamp:
Nov 11, 2007, 10:16:08 PM (13 years ago)
Author:
Sam Hocevar
Message:
  • Random dithering.
Location:
www/study
Files:
4 added
2 edited

Legend:

Unmodified
Added
Removed
  • www/study/index.html

    r1935 r1936  
    245245and, in some cases, cause even worse artifacts. </p>
    246246
    247 <!--
    248247<h3> 2.4. Random dithering </h3>
    249248
    250 TODO
    251 -->
     249<p> Instead of using a deterministic threshold matrix, one can use a different
     250random value for each pixel in the image. This technique is simply called
     251<b>random dithering</b>. Here is an example with values uniformly chosen
     252between 0 and 1: </p>
     253
     254<p style="text-align: center;">
     255  <img src="out2-4-1.png" width="256" height="256"
     256       class="inline" alt="random dithering" />
     257  <img src="grad2-4-1.png" width="32" height="256"
     258       class="inline" alt="random dithering gradient" />
     259</p>
     260
     261<p> This is random dithering with threshold values chosen with a gaussian
     262distribution (mean 0.5, standard deviation 0.15): </p>
     263
     264<p style="text-align: center;">
     265  <img src="out2-4-2.png" width="256" height="256"
     266       class="inline" alt="gaussian (0.5, 0.15) dithering" />
     267  <img src="grad2-4-2.png" width="32" height="256"
     268       class="inline" alt="gaussian (0.5, 0.15) dithering gradient" />
     269</p>
    252270
    253271<h2> 3. Error diffusion </h2>
     
    255273<p> The idea behind error diffusion is to compute the error caused by
    256274thresholding a given pixel and propagate it to neighbour pixels to
    257 compensate for the brightness loss. It is based upon the assumption that
    258 a slightly out-of-place pixel is better than a completely missing pixel. </p>
     275compensate for the average intensity loss or gain. It is based upon the
     276assumption that a slightly out-of-place pixel causes little visual harm.
     277</p>
    259278
    260279<h3> 3.1. Floyd-Steinberg error diffusion </h3>
  • www/study/study.py

    r1935 r1936  
    11#!/usr/bin/env python
    22
    3 import math, gd
     3import math, gd, random
    44
    55# Tiny image class to make examples short and readable
     
    5252# Output 1.1.2: 40% threshold
    5353# Output 1.1.3: 60% threshold
    54 def test1(src, threshold, name):
     54def test11x(src, threshold, name):
    5555    (w, h) = src.size()
    5656    dest = Image((w, h))
     
    6161    dest.writePng(name)
    6262
    63 test1(lenna256bw, 0.5, "out1-1-1.png")
    64 test1(lenna256bw, 0.4, "out1-1-2.png")
    65 test1(lenna256bw, 0.6, "out1-1-3.png")
    66 test1(gradient256bw, 0.5, "grad1-1-1.png")
    67 test1(gradient256bw, 0.4, "grad1-1-2.png")
    68 test1(gradient256bw, 0.6, "grad1-1-3.png")
     63test11x(lenna256bw, 0.5, "out1-1-1.png")
     64test11x(lenna256bw, 0.4, "out1-1-2.png")
     65test11x(lenna256bw, 0.6, "out1-1-3.png")
     66test11x(gradient256bw, 0.5, "grad1-1-1.png")
     67test11x(gradient256bw, 0.4, "grad1-1-2.png")
     68test11x(gradient256bw, 0.6, "grad1-1-3.png")
    6969
    7070# Output 1.2.1: 3-colour threshold
    7171# Output 1.2.2: 5-colour threshold
    72 def test2(src, colors, name):
     72def test12x(src, colors, name):
    7373    (w, h) = src.size()
    7474    dest = Image((w, h))
     
    8282    dest.writePng(name)
    8383
    84 test2(lenna256bw, 3, "out1-2-1.png")
    85 test2(lenna256bw, 5, "out1-2-2.png")
    86 test2(gradient256bw, 3, "grad1-2-1.png")
    87 test2(gradient256bw, 5, "grad1-2-2.png")
     84test12x(lenna256bw, 3, "out1-2-1.png")
     85test12x(lenna256bw, 5, "out1-2-2.png")
     86test12x(gradient256bw, 3, "grad1-2-1.png")
     87test12x(gradient256bw, 5, "grad1-2-2.png")
    8888
    8989# Pattern 2.1.1: a 50% halftone pattern with various block sizes
     
    109109
    110110# Output 2.1.1: 20/40/60/80% threshold with 25/50/75% patterns inbetween:
    111 def test3(src, name):
     111def test211(src, name):
    112112    (w, h) = src.size()
    113113    dest = Image((w, h))
     
    128128    dest.writePng(name)
    129129
    130 test3(lenna256bw, "out2-1-1.png")
    131 test3(gradient256bw, "grad2-1-1.png")
     130test211(lenna256bw, "out2-1-1.png")
     131test211(gradient256bw, "grad2-1-1.png")
    132132
    133133# Pattern 2.2.1: vertical, mixed and horizontal black-white halftones
     
    165165# Output 2.3.2: 4x4 cluster dot
    166166# Output 2.3.3: 5x3 line dithering
    167 def test4(src, mat, name):
     167def test23x(src, mat, name):
    168168    (w, h) = src.size()
    169169    dest = Image((w, h))
     
    182182       [  2, 10,  1,  9],
    183183       [ 13,  6, 14,  5]]
    184 test4(lenna256bw, mat, "out2-3-1.png")
    185 test4(gradient256bw, mat, "grad2-3-1.png")
     184test23x(lenna256bw, mat, "out2-3-1.png")
     185test23x(gradient256bw, mat, "grad2-3-1.png")
    186186
    187187mat = [[ 12,  5,  6, 13],
     
    189189       [ 11,  3,  2,  8],
    190190       [ 15, 10,  9, 14]]
    191 test4(lenna256bw, mat, "out2-3-2.png")
    192 test4(gradient256bw, mat, "grad2-3-2.png")
     191test23x(lenna256bw, mat, "out2-3-2.png")
     192test23x(gradient256bw, mat, "grad2-3-2.png")
    193193
    194194mat = [[ 13,  7,  0,  4, 10],
    195195       [  9,  3,  1,  8, 14],
    196196       [ 11,  5,  2,  6, 12],]
    197 test4(lenna256bw, mat, "out2-3-3.png")
    198 test4(gradient256bw, mat, "grad2-3-3.png")
     197test23x(lenna256bw, mat, "out2-3-3.png")
     198test23x(gradient256bw, mat, "grad2-3-3.png")
     199
     200# Output 2.4.1: uniform random dithering
     201def test241(src, name):
     202    random.seed(0)
     203    (w, h) = src.size()
     204    dest = Image((w, h))
     205    for y in range(h):
     206        for x in range(w):
     207            c = src.getGray(x, y)
     208            d = c > random.random()
     209            dest.setGray(x, y, d)
     210    dest.writePng(name)
     211
     212test241(lenna256bw, "out2-4-1.png")
     213test241(gradient256bw, "grad2-4-1.png")
     214
     215# Output 2.4.2: random dithering
     216def test242(src, name):
     217    random.seed(0)
     218    (w, h) = src.size()
     219    dest = Image((w, h))
     220    for y in range(h):
     221        for x in range(w):
     222            c = src.getGray(x, y)
     223            d = c > random.gauss(0.5, 0.15)
     224            dest.setGray(x, y, d)
     225    dest.writePng(name)
     226
     227test242(lenna256bw, "out2-4-2.png")
     228test242(gradient256bw, "grad2-4-2.png")
    199229
    200230# Output 3.1.1: standard Floyd-Steinberg
    201 def test5(src, name):
     231def test311(src, name):
    202232    (w, h) = src.size()
    203233    dest = Image((w, h))
     
    218248    dest.writePng(name)
    219249
    220 test5(lenna256bw, "out3-1-1.png")
    221 test5(gradient256bw, "grad3-1-1.png")
     250test311(lenna256bw, "out3-1-1.png")
     251test311(gradient256bw, "grad3-1-1.png")
    222252
    223253# Output 3.1.2: serpentine Floyd-Steinberg
    224 def test6(src, name):
     254def test312(src, name):
    225255    (w, h) = src.size()
    226256    dest = Image((w, h))
     
    255285    dest.writePng(name)
    256286
    257 test6(lenna256bw, "out3-1-2.png")
    258 test6(gradient256bw, "grad3-1-2.png")
     287test312(lenna256bw, "out3-1-2.png")
     288test312(gradient256bw, "grad3-1-2.png")
    259289
    260290# Output 3.2.1: Fan (modified Floyd-Steinberg)
    261 def test7(src, name):
     291def test321(src, name):
    262292    (w, h) = src.size()
    263293    dest = Image((w, h))
     
    278308    dest.writePng(name)
    279309
    280 test7(lenna256bw, "out3-2-1.png")
    281 test7(gradient256bw, "grad3-2-1.png")
     310test321(lenna256bw, "out3-2-1.png")
     311test321(gradient256bw, "grad3-2-1.png")
    282312
    283313# Output 3.2.2: Jarvis, Judice and Ninke
    284 def test8(src, name):
     314def test322(src, name):
    285315    (w, h) = src.size()
    286316    dest = Image((w, h))
     
    312342    dest.writePng(name)
    313343
    314 test8(lenna256bw, "out3-2-2.png")
    315 test8(gradient256bw, "grad3-2-2.png")
     344test322(lenna256bw, "out3-2-2.png")
     345test322(gradient256bw, "grad3-2-2.png")
    316346
    317347# Output 3-2-3: Stucki
    318348# TODO: merge with Jarvis, Judice and Ninke
    319 def test9(src, name):
     349def test323(src, name):
    320350    (w, h) = src.size()
    321351    dest = Image((w, h))
     
    347377    dest.writePng(name)
    348378
    349 test9(lenna256bw, "out3-2-3.png")
    350 test9(gradient256bw, "grad3-2-3.png")
     379test323(lenna256bw, "out3-2-3.png")
     380test323(gradient256bw, "grad3-2-3.png")
    351381
    352382##############################################################################
Note: See TracChangeset for help on using the changeset viewer.