Hi,
A while back, I asked if there was any way I could convert an axis into an image matrix. I was pointed to export_fig, which while certainly is functional takes a while for each image you export. The program I am running converts 90 figures into matrices, so you can see how this time adds up. Additionally, I will need to use the same program for a much larger dataset soon, so I'd really like to increase the program efficiency if I can. Essentially, I have several shapes stored in a .mat file which must be converted into an image matrix of 1's (area of a shape) and 0's (area of nothing).
My current process is as follows:
  1. Create a current axis of the same dimensions as the final image.
  2. Draw a solid black image to the current axis.
  3. Load each shape to the workspace and draw on the current axis (on top of the black).
  4. Export the current figure with export_fig into an image matrix.
  5. Sum the resulting image matrix (so that you have a 2D matrix instead of a 3D/RGB matrix)
  6. Divide the image matrix by itself so that all 0's remain 0 but all non-zero values are converted to 1.
I wanted to reclarify my initial question and see if anyone else had additional ideas. I need a tool/method that:
  1. Draws several shapes on an axis which are stored from a .mat file.
  2. Creates a matrix of zeros of the same dimensions (e.g., a 1600 x 900 axis would become imgMatrix = zeros(900,1600))
  3. For every pixel with color, the corresponding location in the matrix becomes a 1 (e.g., if 1400,700 falls within a shape then imgMatrix(700,1400) = 1)
To sum, I start with nothing but several shapes stored in a .mat file. I need to end up with a matrix which contains those shapes "drawn" onto the matrix where 1's represent area covered by the shape and 0's represent area outside of the shapes.

댓글 수: 8

Jon
Jon 2019년 8월 27일
편집: Jon 2019년 8월 27일
From my initial reading of your problem description it does not seem like you ever need to draw the shapes to an axis. I think you should be able to directly construct your "image matrix" just using MATLAB matrix operations. If this is the case, then you do not have to worry about how to export figures more quickly, you can just focus on doing your matrix manipulations efficiently. How are the shapes currently defined?
I am loading them from a .mat file that stores them as ellipse objects. Each .mat file holds five 2x1 cell arrays (1 for each type). The ellipse is stored in the second cell of each array. Here is one example:
Ellipse with properties:
Center: [128.4203 74.8443]
SemiAxes: [52.8749 35.0957]
RotationAngle: 300.6852
AspectRatio: 1.5066
Label: ''
Show all properties
I've attached one .mat file for example if you want to take a closer look.
What matrix operations could I use to do this?
Jon
Jon 2019년 8월 27일
편집: Jon 2019년 8월 27일
Before I saw your comment indicating that you had ellipse objects I made the attached example that shows how you could do it with polygons. Probably a similar approach could be adapted for ellipses. Maybe this will give you a starting point.
% provide matrix dimension
m = 900;
n = 1600;
% define a few shapes as polygons
% x coordinates are column numbers in image matrix
% y coordinates are row numbers in image matrix
shape(1) = polyshape([300 400 600],[200,800,300]) % triangle
shape(2) = polyshape([100 800 800 100],[700 830 1030 900]) % parallelogram
% initialize image matrix
imgMatrix = zeros(m,n);
% make a vector with all of the "x" value coordinates (column numbers)
% and a vector with all of the corresponding "y" value (row numbers)
[y,x] = ind2sub([m,n],1:m*n);
% loop through shapes setting elements of image matrix inside of each shape to true
for k = 1:length(shape)
inside = isinterior(shape(k),y,x);
imgMatrix(inside) = 1;
end
% display the image matrix
imshow(imgMatrix)
I don't have the image processing toolbox so I can't load your .mat file.
Maybe there is a better approach, but one way (extending what I have outlined above) would be to 1) make a function (or find one on the Matlab File Exchange) that could provide the vertices of your elipse approximated as a polygon, and 2) then use the above approach. Note I don't think that the vertices will need to be integers (exact column and row coordinates) as in my simple example for this to work.
Nice, I had no idea those functions existed.
Unfortunately I'm getting an error when I try to use isinterior on an ellipse:
Undefined function 'isinterior' for input arguments of type 'images.roi.Ellipse'.
Error in build_kernel_map (line 15)
inside = isinterior(shapes(i),y,x);
Can I fix this? I've noticed ellipses are quite finicky in Matlab with many of the shape-related functions. If not, any other ideas? I like the concept of matrix operations much more than using my current setup.
Walter Roberson
Walter Roberson 2019년 8월 27일
isinterior() was introduced in R2017b; which release are you using?
Joseph Henry
Joseph Henry 2019년 8월 27일
편집: Joseph Henry 2019년 8월 27일
I am using R2019a.
>> which isinterior
C:\Program Files\MATLAB\R2019a\toolbox\matlab\polyfun\@polyshape\isinterior.m % polyshape method
Sorry, how would I use the ellipse formula to help my problem?
Walter Roberson
Walter Roberson 2019년 8월 27일
Image Analyst's demo creates rotate ellipses from points and lines joining them. The coordinates of those lines can be put into the insertShape() function of Computer Vision Toolbox, to draw ellipses into a matrix.

댓글을 달려면 로그인하십시오.

 채택된 답변

Jon
Jon 2019년 8월 28일
편집: Jon 2019년 8월 28일

0 개 추천

