Are you able to count the number of pixels in a 3D plot?

I am trying to find a way to count the number of red pixels in my moving plot and I was only able to find the number of white pixels in only at an angle. Would it be possible to count the total number of red pixels in a 3D plot?
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
clear; % Erase all existing variables. Or clearvars if you want.
workspace; % Make sure the workspace panel is showing.
xlabel('My x label') % Axis Labels
ylabel('My y label')
zlabel('My z label')
view([-37.5 30]) % standard 3D View
scale = 0.5;
y = 1; % white percentage
%% range of results
d = 10; % Distance Between each point
nmesh = 3; % range
MagR = 0; % Magnetic Radius (MagR>nmesh = Strong, MagR<nmesh = weak, MagR = 0 = no Mag)
niter = 200; % no. of jumps
[X,Y,Z] = meshgrid((-nmesh+1):nmesh-1); % create mesh
X = X * d;
Y = Y * d;
Z = Z * d;
%% random direction for X,Y,Z directions
dx = normrnd(0,1,[(size(X,1))^3 niter]);
dy = normrnd(0,1,[(size(X,1))^3 niter]);
dz = normrnd(0,1,[(size(X,1))^3 niter]);
%% Magnetised particles
c0 = nmesh; % center of magnetic field
for i = 1:size(dx,1)
[ii,jj,kk] = ind2sub(size(X),i); % row and column of force
n = pdist2([ii jj kk],[c0 c0 c0]); % distance to point
if n < MagR % radius of magnetic force
dx(i,:) = -cumsum(dx(i,:)*0+(jj-c0)/n); % cosinus
dy(i,:) = -cumsum(dy(i,:)*0+(ii-c0)/n); % sinus
dz(i,:) = -cumsum(dz(i,:)*0+(kk-c0)/n);
end
end
cla
hold on
%% For Loop to plot
for i = 1:niter-1
X1 = X(:) + dx(:,i);
Y1 = Y(:) + dy(:,i);
Z1 = Z(:) + dz(:,i);
plot3([X(:) X(:)]'+[dx(:,i+1) dx(:,i)]', ...
[Y(:) Y(:)]'+[dy(:,i+1) dy(:,i)]',...
[Z(:) Z(:)]'+[dz(:,i+1) dz(:,i)]','.-r','MarkerSize',5,'LineWidth',1)
%p.MarkerSize = 10; % 6 is the default
%p.LineWidth = 1; % 0.5 is the default
pause(0.01)
%% percentage readings
Image = getframe();
K = sum(sum(rgb2gray(Image.cdata)==255));
percentageofwhite(y) = K/numel(rgb2gray(Image.cdata))*100;
delete(findall(gcf,'type','text'))
txt=text(0.0,0.95,sprintf('White Space = %0.3f%%',percentageofwhite(y)),'Units','normalized');
y=y+1;
%%
xlim([-2*d 2*d]) % Axis limitsg
ylim([-2*d 2*d])
zlim([-2*d 2*d])
end
hold off
rotate3d on

5 Comments

Pixels (Image)?? Is this?
red_area=100-%white_space
@ sui zhi lau
if you study the line no 50 and 51 from your code
you can calculate Red elements count.
Hi Kalyan and Mrutyunjaya,
Thanks so much for answering. The 'white percentage' counter does show the number of white pixels and i can just minus the difference to find the red but I was wondering that if i shift the view of the 3D plot, would the percentages change since Image = getframe() only takes the 2D picture and analyse it after? If it does, how am i supposed to find the exact number of red pixels?
plot3([X(:) X(:)]'+[dx(:,i+1) dx(:,i)]', ...
[Y(:) Y(:)]'+[dy(:,i+1) dy(:,i)]',...
[Z(:) Z(:)]'+[dz(:,i+1) dz(:,i)]','.-r','MarkerSize',5,'LineWidth',1)
According to this, you are drawing 125 pair red points in each iteration
hi Mrutyunjaya,
thank you for the fast repliy! how did you get that value and how would i be able to compared the red pixels compared to the total white percentage to get a percentage of it then?
Ash

Sign in to comment.

Answers (2)

Can you calculate the volume manually?
dv = [dx(:,i+1)-dx(:,i) dy(:,i+1)-dy(:,i) dz(:,i+1)-dz(:,i)];
V = V + pi*R*sqrt(sum(dv.^2,2)); % volume of all lines

9 Comments

