marksgraham / OCT-Converter

Tools for extracting the raw optical coherence tomography (OCT) and fundus data from proprietary file formats.
https://pypi.org/project/oct-converter/
MIT License
199 stars 72 forks source link

(E2E-Export) .avi not exported properly + images darker #21

Closed cklat closed 1 year ago

cklat commented 3 years ago

Hi There! First of all, thank you Mark for your work!

I was trying out your implementation for converting Heidelberg's E2E format to images and videos, respectively. I can execute your example file with my exported E2E-file from HEYEX (v1) but there seem to be 2 problems:

1) The resulting .avi file seems to consist only of one image, although in the step where all slides get displayed through the volume.peek() code line, the images of the slides are all different.

2) The converted images of the slides seem to be a bit darker than what I see in the HEYEX software. Therefore, some areas of the slides are not displayed very detailed. However, I'm not sure how significant this problem is as I'm not an ophthalmologist nor do I have any kind of medical background.

Thanks for your help!

marksgraham commented 3 years ago

Hi there,

  1. If you save as sequential image files (e.g. .png) do you get different slices?
  2. I'm aware of this, but there isn't too much I can about it, unfortunately. It is hard to know how much of an issue this is. I suspect there might just be a linear scaling factor between HEYEX and my data, which shouldn't affect any computational analysis of the data but might, as you say, affect someone's ability to interpret the data by examining it.
cklat commented 3 years ago

Hi Mark,

thank you very much for your reply.

Regarding 1) I will try that out but even if this will work out for me, however I believe issue 2) is critical for my application as I'm primarily need to provide the data for manual examination. So if this issue cannot be resolved, solving 1) isn't gonna help, unfortunately. I saw that your implementation is the python version for UOCTE (https://bitbucket.org/uocte/uocte/src/master/). Do you know if in the original version the issue with the darker images appears as well?

marksgraham commented 3 years ago

Hi,

To change the .e2e scaling, you would want to change this line in the code: https://github.com/marksgraham/OCT-Converter/blob/c335a40f9afd7a32d5865e0a4067b2dfdf44630d/oct_converter/readers/e2e.py#L161 where each pixel is raised to the power of 1/2.4 and multiplie by 256. Changing the power and the 256 scaling factor would adjust the brightness. I took this from uocte (https://bitbucket.org/uocte/uocte/src/8ed70b7ecd5c92cbbfaac281fe090cf7136cba6d/src/io/load_heidelberg.cpp#lines-210) but i'm not sure what their rationale was. I don't think I've ever been able to directly compare .e2e extracted from heidelberg's software to data extracted from mine, so you could be in a good position to compare and see if this can be improved. Would you be able to have a play and see if this fixes your problem?

cklat commented 3 years ago

Hi Mark,

thanks for pointing out the code line to change the brightness for the resulting pictures.

Right now I'm trying to experiment with the values and comparing the resulting images to the image displays in heidelberg's software. Another thing I'm noticing during this process is that the number of slides exported seem to be doubled in comparison to the number of slides in the heidelberg software. Unfortunately, I cannot help myself what's the reason behind this and therefore comparing the results is a little bit inaccurate.

marksgraham commented 3 years ago

That is strange. Is there any way you would be able to share a .e2e file with me, and the corresponding scans exported in HEYEX, for me to take a look at?

cklat commented 3 years ago

I have resolved the problem with the number of slides and there was a mistake on my side. The exported .e2e file was a batch export of a few OCTs at the same time. This is most likely not working with the current implementation of your E2E reader. So I tried the process again with a single OCT per .e2e file which works fine.

Dbrown411 commented 3 years ago

To change the .e2e scaling, you would want to change this line in the code: https://github.com/marksgraham/OCT-Converter/blob/c335a40f9afd7a32d5865e0a4067b2dfdf44630d/oct_converter/readers/e2e.py#L161

where each pixel is raised to the power of 1/2.4 and multiplie by 256. Changing the power and the 256 scaling factor would adjust the brightness. I took this from uocte (https://bitbucket.org/uocte/uocte/src/8ed70b7ecd5c92cbbfaac281fe090cf7136cba6d/src/io/load_heidelberg.cpp#lines-210) but i'm not sure what their rationale was. I don't think I've ever been able to directly compare .e2e extracted from heidelberg's software to data extracted from mine, so you could be in a good position to compare and see if this can be improved. Would you be able to have a play and see if this fixes your problem?

I believe that "arbitrary" exponentiation of the pixels (gamma) is used to decompress the distribution of the floating point representation:

1) gamma=1 test-g1

2) gamma=0.2 test-g0 2

