4
$\begingroup$

There are many descriptions of how to turn a 2D image into a 3D one, however I want to do the opposite, in particular to a ball. As an example, consider the following ball:

enter image description here

If only the (relatively) slow change in intensity due to the light could be removed, the ball would look 2D.

My first approach was to try get a low frequency version of the original, and divide through by that image. A simple way to do that is to blur the image. Here is a sample result using that approach:

enter image description here

This does the job of flattening the light, but there are some problems:

  • There is a light 'halo' around sharp edges.
  • Large flat patches (e.g. the black patches) lose their uniformity in the middle.
  • The edges of the ball are affected by the background during the blurring (there's a dark ring around the ball, particularly noticeable at the bottom right corner).

I've tried mucking about with filters (e.g. bilinear) but haven't really found anything that works. I've also tried to use wavelets (a frequency based approach makes sense to me), but those approaches tended to distort the fine detail, which is very important.

Any ideas on how to do this are greatly appreciated!

$\endgroup$
  • 2
    $\begingroup$ Can you give me another example of what you mean by 3D to 2D? Do you simply want a sort of flattened version of the image? As per your filtered example, do you want to ensure that uniform patches of intensity share the same intensity instead of that haloing effect? $\endgroup$ – rayryeng Jul 13 '14 at 5:46
  • $\begingroup$ Yeah I want to remove the changes due to slow variation, but without distorting the fine detail or the flat values. Kind of like a notch filter effect. I imagined the end result would look something like this, (except with the logo). $\endgroup$ – Pokey McPokerson Jul 13 '14 at 15:15
  • 1
    $\begingroup$ Cool. OK, I get it. Is the desired effect you want supposed to be in Black and White? This is a cool problem. It's like thresholding from colour! $\endgroup$ – rayryeng Jul 13 '14 at 15:24
  • $\begingroup$ The colour doesn't matter, I should've made the original image B&W (updated). $\endgroup$ – Pokey McPokerson Jul 13 '14 at 15:27
  • $\begingroup$ That's fine. Still wouldn't change how I would approach it. Give me a few moments. I'm gonna muck around with this $\endgroup$ – rayryeng Jul 13 '14 at 15:29
3
$\begingroup$

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:

enter image description here

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

  1. The information I want is altered. The objects in the ball (e.g. the dark patches) are disproportionally reduced.
  2. There are some artefacts.
  3. 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.

enter image description here

| improve this answer | |
$\endgroup$
  • 1
    $\begingroup$ Sorry, I haven't forgotten about you. I didn't find a solution that is good enough to be posted. However, consider taking a look at homomorphic filtering. I used it to segment out characters on a license plate when the plate was subject to different shading. stackoverflow.com/questions/24731810/… $\endgroup$ – rayryeng Jul 16 '14 at 21:07
  • $\begingroup$ Thanks! I was actually just looking for a segmentation technique and this looks great! $\endgroup$ – Pokey McPokerson Jul 17 '14 at 6:58
2
$\begingroup$

I tried a 2-D CA-CFAR approach the result and the code is as follows:

% image flattening
clear all; close all;
x = imread('DOX7f.png');
[r, c] = size(x);

N =10;
N2 = N/2;
R = r/N;
C = c/N;
y = zeros(r, c);
K = ones(N+1,N+1);
K(N2:N2+2, :) = 0;
K(:, N2:N2+2) = 0;
K = K/sum(K(:));
y2 = filter2(K, x);
y2 = x > 0.98*y2;

figure(1);
imshow(y2);

The 2-D kernel

The Kernel

The output

The Flattened

Is it what you were looking for?

| improve this answer | |
$\endgroup$
  • $\begingroup$ Thanks, I had never encountered this technique before. It seems quite fragile to the selection of the constant in the last operation (0.98 in your example) though. Ideally I'd like this to work on multiple balls, without having to fiddle with parameters like that for each one. It also has some artefacts (the thick dark ring around the ball for example), and hasn't preserved the flat (black) patches. Thanks for giving me something new to play around with though! $\endgroup$ – Pokey McPokerson Jul 15 '14 at 9:49
  • $\begingroup$ @PokeyMcPokerson Basically the idea was to find a starting point method with variable thresholding. You are right, there are many artifacts and it is very very sensitive to the scaling factor. Besides I also tried histogram equalization at local (10x10 to 100x100 block) and global scale. I tried thresholding based on mean again local and global. Din seem to work that well. $\endgroup$ – learner Jul 15 '14 at 9:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.