matrix show , grain boundaries

how can i show a matrix like this photo with black line boundaries ?

2 Comments

What data you have? You need to have a look on voronoi.
If you're going to ask the same question three times, why do you provide even less information now?
Now I'm reluctant to even answer it if it's just going to get deleted. If all you have is an indexed image, apply edge finding techniques, combine the images. You can keep it indexed or convert it to RGB. Look up fspecial(), imfilter(), edge(), ind2rgb(), colormap(), imshow().

Sign in to comment.

 Accepted Answer

DGM
DGM on 5 May 2021
Edited: DGM on 6 May 2021
Your prior questions suggest that you already have an image to start with. A crude way to add lines to it is to just use edge finding methods. In this example, I'm just using an RGB image. You can do the same with an indexed image, but if you want it to display neatly with distinct colors, you'll have to figure out a colormap that does so (e.g. colorcube or a custom map).
inpict = imread('vdiag.png'); % this is rgb, uint8
emap = any(edgemap(inpict),3); % find edges
emap(:,[1:3 end-2:end]) = 1; % add border around image
emap([1:3 end-2:end],:) = 1;
% thin the edges and the dilate so it has uniform width
emap = imdilate(bwmorph(emap,'thin','Inf'),ones(3));
outpict = inpict.*uint8(~emap); % make edge regions zero
imshow(outpict) % show it
The function edgemap() is from MIMT:
If you don't want to use that, you can use any other method for edgefinding by gradient approximation. That can be done with fspecial+imfilter and some math, or you can use edge().
emap = zeros(size(inpict));
for c = 1:size(inpict,3)
emap(:,:,c) = edge(inpict(:,:,c),'sobel');
end
emap = any(emap,3);
Of course, that still requires IPT, where MIMT does not. If IPT is truly an issue, MIMT also has alternatives for imdilate() and bwmorph().

17 Comments

Adam Danz
Adam Danz on 6 May 2021
Edited: Adam Danz on 6 May 2021
This is why I like participating in this forum. I didn't know about several of those functions!
I couldn't run your code.
Care to elaborate on what you tried to do and what happened, or should I just guess?
If you're missing vdiag.png, then you can just use the copy I posted inline above (right click > view image). Save it and adjust the name accordingly.
If you're missing edgemap(), then use the link above.
If there's some other problem, you'll have to say what it is.
this is mu code:
clc;clear;close all
S=[ 5 5 5 6 6 6;
5 5 5 6 6 6;
5 5 6 6 6 6];
imwrite(uint8(S), 'image1.png');
inpict = imread('image1.png'); % this is rgb, uint8
emap = any(edgemap(inpict),3); % find edges
emap(:,[1:3 end-2:end]) = 1; % add border around image
emap([1:3 end-2:end],:) = 1;
% thin the edges and the dilate so it has uniform width
emap = imdilate(bwmorph(emap,'thin','Inf'),ones(3));
outpict = inpict.*uint8(~emap); % make edge regions zero
imshow(outpict) % show it
and then there is an error :
for the first image, should I make it by voronoie or writing a matrix ?
I assumed you already had an image derived from some operation like a voronoi mapping process. I just found a picture somewhere and used it as an example. I didn't generate it.
I attached the one I used.
what can I do for the error ?
DGM
DGM on 7 Jun 2021
Edited: DGM on 7 Jun 2021
I didn't see that comment. Give me a minute to track it down. I take it you don't have IPT?
EDIT: Auugh. Yeah. There's a bug in padarrayFB() that manifests in a couple modes when the image is smaller than the pad size. It'll take me a while to fix it and reassemble a new package. I'm just attaching a version of edgemap() which avoids the problem.
That said, I don't really know why you want to process a 3x6 image.
I sent a message to you. if you can send me an email I'll explain you accurately.
Not only do I normally not respond to forum posts via email, I haven't even had access to that email account for weeks. If you want to talk to about it, it'll have to be here.
I explianed in the attached file. if it's not understanable and clear, tell me
DGM, I sent you a zip file at previous comment.
there is an error.
what can I do ? I'm using R2020b
The MIMT zip file contains (or should contain) all the dependencies like ifversion(). It's possible that you added the MIMT directory to the path, but not its subdirectories. ifversion() is in MIMT/FEX_dependencies/ifversion_fex, so just check to make sure all those subdirectories are included on the path.
There's one other thing that might be causing issues, and that's trying to represent a small array with an equally small image. For the sake of being able to fit lines in between regions, the displayed image might need to be scaled up.
inpict = uint8([ 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1;
2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1;
2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1;
3 3 3 3 3 3 3 3 3 3 3 3 1 1 1 1 1;
3 3 3 3 3 3 3 3 5 5 5 5 5 5 5 5 5;
3 3 3 3 3 3 3 5 5 5 5 5 5 5 5 5 5;
5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5]);
% the image needs to be big enough that lines can exist between regions
inpict = imresize(inpict,25,'nearest'); % use 'nearest'
% could use this to get the edge map
%emap = any(edgemap(inpict),3);
% or this is the non-MIMT alternative i'd suggested
emap = zeros(size(inpict));
for c = 1:size(inpict,3)
emap(:,:,c) = edge(inpict(:,:,c),'sobel');
end
emap = any(emap,3);
emap(:,[1:3 end-2:end]) = 1;
emap([1:3 end-2:end],:) = 1;
emap = imdilate(bwmorph(emap,'thin','Inf'),ones(3));
inpict = ind2rgb(inpict,colorcube);
outpict = inpict.*(~emap);
If that imresize() line is omitted, you'd get this: (scaled up afterwards so it's visible in browser)
As for how to generate initial arrays for different curved-face polygons, that should probably be best asked as a separate question. I don't have any recommended/preferred approaches to that off the top of my head, but I wouldn't doubt that someone else does.
Thank you alot! It's great!
How can the color of the edges be changed? Be white line instead of black color.
Just change the last line to
outpict = inpict.*(~emap) + emap;
or for a specific color,
outpict = inpict.*(~emap) + permute([0.8 0.5 1],[1 3 2]).*emap;
There are 3 problems:
1- The size of small matrices changes
2- The matrix apparently becomes three-dimensional.
3- I want to use hot colormap so that from the least number to the most number of the matrix is shown with colors in the hot colormap range , i.e, number 1 with black color(hot colormap) and number 5 with white color and others between them base on colormap.
Are these problems solvable?
DGM
DGM on 11 Jun 2021
Edited: DGM on 11 Jun 2021
If there are to be lines drawn between regions, the size of small images must change, otherwise there's nowhere to put the lines. Consider the image [1 1; 2 2; 3 3]. You'd need 4 horizontal lines and 2 vertical lines. That's more pixels than there even are in the image. Even for slightly larger images, the minimal line width would still cover large portions of the regions and distort their apparent geometry.
The output matrix is RGB. That's why it's 3D. You could use a different colormap using ind2rgb() just the same:
% just incorporate the lines into the indexed image
inpict(emap) = max(inpict(:))+1;
inpict = inpict-1; % uint8 indexed images start at 0
% build a custom colormap from hot()
% adjust n as needed for other images
n = 100;
cmap = hot(double(max(inpict(:)))*n+1);
cmap = cmap(1:n:end,:)
outpict = ind2rgb(inpict,cmap);
or you could just leave inpict as an indexed image and have fun dealing with carrying around colormaps if you wanted.
imshow(inpict,cmap);

