You are now following this question
- You will see updates in your followed content feed.
- You may receive emails, depending on your communication preferences.
Anisotropic diffusion for a fingerprint image: resolution issues.
5 views (last 30 days)
Show older comments
Hello,
I have been trying to understand how to successfully use matlab in-built anisotropic diffusion function (imdiffusefilt). To test the function I chose a fingerprint image (that has some noise and some gaps) as my input image. The fingerprint image (.gif) was dowloaded from this url. Incase the hyperlink does not work here is the link: https://www.mia.uni-saarland.de/weickert/demos.html.
There are two images (on 2nd row) under the tittle Gap completion by coherence-enhancing anisotropic diffusion. I will upload the images (1st one is my input image, and 2nd one is the desired result that I am unable to achieve) here as well.
This is the input image (gif):
This is the desired output:
I tried to run 'imdiffusefilt' with default setting, and then ran it with estimated parameters (using 'imdiffuseest' function). My result for the latter is worse. I am going to upload my code below. Any tip/advice on this would be great. Thanks everyone, in advance!
Here is my code:
close all
clear all
%% Read image file
img = imread('finger2.gif');
%% Calculate diffusion parameters (to be used in imdiffusefilt below)
[gradThresh,numIter] = imdiffuseest(img);
%% Check pixel value frequencies (histogram)
figure(11)
histogram(img,805)
%% Apply anisotropic diffusion (imdiffusefilt)
img_diffusion = imdiffusefilt(img,'NumberOfIterations',5); % using default parameters
%% Anisotropic diffusion (using estimated parameters)
% img_diffusion = imdiffusefilt(img,'connectivity','maximal', ...
% 'ConductionMethod','exponential', 'GradientThreshold',gradThresh, ...
% 'NumberOfIterations',numIter);
%% Display the results (original vs anisotropic diffustion)
figure(1)
montage({img,img_diffusion},'ThumbnailSize',[1000,700])
title([' Original Imgae (Left) vs. ' ...
'Smoothing w/ Anisotropic Diffusion (Right)'])
Accepted Answer
Bjorn Gustavsson
on 8 Aug 2022
You might find that you have more control over the anisotropic diffusion with the cedif or eedif functions from the nonlinear-diffusion-toolbox. You might have to doodle around to find the best selection of input-parameters and combination of ordinary filtering and nonlinear isotropic and anisotropic filtering to suit your case. Definitely have a look at that toolbox and its demos and documentation.
HTH
25 Comments
Jay Ghosh
on 9 Aug 2022
Hi Bjorn, thanks for your suggstions. I will explore the toolbox. At first glance, However, I could not find ''eedif" function (though it is mentiond in the parameter description for other functions such as cedif etc).
Bjorn Gustavsson
on 10 Aug 2022
Ah, it seems as if the toolbox version I have has a eedif-version that is nearly indistinguishable from cedif - which I think means that I simply copied cedif.m to edif.m and changed the function-name to match (if I did this it was a long time ago...). The cedif-function have been useful to me at a couple of instances when I needed to filter an image but needed to preserve structures smaller than the necessary filter-width. It was a bit parameter-sensitive when it came to selecting then non-linear diffusivity-reduction, but not difficult to work out with a bit of test and play.
Jay Ghosh
on 19 Aug 2022
Hi Bjorn, I have been able to explore the diffusion toolbox a little during the past few days. The results look decent and are a lot better than anything I had before (see the images below). However, the final output image is not as good as the one I attached with my 1st message (see above); there are rooms for improvement (see the green rectangle on the image below: this area is not resolved).
To elaborate, I just used cedif function (my script w/ parameter values is attached below). Could you please take a look at my scripts and resulting images and let me know your comments / any-further-suggestions? I would greatly appreciate that. Thank you so much!
close all
clear all
%% CEDIF: Coherence enhancing diffusion
%% Read image file
img = imread('finger2.gif'); % fingerprint image
%% Apply cedif to input image
% Set parameters
lambda = 4; sigma = 1.2; rho = 7; m = 100; stepsize = 0.2; steps = 10;
% Apply cedif
img_cedif = cedif(img, lambda, sigma, rho, m, stepsize, steps, 1, 5, ...
'dfstep',2,'imscale', 'grad', 'struc');
%% Convert doubles to uint8
img_cedif = uint8(255*mat2gray(img_cedif));
%% Display the results (original vs anisotropic diffustion)
figure(1)
montage({img,img_cedif},'ThumbnailSize',[1000,700])
title([' Original Imgae (Left) | ' ...
'CEDIF: Coherence Enhanced Diffusion (Right)'])
nldif:
I am now trying to explore nldif function to see if I can achieve further improvements (see attached script below), but no luck so far with resolving the center-right part (see the image below: the area inside the red rectangle), though I could see that some noises have been removed.
close all
clear all
%% Read image file
img = imread('finger2.gif'); % fingerprint image
%% Apply non-linear diffusion
% Set parameters
lambda = 4; sigma = 1.2; rho = 7; m = 100; stepsize = 0.2; steps = 10;
% Or:
% s = 7;
% lambda = [linspace(4,4,s)];
% sigma = [linspace(1.2,1.2,s)];
% m = 100;
% stepsize = 0.2; steps = s;
y = nldif(img, lambda, sigma, m, stepsize, steps, ...
'dfstep', 2, 'grad', 'aos', 'imscale', 1,3); % what are (1,3)? => find out
img_nldif = uint8(255*mat2gray(y));
%% Display the results (original vs anisotropic diffustion)
figure(2)
montage({img,img_nldif},'ThumbnailSize',[1000,700])
title([' Original Imgae (Left) | ' ...
'nldif: Non-linear Diffusion (Right)'])
Bjorn Gustavsson
on 26 Aug 2022
Might be back from vacation Sunday, then will take a look. Play around more with the filter widths and combinations of cedif and nldif perhaps. My take (very much a birds-eye perspective) is that when the output is so parameter-sensitive it might be questionable if it is properly resolvable - sometimes one has to accept that the achievable resolution is not kind to ones objectives...
Jay Ghosh
on 29 Aug 2022
Edited: Jay Ghosh
on 29 Aug 2022
Thanks, Bjorn! Yes, I am still on it, spending some time everyday:)
Another interesting observation is the follwoing. I have been applyig cedif to some image samples that are more realistic, in the sense that those are the kind of images that I will be likely using for my research. These sample images represent magnetic (field) anomaly data (see attached *.png input files).
Once I convert them to grayscale (input for cedif), and run, say, using 10 timestepts, the images begin to shrink from all 4 directions w/ every timestep iteration. For some images, there are zero value blocks inside the image as well (see attached output images: img1.png, img11.png, img2.png, img21.png). It is evident from gradient magnitude plots/images as well (img1_grad_mag.png, img2_grad_mag.png). I suppose we are getting these zero-valued-blocks-of-pixels in the output images as 'cedif' calculates the derivatives. But, I am not sure how to fix this, yet.
I will continue to explore. However, I wanted to share these new findings as well (for these new images).
Thank you very much, indeed, for taking the time out of your busy scedule. I sincerely appreciate it.
Bjorn Gustavsson
on 29 Aug 2022
Another comment with "general opinions": When you do these operations desperately try to find the originial data. The input you have for the NA_iceland seems to be discretised at 3 levels and that doesn't bode well for this type of diffusion where we need gradients. Your Pacific one looks better, but I worry about what looks like clipping/saturation (close to where you get the weird zero-level region).
Jay Ghosh
on 30 Aug 2022
Yes, I realized that, but I still wanted to see what happens if I used the discreticised data.
For the pacific data set, I just clipped the values at 90 percentile (range:-49 to 180 nT) to remove the outliers (on both ends). This resulted in the zero blocks inside output the image (img11.png) as well as along the margins. However, when I ran cedif on the original data (range: -1000 to 1500 nT) without any clipping, I still get the zero values along all the 4 margins, and therefore image seemingly shrinks (img_no_clipping.png). Thanks
Bjorn Gustavsson
on 30 Aug 2022
Quick (possibly stupid question): Does the image you feed cedif contain the "yellow frame"? If so that might lead to your problems.
Outlier removal is an art and a handcraft in and of itself - I have collected some understanding on how to deal with that in my field of work - but it's unclear how well that travels to other fields, so will not give any comments on that unless very explicitly asked...
Jay Ghosh
on 1 Sep 2022
Edited: Jay Ghosh
on 1 Sep 2022
I was wondering about this too, but forgot to ask. If I feed a grayscale image (ex: finer2.gif) as input this yellow frame does not show! However, it happens for the NE_pacific image.
I just checked, and imshow() displays the full image, however, imagesc() or image() produces this yellow/white region along the boundaries (see the plots below) as it squizes the frames inward! This image represents unclipped/original data, btw.
Is this happening because the input image (pacific data) is an indexed image? I saved it as a png fle though (from imagesc display). Does this have any bearing on cedif or is this just a display issue? Thanks
imshow()
imagesc() or image() plot: x = (0-100), and x >750 pixels are blank, as the image is squized inward. No idea what is gping on here! The image dimension is [630 840 3].
Walter Roberson
on 1 Sep 2022
It looks to me as if that image might have a white frame around it. Try setting the axes color to something distinctive. For example,
set(gca, 'color', 'r')
and see if the white still shows up.
Bjorn Gustavsson
on 1 Sep 2022
I guess that the white frame are full of nan's (or at least has a very distinct value relative to the rest of the image), then when you filter the image the nan-region might start to expand into the central part of the image (or if distinct values this will lead to very pronounced sharp gradients - they should remain in place, so I guess it is a nan-problem).
Jay Ghosh
on 3 Sep 2022
Edited: Jay Ghosh
on 3 Sep 2022
Bjorn, I started over just to make sure that I am doing everything correctly and the dimensions are correct. So, now I have the rgb input image of dimenion [630 840 3], which is called '090222-Anomaly_NE_Pacific.png' (attached above).
After converting it to grayscale mage, dimension become [630 840].
Next, I checked for NaN values, and there is none. If I do not have any NaNs, then why do I still get this yellow/white region, when I run cedif? I am not sure.
My code is attached below:
close all
clear all
%% CEDIF: Coherence enhancing diffusion
%% Read image file
img = rgb2gray(imread('090222-Anomaly_NE_Pacific.png'));
sz = size(img);
any(isnan(img(:)));
% Set parameters (NE Pacific) [see parameter descriptions under cedifdemo]
lambda = 10; sigma = 1.2; rho = 2; m = 10; stepsize = .5; steps = 10;
img_cedif = cedif(img, lambda, sigma, rho, m, stepsize, steps, 1, 5, ...
'dfstep',2, 'grad', 'struc','gamma',0.01); % 'imscale'
%% Convert doubles to uint8
img_cedif2 = uint8(255*mat2gray(img_cedif));
figure(22)
montage({img,img_cedif2},'ThumbnailSize',[1000,700])
title([' Original Image (Left) | ' ...
'CEDIF: Coherence Enhanced Diffusion (Right)'])
Walter Roberson
on 3 Sep 2022
Jay, my apologies, but I just accidentally removed one of the images from https://www.mathworks.com/matlabcentral/answers/1775235-anisotropic-diffusion-for-a-fingerprint-image-resolution-issues#comment_2336765 😩
Jay Ghosh
on 5 Sep 2022
Edited: Jay Ghosh
on 5 Sep 2022
Here are 2 histogram plots (attached below).
First is for the orignal xyz data (double). And, the second one is for the (png) image data (uint8) that was saved from xyz imagesc display (090222-Anomaly_NE_Pacific.png). Just thinking it loud, and wondering if this difference in hostogram plots gives any clue as to why 'cedif' (derivative) results in zero value patches.
Walter Roberson
on 5 Sep 2022
The png has a white frame.
Do not use imagesc() followed by getframe followed by imwrite, or the equivalent imagesc followed by saveas or print or exportgraphics
Instead use rescale() on the data, and imwrite() the results. This will avoid writing any frame.
Jay Ghosh
on 5 Sep 2022
Yes Walter, I just realized that when I am saving it as .png from imagesc, it is adding a white frame, and therefore diemnsion increases from (421,709) to (630,840).
I just removed the white space from the png file. However, I have been looking to save it differently altogether and not have the white frame saved in the first place at all. I was about to update my progress is when I saw your comment! Thank you:) I will update here when I get further progress.
Jay Ghosh
on 5 Sep 2022
Edited: Jay Ghosh
on 5 Sep 2022
Walter, could you please elaborate on how I could save an rgb image, from xyz data (double), without using imagesc where the original diemnsion (421,709) is preserved as well? The xyz data ranges from -1000 to 1500.
You said that I could use rescale() and then imwrite(). I tried the following, but it gives me a black and white (one channel) image.
close all
clear all
data = load('EPR_12N_mag.xyz'); % data = [long, lat, mag]
x = data(:,1); % [-106.9500 -101.0500] long range
y = data(:,2); % [12 16] lat range
z = data(:,3); % [-1073 1529.7] nT anomaly range
[ux, indx] = unique(x);
[uy, indy] = unique(y);
zm = reshape(z,709,421);
zm = fliplr(zm);
imwrite(rescale(flipud(zm'),1,255),'test2.png');
May be it's simple but I am not sure how to do this. Thank you.
Walter Roberson
on 6 Sep 2022
rescale with InputMin -1000 InputMax 1500. Let it scale to the default range 0 to 1. imwrite will see that it is floating point and will automatically im2uint8 internally and write out the 8 bit image.
Bjorn Gustavsson
on 6 Sep 2022
@Jay Ghosh, also do your analysis on the data, save the analysis results in a suitable file-format (I tend to favour .mat, but there are valid reasons to chose other formats). Print/save your illustrations to some image format (.png, .eps etc) for use as illustrations. Using image-formats (except .fits) as data-storage is not a great idea.
Jay Ghosh
on 7 Sep 2022
@Walter Roberson, Something like this?
imwrite(rescale(flipud(zm),-1000,1500),'test2.png');
This gives me a black and white image.
Walter Roberson
on 7 Sep 2022
imwrite(rescale(flipud(zm), 'InputMin', -1000, 'InputMax', 1500),'test2.png');
Jay Ghosh
on 25 Jun 2023
Edited: Jay Ghosh
on 25 Jun 2023
@Bjorn Gustavsson, I have been finally able to get back to running difusion for part of my research. Now, I have been running diffusion on original data, instead of on an image file (your advise was to do the analysis on the data).
The functions I have been using are 'cedif' and 'CorerenceFilter' (both from file exchange). For both the functions, I have noticed that the diffusion results are not the same as it was for an image file (0-255) as an input. For original data (range:(-290,273)) as an input, I have to run much longer diffusion timesteps to get similar results, but also diffusion output just does not look as sharp (in terms of preserving edges) as it did before. For an input image file, for 'CoherenceFilter', only a timestep of 20 (T=20) produced some good diffusion output, however, for input data (-290,273), it requres more timesteps to see detectable diffusion, and results are a lot more blurry than it was for an image input.
I was wondering if it has anything to do with the fact that data file has negative values (w/ mean being close to zero), and/or the fact that data file has longer range (-290,273) compared to an image file (0-255). The function description, for both cedif and CoherenceFilter says that input is an image file.
Would you have any thoughts on this? Thank you very much!
More Answers (0)
See Also
Categories
Find more on Image Data in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!An Error Occurred
Unable to complete the action because of changes made to the page. Reload the page to see its updated state.
Select a Web Site
Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .
You can also select a web site from the following list
How to Get Best Site Performance
Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.
Americas
- América Latina (Español)
- Canada (English)
- United States (English)
Europe
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom(English)
Asia Pacific
- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)