Filter löschen
Filter löschen

Finding mean pixel value within boundaries

11 Ansichten (letzte 30 Tage)
Simon Kirkman
Simon Kirkman am 24 Jun. 2020
Kommentiert: Image Analyst am 24 Jun. 2020
I am trying to analyse the different NDVI pixel values of several different plants by getting the mean pixel value for each plant. I have used bwboundaries to find the boundaries of all the plants but i was wondering how you get the mean pixel value within each boundary. I have inserted the image and the code i have done to this point.
%%read in original image as grayscale
original = rgb2gray(imread("c:/Users/simon/Documents/ProjIM/Proj Im/ASI/2206-1-3/NDVI_1.png"))
imshow(original)
%% change to type double because of NVDI values and threshold
doubleImage = im2double(original)
threshValue = 0.05
binaryIm = doubleImage > threshValue
binaryIm = imfill(binaryIm,'holes')
imshow(binaryIm)
%%filter out 12 largest areas for 12 plants
filtered = bwareafilt(binaryIm,12,8)
imshow(filtered)
%% get boundaries with bwboundaries
[boundaries , labelled] = bwboundaries(filtered)
%% plot boundaries on original image to check they are correct
numberOfBoundaries = size(boundaries)
imshow(original)
hold on
for k = 1 : numberOfBoundaries
thisBoundary = boundaries{k};
plot(thisBoundary(:,2), thisBoundary(:,1), 'g', 'LineWidth', 2);
end
hold off

Akzeptierte Antwort

Image Analyst
Image Analyst am 24 Jun. 2020
You can use mean():
[rows, columns] = size(original)
for k = 1 : numberOfBoundaries
thisBoundary = boundaries{k};
x = thisBoundary(:,2);
y = thisBoundary(:,1)
plot(x, y, 'g', 'LineWidth', 2);
mask = poly2mask(x, y, rows, columns);
theMeans(k) = mean(original(mask));
end
Or (much better), you can get the means for each blob from regionprops(), instead of using masks inside the loop:
props = regionprops(binaryIm, original, 'MeanIntensity');
theMeans = [props.MeanIntensity]
  2 Kommentare
Simon Kirkman
Simon Kirkman am 24 Jun. 2020
Thanks for this. I had read your freehand example and manged to peice together the first example with slightly different code that ill put below if anybody ever comes back to this. I am also going to give your second method a go and see how the values compare.
for n = 1:size(boundaries)
B = boundaries{n};
Bx = B(:,2);
By = B(:,1);
BW2 = poly2mask(Bx,By, rows, cols);
imshow (original);
blackmasked = doubleImage;
blackmasked(~BW2) = 0;
meanGL(n) = mean(blackmasked(BW2));
drawnow
end
Image Analyst
Image Analyst am 24 Jun. 2020
The line
blackmasked(~BW2) = 0;
is not needed since you're not looking outside the BW2 mask anyway. Get rid of it to save a very tiny bit of time. Plus you can take the imshow(original) and drawnow out of the loop and put it before since it doesn't change at all during the loop.

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (1)

Monalisa Pal
Monalisa Pal am 24 Jun. 2020
I am not sure whether my answer is the best way to do it but here's an attempt using the concept of connected component labelling:
%% getting mean within boundaries
[labelRegions, numberOfRegions] = bwlabel(filtered, 8); % using 8-connectivity
% Note that numberOfRegions == numberOfBoundaries
regionwiseMeanPixel = zeros(1, numberOfRegions);
for k = 1 : numberOfRegions
mask = (L == k);
region_k = uint8(mask) .* original;
regionwiseMeanPixel(k) = sum(region_k(:)) / sum(mask(:));
end

Kategorien

Mehr zu Image Processing and Computer Vision finden Sie in Help Center und File Exchange

Produkte


Version

R2020a

Community Treasure Hunt

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

Start Hunting!

Translated by