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.
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
CodePudding user response:
This code should work for your image. Please find the explanations inline.
% Read your test image from the web
im = imread('https://i.stack.imgur.com/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);