How to exclude the surrounding empty space when Smoothing?

1,550 views
Skip to first unread message

MTEXNewbie

unread,
Aug 1, 2017, 7:19:56 AM8/1/17
to MTEX
I have an EBSD map of a wire that has empty spaces top and bottom. This space gets filled when I use -

F = splineFilter;
ebsd_smoothed = smooth(ebsd('indexed'),F,'fill',grains);

I would like to fill the not-indexed space inside my phases (grains), not the real empty space or voids.

How do I do that?

Thanks.

Rüdiger Kilian

unread,
Aug 1, 2017, 7:36:03 AM8/1/17
to mtex...@googlegroups.com
Filling works on points which are not in the list of phases, in contrast to points which have the phase nonindexed. So a possible procedure would be to use a map which only consists indexed and nonindexed phases. You can then delete certain points (based on whatever condition works for your voids etc.) from the ebsd list and those are the one that will be filled later on: ebsd(condition)=[];
In your case I guess a suitable condition could be e.g. phase and grain size (single, non-indexed pixels?), being an inclusion within a grain of indexed phase, having no boundary towards the map boundary etc. that's all pretty flexible.
Note that the spline filter might actually be a little "rough" on your data, depending what you'll have in mind doing with it.
I hope this helps,
Cheers, rüdiger

MTEXNewbie

unread,
Aug 1, 2017, 7:50:27 AM8/1/17
to MTEX
I am actually pretty new to this, below is the snippet that I am using. Could you please suggest the appropriate edits?
 
%% Import the Data

% create an EBSD variable containing the data
ebsd = loadEBSD(fname,CS,'interface','crc',...
  'convertSpatial2EulerReferenceFrame');

% take only those measurements with MAD smaller than one
ebsd_corrected = ebsd(ebsd.mad<1)

% Smooth and Fill
F = splineFilter;
ebsd_smoothed = smooth(ebsd_corrected('indexed'),F,'fill');

plot(ebsd_smoothed({'Iron fcc','Iron bcc (old)'}))

ruediger Kilian

unread,
Aug 1, 2017, 2:00:59 PM8/1/17
to mtex...@googlegroups.com
Hi,
you probably need to calculate grains, otherwise it is not possible to clean up data based e.g. on grain size or inclusions etc.

In general,
to delete a point from the list :
ebsd(condition)=[]
to set a point to nonIndexed phase:
ebsd(condition).phase=0;

For example in your case, you decide to filter by mad, but instead of deleting the points it might be more practical at first to set them to nonIndexed:
e.g. ebsd(ebsd.mad<1).phase=0;

Similarly you can construct conditions based on grains properties,for example:

delete ebsd points associated with small, nonIndexed grains
ebsd(grains(grains.grainSize<4 & grains.phase==0))
or
ebsd(grains(grains.grainSize<4 ,'n'))

