Count black and white pixels on a image

34 views (last 30 days)
Hello,
I have this 800x800 image and i want to count the number of black and white pixels in it. To do so i have read the image and divide it (the matrix) in 200x200 cells. But now i am with a bit of dificulty in making a scipt that can count B&W pixels in each cell and returns the values, something like this:
Cell(1,1)--> Black_pix=100; white_pix=300 Cell(1,2)--> Black_pix=100; white_pix=300
I already figured it out how to count B&W pixels in the entire image to do so, i've written the following script:
xmax=800;
ymax=800;
Image = imread('3080.jpg');
BW = im2bw(Image);
BW1=double(BW);
White_pix=0;
Floc=0;
for j=1:(xmax)-1
for i=1:(ymax)-1
if BW1(i,j)==0
White_pix=White_pix+1;
else
Black_pix=Black_pix+1;
end
end
end
My problem is making this process for all of the cells created with "mat2cell" function. Any help would be appreciated!
Thanks
Fearing that my english was so bad that i didn't explain myself very well, i'm posting a small schematic of the paper sheet divided in smaller elements.
I need to have something like this:
Element 1 as 3000 black pixels and 4500 white pixels Element 2 as 4000 black pixels and 9800 white pixels ...
  2 Comments
Jan
Jan on 21 Jul 2011
I hate hate hate tinypic. I see the header line with the blue background. Then "Tags: Click and addtags..." and "<< Prev Next>>" buttons, which lead me to pictures of naked human. Then I get some Tools on the left bottom and some elemnts under "Grab your code". The "Images You'll also enjoy" are hilarious. I'd only enjoy to see, what Nuno wants to show. And there is absolutely nothing.
@Nuno: How is it possible, that a 200x200 block of a BW image contains 3000 black and 4500 white pixels?! Then sum must be 40.000, otherwise it is not a BW image in opposite to your shown code.
Nuno
Nuno on 21 Jul 2011
Really? You didn't see something that looks like a paper sheet split in 8 blocks and has an arrow pointing to the word "Paper sheet"? in my laptop i can see it very well... don't know what happened...
The values for black and white pixels were just an example, of course the sum must be 40.000.

Sign in to comment.

Accepted Answer

Jan
Jan on 21 Jul 2011
From your original question I understood, that you have a {200 x 200} cell, such that each object contains a [4x4] matrix of pixels. But changing this to a {4x4} cell containing [200x200] matrices is trivial.
You've split your BW matrix by MAT2CELL. My answer avoid this time-consuming step, because I do not think, that there is any need for such a cell.
I'm really astonished, that a 200x200 block of a BW image can contain 34 black and 92 white pixels. I'd expect that the sum of the numbers must be 40000 ?!
Now a version for [200x200] blocks:
BW2 = reshape(BW, 200, 4, 200, 4);
nBlack = reshape(sum(sum(BW2, 1), 3), 4, 4);
nWhite = 200*200 - nBlack;
Now "nBlack(1,1)" is the number of black pixels in the first block, "nWhite(2,3)" is the number of white points in the 2nd row and 3rd column, and so on... This method works without MAT2CELL, because you did not explain, why this is needed.

More Answers (6)

Jan
Jan on 20 Jul 2011
I do not see the reason to use a {200 x 200} cell, and this cell does not appear in your code at all.
To count the Black and White pixels in the full image:
Image = imread('3080.jpg');
BW = im2bw(Image);
nBlack = sum(BW(:));
nWhite = numel(BW) - nBlack;
Now let's divide the image into a {200 x 200} cell - although I do not see any reason for such an inefficient storage method:
BW2 = permute(reshape(BW, 4, 200, 4, 200), [1, 3, 2, 4]);
BWC = num2cell(BW2, [1, 2]);
nPixel = numel(BWC{1}); % Number of pixels per block
for jC = 1:size(BWC, 2)
for iC = 1:size(BWC, 1)
aBlock = BWC{iC, jC};
nBlack = sum(aBlock(:));
nWhite = nPixel - nBlack;
... Now whatever you want to do with these numbers
end
end
But I guess this more efficient solves your problem already:
BW2 = reshape(BW, 4, 200, 4, 200);
nBlack = reshape(sum(sum(BW2, 1), 3), 200, 200);
nWhite = 16 - nBlack;
Now Black and White are 200x200 arrays containing the numbers of pixels for each 4x4 sub-blocks.
  3 Comments
