1
votes

I am trying to get pixel intensity values from regions of interest in RGB images.

I segmented the image and saved the regions of interest (ROI) using regionprops 'PixelList' in MATLAB, as shown below:

In this example I am using "onion.png" image built in MATLAB. (But in reality I have hundreds of images, and each of them have several ROIs hence why I'm saving the ROIs separately.)

%SEGMENTATION PROGRAM:

a=imread('C:\Program Files\MATLAB\MATLAB Production Server\R2015a\toolbox\images\imdata\onion.png');warning('off', 'Images:initSize:adjustingMag');

figure; imshow(a,[]);
nrows = size(a,1);ncols = size(a,2);
zr=ones(nrows,ncols); %matrix of ones
r=a(:,:,1);g=a(:,:,2);b=a(:,:,3); %get RGB values
rr=double(r);gg=double(g);bb=double(b);% convert to double to avoid uint8 sums
bgd=(rr+bb)./(2*gg); %calculation RGB ratio of background
zr1=bgd>1.15; %matrix containing background as 1 and ROI as 0

% remake binary image for holes command which requires white object to fill % (this step is not relevant for this example, but it is for my data)
zr2=zr1<0.5; 
zr3=imfill(zr2, 'holes');
figure;imshow(zr3); pause;



roi=regionprops(zr3,'Centroid','PixelList','Area');
ar=[roi.Area];
% find sort order , largest first
[as, ia]=sort(ar(1,:),'descend');
for w=1:length(roi); xy(w,:)=roi(w).Centroid;end
% use sort index to put cenrtoid list in same order
xy1=xy(ia,:);
%and pixel id list
for w=1:length(roi)
roi2(w).PixelList=roi(ia(w)).PixelList;
end
%extract centriod positions as two colums

%SAVE PIXEL LIST FOR EACH ROI IN A SEPARATE FILE

for ww=1:w;
    k=roi2(ww).PixelList;
    save('onion_PL','k'); 
end

How do I use this pixel list to get the intensity values in the original image? More specifically, I need to get the ratio of pixels in Green channel over Red ("grr=rdivide(gg,rr);"), but only in the region of interest labeled with PixelList. Here's my code so far:

%PL is the PixelList output we got above.

a=imread('C:\Program Files\MATLAB\MATLAB Production Server\R2015a\toolbox\images\imdata\onion.png');warning('off', 'Images:initSize:adjustingMag');

PL=dir(['*PL.mat']); %load file PixelList files. "dir" is a variable with directory path containing the pixelist files. In this example, we saved "onion_PL.mat"
for m=1:length(PL);
    load(PL(m).name);
    ex=[]; %empty matrix to hold the extracted values
for mm=1:length(k); 

%INSERT ANSWER HERE

end

This next bit is wrong because it's based on the entire image ("a"), but it contains the calculations that I would like to perform in the ROIs

figure; imshow(a,[]);
pause;

nrows = size(a,1);ncols = size(a,2);
zr=ones(nrows,ncols); %matrix of ones
r=a(:,:,1);g=a(:,:,2);b=a(:,:,3); %get RGB values 
rr=double(r);gg=double(g);bb=double(b);% convert to double to avoid uint8 sums
grr=rdivide(gg,rr);

I am brand new to MATLAB, so my code is not the greatest... Any suggestions will be greatly appreciated. Thank you in advance!

1
Please post a reproducible code sample. There are many sample images that comes with MATLAB, please choose one as your input. Please use minimal code creating sample w and ai ("w" is variable used upstream... makes it more difficult to answer). Don't use 'image.tif'. Why are you using multiple mat files PL=dir(['*PL.mat']);? Your for loops are without an end. Think if it's relevant that you need to get the ratio of pixels in Green channel over Red? Please try to simplify your question, and make sure that your "true problem" description is clear.Rotem
Hello, thank you for your input. I have now edited the question, I hope it is more clear. To answer your questions, I am using multiple mat files because someone else is running a segmentation program prior to this, my job is to use the segmentation information of each ROI in each image to calculate the ratio of Green over Red (which for our images it is relevant indeed). Is it clear now? I'm sorryLarissa Carvalho
I am getting k = [130, 52; 131, 53]. The loop for ww=1:w; k=roi2(ww).PixelList; save('onion_PL','k'); end overwrites the value of k every iteration. Please test your code before posting.Rotem

1 Answers

0
votes

The loop you are looking for seems simple:

grr = zeros(nrows, ncols); % Initialize grr with zeros.

for mm = 1:length(k)
    x = k(mm, 1); % Get the X (column) coordinate.
    y = k(mm, 2); % Get the Y (row) coordinate.
    grr(y, x) = gg(y, x) / rr(y, x);
end

A more efficient solution is using sub2ind for converting the x,y coordinates to linear indices:

% Convert k to linear indices.
kInd = sub2ind([nrows, ncols], k(:,2), k(:,1));

% Update only the indices in the PixelList.
grr(kInd) = rdivide(gg(kInd), rr(kInd));

In your given code sample there are 5 PixelLists.
I don't know how do you want to "arrange" the result.
In my code sample, I am saving the 5 results to 5 mat files.


Here is an executable code sample:

close all

%SEGMENTATION PROGRAM:

a=imread('onion.png');warning('off', 'Images:initSize:adjustingMag');

figure; imshow(a,[]);
nrows = size(a,1);ncols = size(a,2);
zr=ones(nrows,ncols); %matrix of ones
r=a(:,:,1);g=a(:,:,2);b=a(:,:,3); %get RGB values
rr=double(r);gg=double(g);bb=double(b);% convert to double to avoid uint8 sums
bgd=(rr+bb)./(2*gg); %calculation RGB ratio of background
zr1=bgd>1.15; %matrix containing background as 1 and ROI as 0

% remake binary image for holes command which requires white object to fill % (this step is not relevant for this example, but it is for my data)
zr2=zr1<0.5; 
zr3=imfill(zr2, 'holes');
figure;imshow(zr3); %pause;



roi=regionprops(zr3,'Centroid','PixelList','Area');
ar=[roi.Area];
% find sort order , largest first
[as, ia]=sort(ar(1,:),'descend');
for w=1:length(roi); xy(w,:)=roi(w).Centroid;end
% use sort index to put cenrtoid list in same order
xy1=xy(ia,:);
%and pixel id list
for w=1:length(roi)
    roi2(w).PixelList=roi(ia(w)).PixelList;
end
%extract centroid positions as two columns

%SAVE PIXEL LIST FOR EACH ROI IN A SEPARATE FILE

for ww=1:w
    k=roi2(ww).PixelList;
    %save('onion_PL', 'k');
    save(['onion', num2str(ww), '_PL'], 'k'); % Store in multiple files - onion1_PL.mat, onion2_PL.mat, ... onion5_PL.mat
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

clear % Use clear for testing - the variables are going to be read from the mat file.

%PL is the PixelList output we got above.

a=imread('onion.png');warning('off', 'Images:initSize:adjustingMag');

nrows = size(a,1);ncols = size(a,2);
zr=ones(nrows,ncols); %matrix of ones
r=a(:,:,1);g=a(:,:,2);b=a(:,:,3); %get RGB values 
rr=double(r);gg=double(g);bb=double(b);% convert to double to avoid uint8 sums
grr=rdivide(gg,rr);

PL=dir('*PL.mat'); %load file PixelList files. "dir" is a variable with directory path containing the pixelist files. In this example, we saved "onion_PL.mat"
for m = 1:length(PL)
    load(PL(m).name);
    ex=[]; %empty matrix to hold the extracted values
    
    %for mm=1:length(k)

    %INSERT ANSWER HERE
    grr = zeros(nrows, ncols); % Initialize grr with zeros.
    
    for mm = 1:length(k)
        x = k(mm, 1); % Get the X (column) coordinate.
        y = k(mm, 2); % Get the Y (row) coordinate.
        grr(y, x) = gg(y, x) / rr(y, x);
    end
    
    % Instead of using a loop, it's more efficient to use sub2ind
    if false
        % Convert k to linear indices.
        kInd = sub2ind([nrows, ncols], k(:,2), k(:,1));
     
        % Update only the indices in the PixelList.
        grr(kInd) = rdivide(gg(kInd), rr(kInd));
    end
        
    figure;imshow(grr);title(['grr of m=', num2str(m)]) % Show grr for testing.
    save(['grr', num2str(m)], 'grr'); % Save grr for testing.
    imwrite(imadjust(grr, stretchlim(grr)), ['grr', num2str(m), '.png']); % Store grr as image for testing
end

First two grr matrices as images (used for testing):

grr1.png:
enter image description here

grr2.png:
enter image description here