delete ebsd of grains that are inclusion, and nonIndexed
inclusions = grains(checkInside(grains('indexed'), grains))
ebsd(inclusions( 'n’))=[]

or delete ebsd of grains that are inclusion, smaller 10 points and nonIndexed
ebsd(inclusions(inclusions.grainSize<10, 'n’))=[];

There are of course many more possibilities but the procedure will depend on the specific problem, there’s almost no universal recipe.

With respect to filtering, have a look at the documentation.

Hope this helps.
Cheers,
Rüdiger


MTEXNewbie

unread,
Aug 5, 2017, 11:26:07 AM8/5/17
to MTEX

Hi Rüdiger,

I think I am getting a hang of it, by following your suggestion.

However, how do I remove the small phases outside of the wire boundary?


MTEXNewbie

unread,
Aug 7, 2017, 7:45:44 AM8/7/17
to mtex...@googlegroups.com
Can anybody please help me to resolve this problem of excluding empty regions from MTEX calculation?

This is a metal wire and the EBSD image has some empty spaces (resin) above and below the wire (see the 1st picture), and it also has some holes in it.
I need to exclude these regions from MTEX calculations. Otherwise, MTEX is calculating Grain Boundaries on those empty spaces (see the 2nd picture).

Please help!!!

Band Contrast:

[removed]


Orientation Map with Grain Boundary Overlay:

[removed]



ruediger Kilian

unread,
Aug 7, 2017, 7:55:40 AM8/7/17
to mtex...@googlegroups.com
Hi,
have a look at my previous reply. It appears, you are actually deleting those non-indexed points (usually the crc comes with the nonIndexed phase). Thats what makes mtex try top make grain boundaries in areas it doesn’t know about. Best thing would be not to delete the nonIndexed phase. Alternatively there’s the option ‘unitCell’ for calcGrains.
Cheers,
Rüdiger


MTEXNewbie

unread,
Aug 7, 2017, 8:32:00 AM8/7/17
to mtex...@googlegroups.com, ruedige...@unibas.ch
Hi Rüdiger,

Below is the Orientation Map with Grain Boundary Overlay plot with non-indexed points, It is nearly the same.

[removed]

but I have success using the 'unitcell' command as below (also deleted the non-index points) -
[grains,ebsd.grainId] = calcGrains(ebsd('indexed'),'unitcell');

[removed]

Thank you for your continuing help. How do I remove the small grains on top and bottom of the wire, any tricks?

Luiz F. G. Morales

unread,
Aug 7, 2017, 10:12:38 AM8/7/17
to mtex...@googlegroups.com
what about

min_points = 10;
grains = grains(grains.grainSize > min_points)


after you calculate your grains???



best



Luiz




MTEXNewbie

unread,
Aug 7, 2017, 2:03:58 PM8/7/17
to MTEX
Hi Luis,

That was actually quite good to reduce some small grains. However, I still have those dots top and bottom when plotting phase map.

Luiz F. G. Morales

unread,
Aug 8, 2017, 1:59:50 AM8/8/17
to mtex...@googlegroups.com
You can try to increase slighly the number of points per grain to remove more, but you may also remove grains within the wire.

Maybe this:


outerBoundary_id = any(grains.boundary.grainId==0,2);
plot(grains)
hold on
plot(grains.boundary(outerBoundary_id),'linecolor','red','linewidth',2)
hold off
grain_id = grains.boundary(outerBoundary_id).grainId;
grain_id(grain_id==0) = [];
plot(grains(grain_id))
grains(grain_id) = []
plot(grains)


Not sure if this will work, just try, you may also find help here:

http://mtex-toolbox.github.io/files/doc/GrainStatistics.html


Best


Luiz



On 7. Aug 2017, at 20:03, MTEXNewbie <rashed...@gmail.com> wrote:

Hi Luis,

That was actually quite good to reduce some small grains. However, I still have those dots top and bottom when plotting phase map.

--
If you want to reduce the number of emails you get through this forum login to https://groups.google.com/forum/?fromgroups=#!forum/mtexmail, click "My membership" and select "Don't send me email updates". You can still get emails on selected topics by staring them.
---
You received this message because you are subscribed to the Google Groups "MTEX" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mtexmail+u...@googlegroups.com.
Visit this group at https://groups.google.com/group/mtexmail.
For more options, visit https://groups.google.com/d/optout.

ETH Zürich
Luiz F. G. Morales
Scientific Center for Optical and Electron Microscopy (ScopeM)
HPT D 9
Auguste-Piccard-Hof 1
8093 Zurich, Switzerland
Phone +41 44 633 37 46
E-mail: luiz.m...@scopem.ethz.ch
URL: www.scopem.ethz.ch
URL: https://sites.google.com/site/luizfgmorales/
Skype: lfgmorales




MTEXNewbie

unread,
Aug 19, 2017, 9:23:58 AM8/19/17
to MTEX, lu...@ethz.ch
Hi Luiz,

Increasing the number of points per grain slightly to remove them is causing a problem.

Your second approach looks interesting, could you please comment out about what is happening line-by-line?

sauer.k...@gmail.com

unread,
Mar 12, 2018, 5:02:13 PM3/12/18
to MTEX
This might be far too late to help you, but just in case - one thing that may help you is removing poorly constrained grains (ie the grains Mtex thinks you have using the points outside of the wire). Note this approach is done after defining grains.

Here is what I use:

%set stepsize for your map
stepsize = .5;

% Find decimal fraction of each grain consisting of indexed pixels
fraction = (grains.grainSize.*(stepsize^2))./grains.area;

% Plot grains coloured by indexed fraction
figure
plot(grains,fraction) % Red = well constrained; blue = poorly constrained
mtexColorbar

% Plot tradeoff curve
figure
plot(1:length(grains),sort(fraction)*100,'linewidth',2)
xlabel('Number of grains')
ylabel('Indexed fraction (%)')

cutoff = 0.50; % Cutoff (knee in tradeoff curve) - as decimal fraction; Change this to whatever value works for your data

hold on
line([0 length(grains)],[cutoff cutoff]*100,'color','r')  %this plots a line in the tradeoff curve with the cutoff you've chosen

% Restrict grains - just the well constrained ones
grains = grains(fraction > cutoff);


After doing this I also follow Luiz's earlier suggestion to remove small grains. Hope this might help.

Kat









On Tuesday, August 8, 2017 at 12:32:00 AM UTC+12, MTEXNewbie wrote:
Hi Rüdiger,

Below is the Orientation Map with Grain Boundary Overlay plot with non-indexed points, It is nearly the same.




but I have success using the 'unitcell' command as below (also deleted the non-index points) -
[grains,ebsd.grainId] = calcGrains(ebsd('indexed'),'unitcell');


MTEXNewbie

unread,
Mar 13, 2018, 1:09:14 PM3/13/18
to MTEX
Hi Kat,

Thank you for the code, I am yet to solve this problem so your code seems really interesting.

%set stepsize for your map
stepsize = .5; 

The step size is the one used during EBSD image acquisition or just any reasonable value (smaller = better)?

Katrina Sauer

unread,
Mar 13, 2018, 4:00:59 PM3/13/18
to mtex...@googlegroups.com

Hi,

 

Yes, the step size is the one you use during acquisition of the EBSD. If you accidentally forget to change it and it’s wrong, the tradeoff curve scale will not have y values from 0-1 – so it’s a good double check!

 

Cheers

Kat

--

If you want to reduce the number of emails you get through this forum login to https://groups.google.com/forum/?fromgroups=#!forum/mtexmail, click "My membership" and select "Don't send me email updates". You can still get emails on selected topics by staring them.
---

You received this message because you are subscribed to a topic in the Google Groups "MTEX" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/mtexmail/fOrMd92tIJk/unsubscribe.
To unsubscribe from this group and all its topics, send an email to mtexmail+u...@googlegroups.com.

MTEXNewbie

unread,
Mar 13, 2018, 4:05:19 PM3/13/18
to MTEX
Thanks for confirming.

Could you please point me to some resources that explains your algorithm? It's kind of working and I would like to know more about it, especially the trade-off curve and the value at knee.

Dripta Dutta

unread,
May 3, 2018, 1:58:49 AM5/3/18
to MTEX
Dear Dr. Kilian,

I was trying to smoothen the interiors of the grains and fill them at the same time. Although the boundaries of the grains can be recognized pretty well, but the moment I'm trying to 'fill' them I'm getting a rather absurd plot. Here's the code:

ebsd = ebsd(ebsd.ci>0.1);

plot(ebsd('Quartz'),ebsd('Quartz').orientations); % the plot thus obtained is attached (Image 1.jpg)


[grains,ebsd.grainId] = calcGrains(ebsd('indexed'),'unitcell');

ebsd_new=ebsd(grains(grains.grainSize>20 & grains.phase==0));

[grains_new,ebsd_new.grainId] = calcGrains(ebsd_new('indexed'),'unitcell');

plot(ebsd_new('Quartz'),ebsd_new('Quartz').orientations);

hold on

plot(grains_new.boundary); % plot thus obtained is attached (Image 2.jpg)


F=splineFilter;

ebsd_smooth=smooth(ebsd_new('indexed'),F,'fill');

plot(ebsd_smooth('Quartz'),ebsd_smooth('Quartz').orientations); % this step produces Image 3.jpg (attached)


Could you please let me know, where am I going wrong? I want to fill the interior of the grains and the space between the larger grains, but not the space surrounding them.

Image 1.jpg
Image 2.jpg
Image 3.jpg

Rüdiger Kilian

unread,
May 3, 2018, 4:55:42 AM5/3/18
to mtex...@googlegroups.com
Hi Dripta
in your first line 'ebsd = ebsd(ebsd.ci>0.1);' you basically delete a lot of points and all these points are those that will be filled later on, hence your rather funny result.

You could start with figuring out which 'bad' points are inside larger grains (and those are the points you can delete) and which grains are e.g. one pixel grains, outside, which you can set to the nonIndexed phase.

So, maybe try to do calcGrains first, then set all grains of grains size < 2 to nonIndexed, and follow up and make yourself familiar with checkInside (help grain2d/checkinside) and delete all "inclusions" in your large grains which can then fill. Alternative, it might also be work to use your ci-condition then.

Hope this helps,
Rüdiger




Dripta Dutta

unread,
May 5, 2018, 3:45:45 AM5/5/18
to MTEX
Dear Dr. Kilian,

I figured out that almost all the grains outside the larger grains have a grain-size below 20. Hence, to set them as non-indexed phases I used the code

ebsd(grains(grains.grainSize<20)).phase=0;

However, when I try to plot the ebsd for only the indexed points using: plot(ebsd('indexed'),ebsd('indexed').orientations);

I get an image wherein the outside grains were still included !! (Image_1.jpg). I also tried to detect and delete the inclusions within the larger grains using the following commands:

inclusions=checkInside(grains(grains.grainSize>20),grains);
ebsd(inclusions('n'))=[];

But I guess, I'm going wrong somewhere. Since plot doesn't change much. I don't think the inclusions are getting detected or deleted at all.
Image_1.jpg

Dripta Dutta

unread,
May 5, 2018, 5:34:57 AM5/5/18
to MTEX
Thanks a lot, Dr. Kilian for the help.

I finally managed to figure out the glitch and rectified the same to obtain the result I was expecting (figure attached).


On Thursday, May 3, 2018 at 2:25:42 PM UTC+5:30, Rüdiger Kilian wrote:
Final Image.jpg

Dripta Dutta

unread,
May 7, 2018, 1:09:54 AM5/7/18
to MTEX
Dear Dr. Kilian,

I'm really sorry for the repeated queries, but I'm stuck at another problem.

Even after smoothing the EBSD data, there remain few data points inside larger grains that have confidence indices lower than 0.1. I tried deleting them as well (before smoothing) but without sucess. Here's what I did:

1. I set those points to nonIndexed: ebsd(ebsd.ci<=0.1).phase=0;

2. Tried to delete the nonIndexed inclusions from larger grains (hoping that the nonIndexed data points from step 1 will get deleted as well):

inclusions=grains(checkInside(grains(grains.grainSize>20),grains));

ebsd(inclusions('n'))=[];


Didn't help.


I tried this code as well:


ebsd_CI=ebsd(checkInside(grains(grains.grainSize>20),ebsd));---- the program gets kind of freezed once this line is enountered

ebsd(ebsd_CI<=0.1)=[]; 


No success still. I am unable construct the correct code to delete only those nonIndexed data points, which are present inside larger grains. I would really appreciate if you could help me out here.


On Thursday, May 3, 2018 at 2:25:42 PM UTC+5:30, Rüdiger Kilian wrote:

Rüdiger Kilian

unread,
May 7, 2018, 3:47:43 AM5/7/18
to mtex...@googlegroups.com
Hi Dripta,
maybe the example below helps (just set you whatever condition you use instead of mad).

With regard to using the confidence index to discriminate "bad" pixels":
Have you actually checked whether grains with a low CI are actually badly oriented?


mtexdata twins

% set points to 'n' based on some property
ebsd(ebsd.mad>=1.5).phase=0
% calc grains
[grains,ebsd.grainId]=calcGrains(ebsd)
% check if inclusion
is_incl = sum(checkInside(grains,grains),2);
% delete pixels of a) inclusions and b) smaller some size
ebsd(grains(is_incl & grains.grainSize<10))=[];
% delete all nonIndexed pixels smaller some size
ebsd(grains(grains.grainSize<10),'n')=[];
% anything else ...

% recalc grains
[grains,ebsd.grainId]=calcGrains(ebsd)
% some filter for denoising
 f=halfQuadraticFilter;
 f.threshold=1*degree; f.alpha=[0.05 0.05];
ebsdf = smooth(ebsd,f,'fill')


[grainsf,ebsdf.grainId]=calcGrains(ebsdf)
plot(ebsdf('m'))
hold on
plot(ebsdf('n'),'FaceColor',[0.1 0.1 0.4])
plot(ebsd('m'),'FaceColor',[0.8 0.1 0.9],'FaceAlpha',0.3)
plot(ebsd('n'),'FaceColor',[0.3 0.6 0.1],'FaceAlpha',0.1)
plot(grainsf.boundary)
hold off


Cheers,
Rüdiger

Dripta Dutta

unread,
May 7, 2018, 7:32:01 AM5/7/18
to MTEX
Dear Dr. Kilian,

I'm afraid, I don't really know how to check if the grains with low CI are badly oriented or not. 

Is it that smoothing of the EBSD regenerates pixels of low CI? If so, is it possible to smooth the EBSD such that a pixel is smoothened using the CI of neighboring pixels?

I ran the following code (didn't get the desired output though):

% to set all pixels with confidence indices<0.1 to non-Indexed
ebsd(ebsd.ci<=0.1).phase=0;

[grains,ebsd.grainId] = calcGrains(ebsd);

% check for inclusions inside larger grains
is_incl = sum(checkInside(grains(grains.grainSize>20),grains),2);

% to set the smaller grains as non-Indexed
ebsd(grains(grains.grainSize<10)).phase=0; 

% delete the inclusions and non-Indexed grains (does it delete the non-Indexed grains inside the larger grains?)
ebsd(grains(is_incl & 'n'))=[]; 

[grains,ebsd.grainId] = calcGrains(ebsd);

F=splineFilter;

ebsd_sm=smooth(ebsd,F,'fill');

[grains_sm,ebsd_sm.grainId] = calcGrains(ebsd_sm);


% to delete the smaller and non-Indexed grains surrounding the larger ones

ebsd_sm(grains_sm(grains_sm.grainSize<10,'n'))=[];



ruediger Kilian

unread,
May 7, 2018, 7:46:24 AM5/7/18
to mtex...@googlegroups.com
Hi Dripta,

when you interpolate your map and fill pixels only orientations will be generated, but since mtex cannot know what other property (ci, bc,mad....) the filled pixels should have, no value will be assigned.
To see minor orientation differences, you can use a mis2mean (about at end of this page: http://mtex-toolbox.github.io/files/doc/EBSDSmoothing.html )

Maybe you could elaborate what you mean with desired output and what didn't work?

Also, try to plot grains/ebsd after each step you do, so you can figure where undesired things start to happen.

Cheers,
Rüdiger

Dripta Dutta

unread,
May 7, 2018, 8:38:27 AM5/7/18
to MTEX
Dear Dr. Kilian,

I mean to say, that there are still pixels/grains inside larger grains (after smoothing) that have CI lower than 0.1. I have attached the images.

Image 1 presents the output after smoothing. However, once I delete the low CI pixels (from the smoothened EBSD) and replot the map, I get Image 2.

The white spaces/points within the larger grains (in Image 2) are the ones I want to remove before smoothing the EBSD.
Image_1.jpg
Image_2.jpg

ruediger Kilian

unread,
May 7, 2018, 9:00:21 AM5/7/18
to mtex...@googlegroups.com
Just set them as nonIndexed to beging with, as I in the previous example (just used mad because there's no ci in the example dataset) and calc grains. They can then be discriminated as grains being included in the indexed phase of a certain size.

Cheers,
Rüdiger

signature.asc
Reply all
Reply to author
Forward
0 new messages