matlabpositionpixelimage-segmentationimage-thresholding

Select pixel position for image segmentation based on threshold value


I am writing a function to segment an image in MATLAB. I want to do a simple segmentation where I first sum up elements along columns and select pixel position which is greater than threshold and display only those pixels from the original[![enter image description here] image. I have written a function below where it can sum pixel intensities, I need help in selecting pixel position where intensity is greater than threshold and display only that part of image. im

 function S = image_segment(im) 
% im is the image to segment
    
nrofsegments = 5; % there is 5 fragments for this image
S = cell(1,nrofsegments);
m = size(im,1);
n = size(im,2);
for kk = 1:nrofsegments
    S_sum=sum(im); %sum the intensity along column
    S_position = ... % get pixel position where the pixel intensity is greater than 128
    S{kk} = ... % im(S_position), only part of image with this pixel position

    
end

Solution

  • This code should work for your image. Please find the explanations inline.

    % Read your test image from the web
    im = imread('https://i.sstatic.net/qg5gx.jpg');
    
    % Get sum of intensities along the columns
    colSum = sum(im);       
    
    % Set a proper threshold (128 was not working for me)
    thresh = 300;
    
    % Get an 1-D logical array indicating which columns have letters
    hasLetter = colSum > thresh;   
    
    % Get the difference of consecutive values in hasLetter
    hasLetterDiff = diff( hasLetter ) ;
    
    % If this is greater than 0, we have the start of a letter.
    % The find gets the indices where this is true.
    % Then, we add one to compensate for the offset introduced by diff.
    letterStartPos = find( hasLetterDiff > 0  ) + 1;
    
    % Use a similar approach to find the letter end position
    % Here, we search for differences smaller than 0.
    letterEndPos = find( hasLetterDiff < 0  ) + 1;
    
    % Cut out image from start and end positions
    numSegments = 5;
    S = cell(1, numSegments );
    for k = 1 : numel(S)
       S{k} = im( :, letterStartPos(k) : letterEndPos(k));
    end
    

    You should consider furthermore to add some code to make it fail-safe for cases where there are less than 5 segments. Moreover, I would recommend to do some low-pass or median filtering on colSum.

    Alternative: Instead of deriving the start and stop positions, it would also be possible to use splitapply (introduced in R2015) directly on hasLetterDiff as follows:

    S = splitapply( @(X) { im(:,X) }, 1 : numel( hasLetter),  [1 cumsum( abs( hasLetterDiff))] + 1);
    S = S(2:2:end);