简体   繁体   中英

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. 我是

 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

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);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM