timjerman / JermanEnhancementFilter

Jerman's tubular (vessel) and spherical (blob) enhancement filters
Other
62 stars 23 forks source link

Merging of small vessels, hollowing of large vessels #1

Closed Chadwick4 closed 5 years ago

Chadwick4 commented 6 years ago

Hello,

Just want to first say what an amazing code this is and how useful it is for my field. I am trying to use it on micro-CT images of a mouse lung. Due to the nature of the vasculature in lungs, I am trying to preserve both very large vessels (~2mm in diameter) and very small (~15 microns in diameter). I have found a nice range of sigmas for the small to medium sized vessels (1:10). When I do this however, only parts of the outline of larger vessels are detected. When I increase the sigma range (1:40), I get a new problem of smaller vessels merging together.

Have you ever run into this during development? I think I understand why it is happening, but I am at a loss for how to fix it. Is it maybe just a limitation of the code that vessels that are so different in size cannot be characterized at the same time?

Any help you can provide would be greatly appreciated!

Cheers,

Eric

timjerman commented 6 years ago

Hi Eric (@Chadwick4),

probably you have also tried tuning the parameter tau? Usually by lowering it, it can help increase the intensities across all vessels, but unfortunately it also results in more false positives. Usually, some additional preprocessing before applying the filter that balances the intensities across the vessels can help. But with such a large range of vessel diameters it is always hard to tune everything. Nevertheless, if you are able to share one image with me, it would be much easier for me to see where the problems are. I could then try to point you in a better direction.

Regards, Tim

Chadwick4 commented 6 years ago

Hi Tim,

Thanks for getting back to me so quickly! I have tried tuning Tau, and it does help a bit, but as you said it creates more false positives and doesn't improve my situation enough to make it worth it. I will try improving contrast on my end. Meanwhile I have attached an image you can take a look at if you have the time. I have downsampled it significantly so it is easier to troubleshoot and upload. Any suggestions you have would be greatly appreciated!

Cheers,

Eric im.zip

timjerman commented 6 years ago

Hi Eric,

it's really a challenging problem that you have. As you already found out, I believe it is not possible to select a range of scales that would enhance both small and large vessels. The large ones are really huge, and if you want to enhance them, you would need to select a large scale, however, this large scale would marge smaller vessels together. Nevertheless, the large vessels in your image have high intensities, so I think there is no need for enhancing them as you can extract them with simpler techniques. So you could, for example, combine the enhancement of smaller vessels with thresholding of the larger ones.

Here is an example code with some comments:

% I - input 3D image
% improve the contrast
I = double(I);
I(I > 120) = 120; 
% I just manually selected the values [64, 120], but could be done automatically
% for example the upper threshold can by found taking the 99th percentile of the image
I(I<64) = 64;

% normalization to [0, 1] range
I = I - min(I(:));
I = I / max(I(:));

% enhancement of smaller vessels
V = vesselness3D(I, 0.25:0.25:1, [1;1;1], 0.75, true);

% apply nonlinear scaling and threshold input image to extract the larger vessels
I_gamma = I.^0.5;
I_gamma (I_gamma < 0.8) = 0;

% merge smaller and larger vessels
O = max(V, I_gamma))

% afterwards you can threshold the response to get a segmentation
O = O(O > 0.5);
% if needed, you can than apply the segmentation to the input image
I_v = I .* O;

There is another idea that comes to mind, but I haven't tested it: First detect the smaller vessels. This should give you also the outline of the large ones. Threshold this response. Than maybe you can apply some kind of a hole filling method, that would be able to fill the larger vessels. Or maybe find connected components and then fill them.

I hope that this helps you in some way!

Regards, Tim

Chadwick4 commented 6 years ago

Hi Tim,

Thank you so much for this. Sorry for my late response, I have been preparing for upcoming experiments and haven't been focused on image processing as much. I tried the code you provided and it worked quite well! It is hard to tell how well on a small image so I am waiting for results on the full sized image, but it seems promising! I'll let you know when I get the final results if you are interested.

Thanks again!

Eric

timjerman commented 6 years ago

Hi Eric,

I am glad to hear that the solutions works for you and I hope that it will be successful also for the full sized image. When you get the results I would be interested to hear how it went.

Regards, Tim

Chadwick4 commented 6 years ago