Improving somewhat on my earlier comment you could do something like this
% provide matrix dimension
m = 900;
n = 1600;
% define a few ellipses
% x coordinates are column numbers in image matrix
% y coordinates are row numbers in image matrix
ellipse(1).xf = [300 400];
ellipse(1).yf = [350 500];
ellipse(1).a = 200;
ellipse(2).xf = [500 800];
ellipse(2).yf = [700 100];
ellipse(2).a = 400;
% initialize image matrix
imgMatrix = zeros(m,n);
% make a vector with all of the "x" value coordinates (column numbers)
% and a vector with all of the corresponding "y" value (row numbers)
[y,x] = ind2sub([m,n],1:m*n);
% loop through shapes setting elements of image matrix inside of each shape to true
for k = 1:length(ellipse)
inside = inEllipse(ellipse(k).xf,ellipse(k).yf,ellipse(k).a,x,y);
imgMatrix(inside) = 1;
end
% display the image matrix
imshow(imgMatrix)
where I have made the inEllipse function
function tf = inEllipse(xf,yf,a,xq,yq)
%INELLIPSE determine if query points are inside of specified ellipse
% tf = inEllipse(xf,yf,a,xq,yq) returns a vector of ones and zeros
% corresponding to the query points xq,yq with tf(i) = 1 when xq(i),yq(i)
% is in the interior of an ellipse with focus points xf(1),yf(1) and
% xf(2),yf(2) where the sum of the distances to any point on the ellipse to
% the two foci equals 2a
%
% find distances from query points to foci
d = sqrt([(xf(1) - xq(:)).^2 + (yf(1) - yq(:)).^2,...
(xf(2) - xq(:)).^2 + (yf(2) - yq(:)).^2]);
% determine if sum of distances is less than 2*a
tf = sum(d,2) <= 2*a;
You will have to do a little more work to get the foci and and value of a used in my definition of an ellipse from the properties of your ellipse, center, semiaxes etc. I just wanted a straightforward definition of an ellipse to illustrate the idea.

댓글 수: 4

Jon
Jon 2019년 8월 28일
편집: Jon 2019년 8월 28일
Actually if you haven't done it already, I think this will allow you to work directly with ellipses defined by their major axes, minor axes, center and rotation
function tf = inEllipse2(a,b,c,theta,xq,yq)
%INELLIPSE2 determine if query points are inside of specified ellipse
% tf = inEllipse2(a,b,c,theta,xq,yq) returns a vector of ones and zeros
% corresponding to the query points xq,yq with tf(i) = 1 when xq(i),yq(i)
% is in the interior of an ellipse with major axis a, minor axis b, centered
% at c, rotated by an angle theta counter clockwise from the horizontal
%
% translate query points to coordinate centered on elipse
p = [xq(:)' - c(1); yq(:)' - c(2)]; % use (:)' to make sure x and y are in rows
% rotate query points by theta
p = [cos(theta) -sin(theta);sin(theta) cos(theta)]*p;
% check if points are inside of standard elipse
tf = p(1,:).^2/a^2 + p(2,:).^2/b^2 <= 1;
Here's an example using this function
% provide matrix dimension
m = 900;
n = 1600;
% define a few ellipses
% x coordinates are column numbers in image matrix
% y coordinates are row numbers in image matrix
ellipse(1).a = 200;
ellipse(1).b = 50;
ellipse(1).c = [250 125];
ellipse(1).theta = 30/360*2*pi;
ellipse(2).a = 400;
ellipse(2).b = 100;
ellipse(2).c = [1000,500];
ellipse(2).theta = 80/360*2*pi;
% initialize image matrix
imgMatrix = zeros(m,n);
% make a vector with all of the "x" value coordinates (column numbers)
% and a vector with all of the corresponding "y" value (row numbers)
[y,x] = ind2sub([m,n],1:m*n);
% loop through shapes setting elements of image matrix inside of each shape to true
for k = 1:length(ellipse)
inside = inEllipse2(ellipse(k).a,ellipse(k).b,ellipse(k).c,ellipse(k).theta,x,y);
imgMatrix(inside) = 1;
end
% display the image matrix
imshow(imgMatrix)
I find it somehow non-intuitive when working with matrices as images that the row numbers are the y coordinates and the column numbers are the x coordinates. For matrices it is conventional to list the indices as row,col but for coordinates it is conventional to list the coordinates as x,y.
Also a little strange that increasing positive y, (row numbers) goes vertically down rather than up.
I think in the end I got this right, but you should double check.
Joseph Henry
Joseph Henry 2019년 8월 28일
This works great! Thanks.
Also, for anyone else reading this if you need to go straight from an ellipse object to the above code, you need to convert your rotation angle (theta) to radians. Tripped me up for a bit, but eventually realized my err :)
Jon
Jon 2019년 8월 28일
Glad that this approach is working for you. Sorry you had some problems not realizing the rotation angle in my function was in radians. I was hoping you would see it in the example where I do the conversion, but I should have made it more explicit. I think for the most part MATLAB takes radian arguments to trig functions, but your output from the roi is in degrees so I guess you have to be careful.
Joseph Henry
Joseph Henry 2019년 8월 28일
No worries, I should have looked more carefully. All is well though, thank you again!

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

카테고리

도움말 센터File Exchange에서 Graphics Performance에 대해 자세히 알아보기

질문:

2019년 8월 27일

댓글:

2019년 8월 28일

Community Treasure Hunt

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

Start Hunting!

Translated by