So I am trying to create a script that will do custom dithering while applying a palette. Basically, I want to make sure that errors do not bleed across any 32x32 boundary. Here is the code I came up with. Unfortunately, it looks very messy and inelegant. In my experience, using lots of nested loops in a Python program means you're doing something wrong, but I can't figure out any ways to do it better. So how can I improve this code?
[source lang='python']
def applyPaletteDither(pixels, pal):
def closest_ind(pt):
return ((pal - pt)**2).sum(1).argmin()
h,w,ch = pixels.shape
vals = np.empty((h,w), dtype=int)
size = 32
for ty in xrange(0, pixels.shape[0], size):
for tx in xrange(0, pixels.shape[1], size):
errs = np.zeros((size,size,ch))
for r in xrange(size):
for c in xrange(size):
#FSD weights: [7,3,5,1]/16
px = pixels[ty+r,tx+c] + errs[r,c]/16
ind = closest_ind(px)
vals[ty+r,tx+c] = ind
err = px - pal[ind]
if c<size-1:
errs[r,c+1] += err*7
if r<size-1:
if c>0:
errs[r+1,c-1] += err*3
errs[r+1,c] += err*5
if c<size-1:
errs[r+1,c+1] += err
assert(max(vals.flat[:9]) <= len(pal)) #sanity check
return vals[/source]
python dithering with seperate blocks
What's the problem with this code? Certainly not excessive loop nesting, since you are looping quite naturally on each tile and each pixel of each tile.
Does it work incorrectly? What's the point of processing the image in tiles rather than as a whole? Can't you do better than Floyd-Steinberg dithering?
I can see only stylistic venial sins like ugly variable names (errs, err, ind) and loops to pixels.shape[0] and pixels.shape[1] rather than to the unused w and h.
Does it work incorrectly? What's the point of processing the image in tiles rather than as a whole? Can't you do better than Floyd-Steinberg dithering?
I can see only stylistic venial sins like ugly variable names (errs, err, ind) and loops to pixels.shape[0] and pixels.shape[1] rather than to the unused w and h.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement