clEsperanto / pyclesperanto_prototype

GPU-accelerated bio-image analysis focusing on 3D+t microscopy image data
http://clesperanto.net
BSD 3-Clause "New" or "Revised" License
208 stars 44 forks source link

Discrepancy in Results: Applying Top Hat Morphological Operation on Microscopy Data Volume #331

Closed dxvidparham closed 6 months ago

dxvidparham commented 6 months ago

Hi everyone,

I'm currently exploring the application of the top hat morphological operation on an entire volume of microscopy data. I've followed a similar approach demonstrated in the 3D-Segmentation-Notebook for the Intensity and background correction.

def top_hat(data, radius=10):
    background_corrected_stack = cle.create_like(data)
    a_slice = cle.create([data.shape[1], data.shape[2]])

    num_slices = data.shape[0]
    background_corrected_img = None
    for z in range(0, num_slices):
        # get a single slice out of the stack
        cle.copy_slice(data, a_slice, z)

        background_corrected_img = cle.top_hat_box(a_slice, background_corrected_img, radius_x=radius, radius_y=radius)
        # copy slice back in a stack
        cle.copy_slice(background_corrected_img, background_corrected_stack, z)

    return background_corrected_stack

top_hat_data = top_hat(data)
idx = 1
top_hat_data[idx]

The above code produces the following result:

sample_1

Afterwards, I used the following code to verify the results:

radius = 10
tmp = cle.top_hat_box(data[idx], None, radius_x=radius, radius_y=radius)
tmp

This code yields the following result:

sample_2

I expected the results to be similar, but they differ quite significantly. Can anyone provide insights into why this discrepancy occurs?

Thank you!

haesleinhuepf commented 6 months ago

Hi @davidlbit ,

as you closed the issue, can you tell what was the problem?

Thanks!

Best, Robert

dxvidparham commented 6 months ago

Hi @haesleinhuepf,

The issue I encountered turned out to be a result of my own oversight regarding how Cle works. I realized that the data variable is already of type pyclesperanto_prototype._tier0._pycl.OCLArray, at this point of time.

When attempting the following code:

radius = 10 tmp = cle.top_hat_box(data[idx], None, radius_x=radius, radius_y=radius) tmp

The observed issue occurs due to not accessing the numerical representation of the slice, as one would with numpy arrays, but rather the view representation that Cle offers. I realized this after changing the index values but consistently obtaining the same plot. This realization was further supported by comparing the function with two distinct indexes and comparing their numerical representations against each other, as shown below:

radius = 10 tmp_1 = cle.top_hat_box(equalized_data[0], None, radius_x=radius, radius_y=radius) tmp_2 = cle.top_hat_box(equalized_data[10], None, radius_x=radius, radius_y=radius) (cle.pull(tmp_1) == cle.pull(tmp_2)).all()

This resulted in the output True.

Although I'm not entirely sure what's happening under the hood since no error messages are displayed, it appears that the slice with the most information is used as a fallback in situations like these.

haesleinhuepf commented 6 months ago

Awesome thanks for the feedback!