Image Processing: Flatten a 3D Ball
My best attempt at this so far is kind of inspired by the difference of Gaussians. I'm putting it as an answer, even though I'm not totally happy with it.

Basically I made a blurred version of the image using two different Gaussian kernels. One captures the fine detail (small kernel) and the other captures the broad detail (large kernel). These two were then merged. This new blurred image is then subtracted from the original.

UPDATE: Made the process iterative, added contrast equalisation and changed blur divide to blur subtract.



output_image = get_input_image()

for i in xrange(4):
    # Magic numbers
    sigma_broad = 301
    sigma_fine  = 5
    merge_ratio = 0.5

    # Get blur
    broad_detail = cv2.GaussianBlur(output_image, (sigma_broad, sigma_broad), 0)
    fine_detail  = cv2.GaussianBlur(output_image, (sigma_fine, sigma_fine), 0)
    blurred = merge_ratio*broad_detail + (1-merge_ratio)*fine_detail

    # Subtract blur from original (and correct for average drop in intensity)
    output_image = (output_image + np.mean(blurred)) - blurred

# Contrast equalisation
clahe = cv2.createCLAHE(clipLimit=1.0, tileGridSize=(4,4))
output_image = clahe.apply(output_image.astype(np.uint8))


Result:



The reasons that I'm not totally satisfied with this result:


The information I want is altered. The objects in the ball (e.g. the dark patches) are disproportionally reduced.
There are some artefacts.
There are lots of magic numbers and parameters to fiddle with. Ideally the algorithm should be robust for a variety of balls.


ANOTHER UPDATE:
I had a go at a Laplacian Pyramid filter, which I adapted from here. I got decent results, posting mainly for interest. This strategy allows for targeting frequency bands, but it's very fiddly.