clEsperanto/pyclesperanto_prototype

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

Closed this issue · 3 comments

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!

Hi @davidlbit ,

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

Thanks!

Best,
Robert

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.

Awesome thanks for the feedback!