Jan
Jan on 20 Jul 2011
@Nuno: Is this answer sufficient or do you need further assistence?
Nuno
Nuno on 21 Jul 2011
Hi Jan thank you for your assistance, but i can't figure how does your answer solves my problem (i'm still learning matlab... :)), i edited my previous post and placed a schematic image of what i want to do...

Sign in to comment.


Wolfgang Schwanghart
Wolfgang Schwanghart on 20 Jul 2011
How about using blockproc to get the number of white pixels (in case you have the image processing toolbox)?
A = full(sprand(800,800,0.3));
fun = @(block_struct) sum(block_struct.data(:));
C = blockproc(A,[200 200],fun);
Regards, W.
  1 Comment
Nuno
Nuno on 20 Jul 2011
I didn't used the image processing toolbox because i want this counting process to be used in other script that later will be incorporated in a independent software... This is only a small part on the determination of the paper sheet elastic properties...
And i want this to be as "independent" as possible.

Sign in to comment.


Nuno
Nuno on 21 Jul 2011
Hi all,
I have divided the matrix in this form:
Mcell = mat2cell(BW,[200 200 200 200],[200 200 200 200]);
So now i have 16 200x200 matrices which corresponds to the 800x800 matrix of the image.
Now my problem is to find a way to count in each one of this 200x200 cells how many white and black (1's and 0's) pixels are for each of this cells.
For instincts, if i want to know how many whites (1's) are in the first cell (1,1) i just have to type Mcell(1,1) and it returns:
Black_Pix=34 White_Pix=92
  3 Comments
Nuno
Nuno on 21 Jul 2011
yes, but i think i don't understand very well the results from your answers...
Thanks anyway
Sean de Wolski
Sean de Wolski on 21 Jul 2011
What is not clear about this?
white = sum(Image(:)); %number of white px
black = numel(Image) - white; %number of black px

Sign in to comment.


Christoph
Christoph on 20 Jul 2011
image=ones(800,800);
image(1:400,:)=0;
[b w]=countBW(image)
function [black white]=countBW(Image)
black=length(Image(Image==0));
white=length(Image(Image==1));
end
Do you mean something like that?
  5 Comments
Jan
Jan on 20 Jul 2011
@Sean: These wiered bits are going to drive me crazy. In the question I find: "if BW1(i,j) == 0, White_pix = White_pix+1". However, the OP will have the power to decide if black is black or white is black or white is white...

Sign in to comment.


Nuno
Nuno on 21 Jul 2011
Hi,
Thank you all for your assistance.
@Jan your solution solves my problem, sorry for my bad explanation of the problem that made you waste your time with this... By this moment i had the following script, but your's seems to be much faster and simple!
Image = imread('3080.jpg');
%Normaliza a luminosidade segundo o critério de Otsu's
level = graythresh(Image);
%Converte a imagem em binário
BW = im2bw(Image,level);
imshow(BW)
Mcell = mat2cell(BW,[200 200 200 200],[200 200 200 200]);
%Determina para cada uma das células quantos 0's(pixeis pretos)e 1's
%(pixeis brancos) existem
a=zeros(4,4);
b=zeros(4,4);
for i=1:4
for j=1:4
index = find(Mcell{i,j}==0);
a(i,j)=numel(index);
b(i,j)=numel(Mcell{i,j})-a(i,j);
end
end
Once again thank you all
Regards Nuno Gonçalves

Sean de Wolski
Sean de Wolski on 21 Jul 2011
tinypic makes this possible though: Nuno's image, no porn/ads/taggings/things you may (or may not) be interested in etc.
  2 Comments
Image Analyst
Image Analyst on 3 Jul 2022
Is that the '3080.jpg' image? It's now missing from tinypic.com.
That's another disadvantage of posting images on third party web sites -- they can be removed or taken down. Would not have happened if it was hosted here on the Mathworks site.

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!