Hi Darova,
Thank you again for the help. It does seem to work but how would I know the radius as I know the linewidth and plot size but how would i be able to convert the sizes to pixel numbers? And how would I be able to find the number of pixels for the whole plot?
Just to be sure: you want to calculate pixels or percentage (volume)? read/white = value?
Number of pixels differs, it depends on window size. Here is an example
f = figure(1);
plot([0 1 2],[0 1 1],'linew',2) % plot some data
set(f,'position', [200 100 500 400]) % set small window
axis equal
fr = getframe;
A1 = fr.cdata; % small image
set(f,'position', [200 100 600 500]) % set larger window
fr = getframe;
A2 = fr.cdata; % large image
blue = @(A) A(:,:,1) < 10 & A(:,:,2) < 10 & A(:,:,3) > 240;
white= @(A) sum(A,3) > 250*3;
% get colors from images
A1b = blue(A1);
A2b = blue(A2);
A1w = white(A1);
A2w = white(A2);
% check if colors are correct
figure
subplot(211)
imshowpair(A1b,A2b,'montage')
subplot(212)
imshowpair(A1w,A2w,'montage')
sum(A1b(:))/sum(A1w(:))
sum(A2b(:))/sum(A2w(:))
Result
ans =
0.0078
ans =
0.0065
As you see the data remain the same, window size changes only. But ratio of blue/white changes
So can you tell what are you trying to calculate?
Yes, I just wanted to compare the red and white pixels in terms of a ratio. So the comparison of red and white volume works as well. so red/white = value? -> can be either pixels or volume.
So the number of pixels does not matter.
I think it's You should define some linewidth (radius). Can't calculate ratio without this
I made a mistake in my first post
dv = cat(3,dx,dy,dz);
dv1 = pi*R*sqrt(sum(dv.^2,3)); % volume of each line
V = sum(dv1(:));
Yes i get that linewidth is the radius but i was wondering what values should i use for R when im unsure with the linewidth pixels. Or do i just use the properties given from plot3. And once i solve for the red volume, how do i find the white's volume?
White volume looks simple
white = 40*40*40 - red
Yes but what do i replace R with? For example i put my linewidth as 0.5, do i take my R as 0.5 ?

Sign in to comment.

@ sui zhi lau,
Outside Loop
totalData = 0;
whitePixData = 40*40*40;
Inside Loop
redPixData(y) = sum(sqrt(((dx(:,i+1) - dx(:,i)).^2) + ((dy(:,i+1) - dy(:,i)).^2) + ((dz(:,i+1) - dz(:,i)).^2)));
totalData = totalData + redPixData(y);
percentageofred(y) = (totalData/whitePixData)*100;
txt=text(0.0,0.95,sprintf('White Space = %0.3f%%',percentageofred(y)),'Units','normalized');

3 Comments

I tried this but I think the totalData does not reflect the values correctly as for example,
Gives me a red percentage of 1614%
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
clear; % Erase all existing variables. Or clearvars if you want.
workspace; % Make sure the workspace panel is showing.
xlabel('My x label') % Axis Labels
ylabel('My y label')
zlabel('My z label')
view([-37.5 30]) % standard 3D View
nmesh = 5;
niter = 100;
scale = 0.5;
y = 1;
totalData = 0;
%%
d = 3;
[X,Y,Z] = meshgrid(0:nmesh-1); % create mesh
X = X * d
Y = Y * d
Z = Z * d
whitePixData = (d*(nmesh-1))^3;
%%
dx = normrnd(0,1,[nmesh^3 niter]);
dy = normrnd(0,1,[nmesh^3 niter]);
dz = normrnd(0,1,[nmesh^3 niter]);
cla
%plot3(X(:),Y(:),Z(:),'ob') % plot starting points
hold on
%plot(X,Y,'k') % plot grid
%plot(X',Y','k')
for i = 1:niter-1
s=5;
%s = normrnd(45,1)
X1 = X(:) + dx(:,i);
Y1 = Y(:) + dy(:,i);
Z1 = Z(:) + dz(:,i);
q = quiver3(X1, Y1, Z1, dx(:,i+1)-dx(:,i), dy(:,i+1)-dy(:,i),dz(:,i+1)-dz(:,i),'r')
q.LineWidth = s;
q.ShowArrowHead = 'off';
%plot([X(:) X(:)]'+[dx(:,i+1) dx(:,i)]', ...
%[Y(:) Y(:)]'+[dy(:,i+1) dy(:,i)]','.-r')
pause(0.02)
%% percentage readings
redPixData(y) = sum(sqrt(((dx(:,i+1) - dx(:,i)).^2) + ((dy(:,i+1) - dy(:,i)).^2) + ((dz(:,i+1) - dz(:,i)).^2)));
totalData = totalData + redPixData(y);
percentageofred(y) = (totalData/whitePixData)*100;
delete(findall(gcf,'type','text'))
txt=text(0.0,0.95,sprintf('Red Percentage = %0.3f%%',percentageofred(y)),'Units','normalized');
y = y+1;
xlim([0 d*nmesh])
ylim([0 d*nmesh])
zlim([0 d*nmesh])
end
hold off
rotate3d on
because, we are not considering the elimination of overlapping area.
How would you consider with elimination of overlapping areas?

Sign in to comment.

Products

Asked:

on 5 May 2020

Commented:

on 7 May 2020

Community Treasure Hunt

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

Start Hunting!