Sign in to comment.

More Answers (1)

Adam Danz
Adam Danz on 4 May 2021
Edited: Adam Danz on 5 May 2021
H Ghari > how can i show a matrix like this photo with black line boundaries ?
This should get you started:
rng default;
n = 100;
x = rand([1 n]);
y = rand([1 n]);
h = voronoi(x,y);
DT = delaunayTriangulation(x(:),y(:));
[V,R] = voronoiDiagram(DT);
verts = cell(size(R));
for i = 1:numel(R)
verts{i} = V(R{i}([1:end,1]),:);
end
hold on
axlims = [xlim; ylim]; % [xlim; ylim]
patchColors = hsv(numel(verts)+1);
for j = 1:numel(verts)
patch(verts{j}(:,1), verts{j}(:,2), patchColors(j,:))
end
delete(h)
set(gca,'color', patchColors(end,:)) % <-- kind of cheating
axis equal
xlim(axlims(1,:))
ylim(axlims(2,:))
Also see these two blog posts by Mike Garrity.
And the vononi2mask or the voronoizone functions on the file exchange (not tested).

13 Comments

I want to have a Matrix as an output. this picture represents a material microstructure. so I have to have a matrix to change it in the future.
Adam Danz
Adam Danz on 5 May 2021
Edited: Adam Danz on 5 May 2021
A matrix of what?
Your original question was "how can i show a matrix like this photo with black line boundaries ?" and that's exactly what I answered.
You need to describe the problem much more clearly so that no more time is spent answering a different question.
I'm assuming OP wants a raster copy of the figure. Normally, I just use export_fig
rastercopy = export_fig('-a4','-m2'); % set params accordingly
although I'm sure there are canonical ways of doing that.
#Mr Danz,
Can the average grain diameter and number of grains be determined to create a structure similar to the one you sent? For example, 20 grains with an average grain diameter of 30 microns by Voronoi.
(You asked about more detailed information about my work which I wrote in a PDF on this page)
Adam Danz
Adam Danz on 13 Jun 2021
Edited: Adam Danz on 13 Jun 2021
I don't know. If I had to solve this problem I'd look for literature on creating Voronoi diagrams with known average areas.
there is a problom in your code.
My answer starts with "This should get you started" and when the answer was written, my interpretation of your question was that you were trying to recreate an image similar to the one you shared but with black edge lines. The variable n must be larger for it to work (in my answer, n=100).
In my answer, there is a comment "kind of cheating". That line colors the background. You could remove that line but you won't have a square image.
You question has changed or has become more clear and I recommended above that you turn to the literature and read about Voronoi diagrams. When asking a question, it's very important that you clearly define the goal so you don't get answers to the wrong question.
OK, I think I have to ask again in another question with details. Thank you.
do you know how can we add hemicircles inside of this shape
  • What defines the size and orientation of the semicircles?
  • Are they specifically semicircles or are they just general circular/elliptical arcs?
  • Inside of which shape?
  • Is this in a raster image or in a diagram drawn in a figure?
I doubt that these details don't matter, so it would make sense to know them ahead of time.
Hi
Do you knoW hoW can I mesh this data for abaqus?
If you have any idea it would help me alot. I tried here delanuay triangulate but did not work
th = linspace( pi/3.4, -pi/2, 100);
R = 0.25; %or whatever radius you want
for i=0:0.2:1
for j=0:0.4:1
x = R*cos(th)+i ;
y = R*sin(th)+j ;
plot (x,y)
hold on
end
end
rng default
x= rand([1 50]);
y= rand([1 50]);
voronoi(x,y)
DT = delaunayTriangulation(x(:),y(:));
[V,R] = voronoiDiagram(DT);
verts = cell(size(R));
for i = 1:numel(R)
verts{i} = V(R{i}([1:end,1]),:);
end
xlim([0 1.3])
ylim([-0.2 1])
DGM
DGM on 5 Oct 2023
Edited: DGM on 5 Oct 2023
I suggest you open a new question for this.

Sign in to comment.

Asked:

HG
on 4 May 2021

Edited:

on 5 Oct 2023

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!