Hi Tim,

The code worked well on larger images! Thanks again! Just have to change some values. I am using the 99th percentile as you suggested and that works well. To use this on my largest images, however I am attempting to compile the script so I can send it to a server farm for computation. The issue I am running into is with the eig3volume file. Since it is not a matlab function I cannot simply put it into the main script and compile it and the compiled script can't seem to access the mex or c file while running.

Do you have any suggestions for how to get around this? I am compiling using matlabs mcc compiler in linux. Or do you by any chance have a matlab equivalent function?

Cheers,

Eric

On Fri, Jun 1, 2018 at 1:48 AM, timjerman notifications@github.com wrote:

Hi Eric,

I am glad to hear that the solutions works for you and I hope that it will be successful also for the full sized image. When you get the results I would be interested to hear how it went.

Regards, Tim

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/timjerman/JermanEnhancementFilter/issues/1#issuecomment-393767191, or mute the thread https://github.com/notifications/unsubscribe-auth/AfmCZzClgYehUVQ7fTOisgP8hlYL_E57ks5t4NWvgaJpZM4T-QPy .

timjerman commented 6 years ago

Hi Eric,

it is great to hear that everything is still working well for you. I've done a quick search for the replacement of the eig3volume function. You can try the eigenvaluefield33 function.

In the vesselnes3D.m you need to replace the following line:

[Lambda1i,Lambda2i,Lambda3i]=eig3volume(Hxx,Hxy,Hxz,Hyy,Hyz,Hzz);

with:

[Lambda1eig,Lambda2eig,Lambda3eig] = eigenvaluefield33(Hxx,Hxy,Hxz,Hyy,Hyz,Hzz);
Lambda3i = min(min(Lambda1eig, Lambda2eig), Lambda3eig);
Lambda1i = max(max(Lambda1eig, Lambda2eig), Lambda3eig);
Lambda2i = Lambda1eig+Lambda2eig+Lambda3eig - Lambda1i - Lambda3i;

The last three lines sort the eigenvalues, because the eigenvaluefield33 function doesn't sort them by itself. I did a quick test of the replacement and the results seems the same, however, I haven't thoroughly tested it.

Regards, Tim

Chadwick4 commented 6 years ago

Hi Tim,

Thanks for the quick reply! I was actually able to get support from the people who run the server farm and I was able to compile using mex on their server so that it was a linux mex file, and then compile my script to include the mex file. This worked and now I can try with my large images!

Thanks again!

Cheers,

Eric

On Wed, Jul 11, 2018 at 12:54 PM, timjerman notifications@github.com wrote:

Hi Eric,

it is great to hear that everything is still working well for you. I've done a quick search for the replacement of the eig3volume function. You can try the eigenvaluefield33 https://www.mathworks.com/matlabcentral/fileexchange/40677-fast-eigenvalue-computation-of-massive-3-by-3-real-symmetric-matrices?s_tid=mwa_osa_a function.

In the vesselnes3D.m you need to replace the following line:

[Lambda1i,Lambda2i,Lambda3i]=eig3volume(Hxx,Hxy,Hxz,Hyy,Hyz,Hzz);

with:

[Lambda1eig,Lambda2eig,Lambda3eig] = eigenvaluefield33(Hxx,Hxy,Hxz,Hyy,Hyz,Hzz); Lambda3i = min(min(Lambda1eig, Lambda2eig), Lambda3eig); Lambda1i = max(max(Lambda1eig, Lambda2eig), Lambda3eig); Lambda2i = Lambda1eig+Lambda2eig+Lambda3eig - Lambda1i - Lambda3i;

The last three lines sort the eigenvalues, because the eigenvaluefield33 function doesn't sort them by itself. I did a quick test of the replacement and the results seems the same, however, I haven't thoroughly tested it.

Regards, Tim

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/timjerman/JermanEnhancementFilter/issues/1#issuecomment-404239202, or mute the thread https://github.com/notifications/unsubscribe-auth/AfmCZ7BcrqnzaxSLtafDlBx4b7CsHBfcks5uFi22gaJpZM4T-QPy .

Chadwick4 commented 5 years ago

Hi Tim,

Things have been going very well with my images since taking your advice. Thanks again!

