1

Just doing a simple bump_map operation in python GIMP. But the result has color banding!

import os, glob, sys, time
from gimpfu import *

image = pdb.gimp_file_load(img_path, img_path, run_mode=RUN_NONINTERACTIVE)
gray = pdb.gimp_file_load(gray_path, gray_path, run_mode=RUN_NONINTERACTIVE)

pdb.plug_in_bump_map(image, image.active_layer, gray.active_layer, 
    135.0, 20.00, 30, 0, 0, 0.0, 0.0, 1, 0, 0)
pdb.file_png_save_defaults(image, image.active_layer, out_path, out_path)

If I remove the "plug_in_bump_map" operation, there is no color banding in my final result saved. If I apply a gaussian blur to the grayscale image, the color banding disappears in the final result, but leaves an undesirable blurriness, what should I do? All images are PNG.

example of banding example two

user2827214
  • 1,191
  • 1
  • 13
  • 32
  • 1
    More like round-off errors than banding. Is this Gimp 2.10 or Gimp 2.8? And if 2.10, is this a high-precision image? How do you obtain the bump map? Can you share that layer as a picture? – xenoid Nov 04 '21 at 08:10
  • looks like that plugin is bad. it should use float values for the height instead of integers. – Christoph Rackwitz Nov 04 '21 at 09:27
  • @xenoid it's 2.10. I don't know what defines a high precision image. The image is a 2k x 2k, 479 Kb sized PNG. The grayscale image is obtained by another script that uses OpenCV, and does cv2.cvtColor(, BGR2GRAY) then cv2.distanceTransform, dstType=cv2.CV_8U, I posted the result at https://ibb.co/k9bCTDD – user2827214 Nov 04 '21 at 14:00

1 Answers1

2

OK, so it's banding :)

But if you look closely, the banding is already in your bump map, and is sort of unavoidable since you only have 256 levels in your PNG.

Banding occurs when there is a significant change in value between two uniform areas with a somewhat linear border between them. So the two mitigations are

  • spreading the change around the border:
    • higher precision image, so the changes can be smaller than 1/256
    • blurring the image
  • making the border non linear to the eye (spread noise)
  • dithering, which does a bit of both, since it introduces intermediate values, but places them at random.

The best way to fix the problem is at the source, so if openCV can compute on more that 256 levels, have it do so and export the bump map in some high-bit depth format (16-bit/channel PNG could be enough, otherwise TIFF).

Otherwise if you have to start with an 8 bit bump map:

  1. Load in Gimp
  2. Convert to high-precision (32bit FP linear)
  3. If you look at the histogram at that point you still have only 256 values:

Histogram Before

  1. You then add "dithering" with the RGB noise filter to spread the values to fill the gaps. This is best done with the Histogram dialog up, and cranking up the values until the "hair comb" structure nearly disappears:

RGB noise settings Histogram Noise

  1. You can also use Spread noise to "shake the pixels" a bit (2-3px), so that transitions are less linear and so less visible:

Spread noise

  1. You can then apply the bump mapping. You trade banding for a bit of graininess:

Bump mapped

  1. You can reduce the graininess using Median blur without having to use values that make your image lose too much sharpness.

Median blur

It is also possible to replace steps 4 & 5 by a selective Gaussian blur.

Edit: tried your 16bpc:

  1. Promote to 32bit FP linear
  2. Apply bump-map without pre-processing

"native" result is already much better:

Direct 16bpc bump-mapping

It can be improved with:

  1. color selection of the "flats" color with a threshold of 0
  2. Selective Gaussian blur

16Bps bump map+Selective Gaussian

xenoid
  • 8,396
  • 3
  • 23
  • 49
  • Thanks for all the detail! I did distanceTransform w/ param dstType=cv2.CV_32F, result is numpy.float32, then cv2.imwrite(x.tiff), but the tiff file is now just the black and white edges, no grays. – user2827214 Nov 04 '21 at 17:31
  • Added results with 16-bit bump-map – xenoid Nov 04 '21 at 22:10
  • alternative idea... if the edges were smooth, there would be no ridges in the raised planes, and no banding (I'm guessing). If there's an easy way to smooth the edges like erode dilate, erode dilate - that might cure the banding with no blurriness.? – user2827214 Nov 05 '21 at 08:29
  • Unlikely (but you can try). See beginning of edited answer. – xenoid Nov 05 '21 at 08:50