3) gamma=0.05 test-g0 05

This is the .tif of one frame exported from the heidelberg system, which has an interesting distribution of intensities and may be a clue for us.

Heidelberg Exported

You can get images that match reasonably well using the smaller gamma and clipping the bottom 50% of the pixels

test-g0 2-clipped_bot_50

, but the smaller gamma also amplifies those periodic spikes. Interestingly, if we fourier transform, clip 50%, and then iFFT, we get pretty good results, with a distribution dependent on the gamma we chose:

Inverse FFT of test-g0 05

Will need to keep experimenting.

marksgraham commented 3 years ago

Really interesting. I think as a minimum we could allow users to set the gamma value as an argument so they experiment with how this might affect their data.

Oli4 commented 2 years ago

I had a similar problem when working with the HEYEX VOL export, where I found the intensity transformation to be logarithmic. If the E2E data is the same as in the VOL file the following function might help:

def vol_intensity_transform(data):
    selection_0 = data == np.finfo(np.float32).max
    selection_data = data <= 1

    new = np.log(data[selection_data] + 2.44e-04)
    new = (new + 8.3) / 8.285

    data[selection_data] = new
    data[selection_0] = 0
    data = np.clip(data, 0, 1)
    return img_as_ubyte(data)

I found the output to differ by at most +/- 3 when compared with the XML export of the same volume for my small sample dataset. This difference arises from the same intensity in VOL data having multiple intensities in the XML data (See images below). There might be an additional context-sensitive processing step?

Plotted XML intensities(y-axis) againts VOL intensities (x-axis) Blue: intensities scatterplot (the values overlap) Red: function I use for the intensity transform

XML/VOL intensities

Zoom in on the plotted intensities. image

If you are interested in reading the HEYEX VOL or XML export which do not seem to be supported by the OCT-converter, have a look at my package eyepy

marksgraham commented 2 years ago

Thanks @Oli4 Your package looks useful, I've had users request the ability to read HEYEX files before. Would you be happy if I linked to it in a 'Related projects' section of my README?

Oli4 commented 2 years ago

@marksgraham This would be great :) I will do so as well!

Oli4 commented 2 years ago

Dear @marksgraham, I just released an annotation tool based on eyepy. Would it be possible to link it in the related projects section? You can find the tool here https://github.com/MedVisBonn/eyelab

marksgraham commented 2 years ago

Hi @Oli4 , Done!

fabhari commented 2 years ago

I had a similar problem when working with the HEYEX VOL export, where I found the intensity transformation to be logarithmic. If the E2E data is the same as in the VOL file the following function might help:

def vol_intensity_transform(data):
    selection_0 = data == np.finfo(np.float32).max
    selection_data = data <= 1

    new = np.log(data[selection_data] + 2.44e-04)
    new = (new + 8.3) / 8.285

    data[selection_data] = new
    data[selection_0] = 0
    data = np.clip(data, 0, 1)
    return img_as_ubyte(data)

I found the output to differ by at most +/- 3 when compared with the XML export of the same volume for my small sample dataset. This difference arises from the same intensity in VOL data having multiple intensities in the XML data (See images below). There might be an additional context-sensitive processing step?

Plotted XML intensities(y-axis) againts VOL intensities (x-axis) Blue: intensities scatterplot (the values overlap) Red: function I use for the intensity transform

XML/VOL intensities

Zoom in on the plotted intensities. image

If you are interested in reading the HEYEX VOL or XML export which do not seem to be supported by the OCT-converter, have a look at my package eyepy

This helped me a lot thanks. the results are so promising

marksgraham commented 1 year ago

Hi all,

I've finally got around to addressing this, making use of @Oli4's intensity transform suggested above. The contrast of extracted .e2e files now seems much better. It's available in the latest version, v0.5.8. If you want the old behaviour, you can use the flag file.read_oct_volume(legacy_intensity_transform=True)