I was wondering if I might be able to trouble you for some more advice regarding your other algorithm for enhancing blobs in 3D. I have 2D images of bubbles from a lab mate and I have been trying to help him enhance the bubbles since there is a lot of noise in the images. The SNR may be too high, but so far I have been able to isolate some of them roughly using median filters, mean filters, and segmentation techniques. I thought maybe a blobness enhancement filter would do better, so I tried yours, but it is for 3D specifically and I am not sure how to adapt it to 2D or if it even makes sense too. I was planning a 'circularity test' after segmentation, but I'd prefer to enhance the bubbles before segmentation like I do with my vessels using your code.

Best Regards,

Eric

On Wed, Jul 11, 2018 at 12:56 PM Eric Chadwick eric.chadwick1@gmail.com wrote:

Hi Tim,

Thanks for the quick reply! I was actually able to get support from the people who run the server farm and I was able to compile using mex on their server so that it was a linux mex file, and then compile my script to include the mex file. This worked and now I can try with my large images!

Thanks again!

Cheers,

Eric

On Wed, Jul 11, 2018 at 12:54 PM, timjerman notifications@github.com wrote:

Hi Eric,

it is great to hear that everything is still working well for you. I've done a quick search for the replacement of the eig3volume function. You can try the eigenvaluefield33 https://www.mathworks.com/matlabcentral/fileexchange/40677-fast-eigenvalue-computation-of-massive-3-by-3-real-symmetric-matrices?s_tid=mwa_osa_a function.

In the vesselnes3D.m you need to replace the following line:

[Lambda1i,Lambda2i,Lambda3i]=eig3volume(Hxx,Hxy,Hxz,Hyy,Hyz,Hzz);

with:

[Lambda1eig,Lambda2eig,Lambda3eig] = eigenvaluefield33(Hxx,Hxy,Hxz,Hyy,Hyz,Hzz); Lambda3i = min(min(Lambda1eig, Lambda2eig), Lambda3eig); Lambda1i = max(max(Lambda1eig, Lambda2eig), Lambda3eig); Lambda2i = Lambda1eig+Lambda2eig+Lambda3eig - Lambda1i - Lambda3i;

The last three lines sort the eigenvalues, because the eigenvaluefield33 function doesn't sort them by itself. I did a quick test of the replacement and the results seems the same, however, I haven't thoroughly tested it.

Regards, Tim

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/timjerman/JermanEnhancementFilter/issues/1#issuecomment-404239202, or mute the thread https://github.com/notifications/unsubscribe-auth/AfmCZ7BcrqnzaxSLtafDlBx4b7CsHBfcks5uFi22gaJpZM4T-QPy .

timjerman commented 5 years ago

Hi Eric,

it is nice to hear that you are progressing well.

I never needed a filter for enhancing blobs in 2D so I now tried to create one. Because of this, the code is totally experimental and not validated. I pushed the code for 2D blob enhancement together with an example to git so you can try it out.

On lines https://github.com/timjerman/JermanEnhancementFilter/blob/master/blobness2D.m#L54-L57 I commented possible changes to the code that might result in slightly different enhancement responses. So you can try to modify those to receive a better response.

Regards, Tim

Chadwick4 commented 5 years ago

Hi Tim,

Wow! I was not expected you to do that. Thank you so much! I tried it out got some very promising results! Hopefully my lab mate will be as excited as I am. As always whenever we publish results using your code I will make sure to give you credit.

Thank you again for being such a friendly developer!

Cheers,

Eric

On Tue, Dec 11, 2018 at 5:24 PM timjerman notifications@github.com wrote:

Hi Eric,

it is nice to hear that you are progressing well.

I never needed a filter for enhancing blobs in 2D so I now tried to create one. Because of this, the code is totally experimental and not validated. I pushed the code for 2D blob enhancement together with an example to git so you can try it out.

On lines https://github.com/timjerman/JermanEnhancementFilter/blob/master/blobness2D.m#L54-L57 I commented possible changes to the code that might result in slightly different enhancement responses. So you can try to modify those to receive a better response.

Regards, Tim

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/timjerman/JermanEnhancementFilter/issues/1#issuecomment-446385648, or mute the thread https://github.com/notifications/unsubscribe-auth/AfmCZ1A3aTSQ4EcWs8cVqZ0Mm1sRBOUGks5u4DB-gaJpZM4T-QPy .