[comp.graphics] Floyd-Steinberg, yet again

hutch@net1.ucsd.edu (Jim Hutchison) (07/23/88)

foo()

I have recently written a modified filter for converting grey scale
to 0/1 using another modification of the Floyd-Steinberg error
propagation algorithm.  It works to a point, but generates pools
of color when it travels to long in boring plains of light grey.

pardon my pseudo code:

        short carry[scan line width]         Some 16 bit signed data items

        err = carry[x] + data[x]             Data is an 8 bit grey
        if (err > 0x3f)                      Based on my monitors black
                err = err - 0x0ff            How close were we?
                white_pixel
        else
                black_pixel

    now, do local error propagation (lose 1/16 of it)

               * ->  7/16
            /  |
        3/16 5/16

        carry[x+1] += (7 * err) / 16         One ahead
        if (x == 0)
                carry[x] = err / 2           No back, 3+5/16 = 1/2
        else
                carry[x] = (5 * err) / 16    Propagate error down
                carry[x-1] = (3 * err) / 16  Propagate error diag back

I process the scan lines left-to-right and I do not get anything in the
way of daggers.  Just a  nice patterning like baked paint.  The problem
is that lakes develope in large grey areas where error builds up like a
wave and drips on the picture.  Adding the last term (the 1/16 diagonally
forward), I get black stones like Mt. St. Helens.

I'm going to give the white/blue noise perturbation on the threshhold a
try, I'll keep you posted.  Does anyone have any suggestions?

/*    Jim Hutchison   		UUCP:	{dcdwest,ucbvax}!cs!net1!hutch
		    		ARPA:	JHutchison@ucsd.edu		*/

hutch@net1.ucsd.edu (Jim Hutchison) (07/24/88)

In article <1050@ucsd.EDU> hutch@net1.UUCP (Jim Hutchison) writes:
<               * ->  7/16
>            /  |
<        3/16 5/16
>
<        carry[x+1] += (7 * err) / 16         One ahead
>        if (x == 0)
<                carry[x] = err / 2           No back, 3+5/16 = 1/2
>        else
<                carry[x] = (5 * err) / 16    Propagate error down
TYPO------>      carry[x-1] = (3 * err) / 16  Propagate error diag back
Should Be--->    carry[x-1] += (3 * err) / 16

/*    Jim Hutchison   		UUCP:	{dcdwest,ucbvax}!cs!net1!hutch
		    		ARPA:	JHutchison@ucsd.edu		*/