0
votes

I'm looking for Double thresholding for segmentation! I have to do this algorithm in matlab,but I couldn't find any source !!

Double Thresholding:

(1) Select two thresholds T1 and T2.

(2) Partition the image into three type regions :

R1, containing all pixels with gray values below T1.

R2, containing all pixels with gray values between T1 and T2 , inclusive.

R3, containing all pixels with gray values above T2.

where R1=core region, R2= fringe(intermediate, transition) region, R3=background.

(3) Visit each pixel in region R2. If the pixel has a neighbor in region R1, then reassign the pixel to region R1.

(4) Repeat step 3 until no pixels are reassigned.

(5) Reassign any pixels left in region R2to R3.

this Image show what I want : http://www.directupload.net/file/d/3636/3ihhmzgb_jpg.htm

how can I do that ?! please Help me .

2
What have you already tried?Rafael Monteiro
Good luck on your homework!Cape Code
@rayryeng I think we are past the HW deadline ;)Divakar
@ rayryeng , great thanks for all your work :)Hanieh
@Hanieh Thank you for the pic, it makes sense now. Maybe edit your question with it? Finally it could turn out as a great question, because you know people like photos :)Divakar

2 Answers

5
votes

Suppose you have an image stored in the variable called im. It is also assumed that im is in double format [0-1]. Let's step through each part one at a time, with accompanying code.

(1) Select two thresholds T1 and T2.

Let's say T1 = 0.1 and T2 = 0.7. We need to make sure that these thresholds are at the lower and higher end of the intensity spectrum.

T1 = 0.1;
T2 = 0.7;

(2) Partition the image into three type regions : R1, containing all pixels with gray values below T1. R2, containing all pixels with gray values between T1 and T2, inclusive. R3, containing all pixels with gray values above T2. where R1=core region, R2= fringe(intermediate, transition) region, R3=background.

We will create three binary maps that will tell us where in the image each of these conditions are satisfied.

R1 = im < T1;
R2 = im >= T1 & im <= T2;
R3 = im > T2;

(3) Visit each pixel in region R2. If the pixel has a neighbor in region R1, then reassign the pixel to region R1.

I'm going to assume 8-connectedness, which means that a neighbour would be N, NE, E, SE, S, SW, W, or NW, using cardinal directions. What we can do is take each overlapping neighbourhood of pixels for R2 and place them into columns. Do the same for R1. We can use the function called im2col to help us do that. 8-connectedness checks for neighbours within a 3 x 3 pixel neighbourhood. What's cool about im2col is that the for the output of this function, middle row will contain the centre of each neighbourhood. We will definitely need this when we want to reconstruct our regions back. When we extract the centre of each neighbourhood, it's just a matter of checking to see if:

  1. If the centre of each neighbourhood in region R2 evaluates to true
  2. Any pixels in the corresponding neighbourhood of R1 evaluates to true, then these are all neighbours of R2.
     %//Zero-pad the regions so we can check the borders
     R1 = padarray(R1, [1 1], 'replicate');
     R2 = padarray(R2, [1 1], 'replicate');

     %//Transform into columns
     B1 = im2col(R1, [3 3]);
     B2 = im2col(R2, [3 3]);

     %//Extract size for later
     [rows cols] = size(R1); 

     %// Extract centre of each neighbourhood
     middleB2 = B2(5,:);

     % // Find the indices of those neighbourhoods that have 1 in the centre
     windowsHaving1 = find(middleB2 == 1);

     % // Access the corresponding neighbourhoods in R1
     % // If ANY of them have a pixel of 1, then we know
     % // these locations from R2 need to go back to R1
     % // In that case, all you really have to do is take whichever
     % // pixels are true, and set them to true in R1

     % // See which neighbourhoods in `R1` have any pixels that are 1
     % // given the corresponding region in R2
     finalColumns = any(B1(:,windowsHaving1), 1);

     % // Grab the indices of these columns
     finalColumnsIndex = windowsHaving1(finalColumns);

     % // Reasign those pixels that are neighbours to R1     
     B1(5, finalColumnsIndex) = 1;
     B2(5, finalColumnsIndex) = 0;

     %// Restructure back - Recall this image is padded
     %// We took the rows and columns of the padded image
     %// and so we need to subtract each dimension by 2
     R1 = reshape(B1(5,:), rows-2, cols-2);
     R2 = reshape(B2(5,:), rows-2, cols-2);

(4) Repeat step 3 until no pixels are reassigned.

Already performed.

(5) Reassign any pixels left in region R2 to R3.

That's pretty straight forward. Any pixels that are true in R2, simply turn these on in R3.

R3 = R2 | R3;

As such, your final double thresholded images are left in R1 and R3. If you want to create an integer map that tells you which pixels are in what region, you can do something like:

map = zeros(size(im));
map(R1) = 1;
map(R3) = 2;

Any pixels that are 0 did not meet the criteria after you went through the double threshold process. As a test, let's take a look at this on a regular image. I'll be using cameraman.tif that is in the MATLAB path. As such, load in your image like so:

im = im2double(imread('cameraman.tif'));

After, run through my code. These are the results I get. White pixels belong to the corresponding region, while black pixels don't.

enter image description here

Good luck!

3
votes

UPDATED inspired by @rayryeng's complete solution, here is a working (proven) solution - my original had a couple of small errors (as happens when you write Matlab code outside of the Matlab environment...). The advantage of this method is that it doesn't require use of the Image Processing Toolbox.

A = double(imread('cameraman.tif'))*(1/256.0); % import, scale to range 0-1
original = A; % keep a copy
T1 = 0.2;
T2 = 0.5; % thresholds

A(A>T2) = 3; % region 3
A(A<T1) = 1; % region 1
A(A~=1 & A~=3) = 2;  % region 2: the rest

% create a "padded" version
Apad = zeros(size(A)+2);
Apad(2:end-1, 2:end-1) = A; % now we have a zero border
nr = size(Apad, 1); % number of rows
numFound = 1; % initially some number > 0
neighbors = [-nr-1, -nr, -nr+1, -1, 1, nr-1, nr, nr+1]; % offset of all neighbors

% loop that does the hard work:
while numFound>0
  f2 = find(Apad==2); % indices of all elements in region 2
  i21 = bsxfun(@plus, f2(:), neighbors); % indices of all neighbors
  convert = find(any(Apad(i21) == 3, 2)); % find all pixels that have a neighbor in region 3
  numFound = numel(convert);
  Apad(f2(convert)) = 3;
end

Apad(Apad==2) = 1; % set remaining "islands" to 1
result = Apad(2:end-1, 2:end-1);

%% display results
figure('position', [100 100 900 300]);
subplot(1,3,1); imagesc(original); axis image; axis off; colormap gray
subplot(1,3,2); imagesc(A); axis image; axis off; colormap jet
subplot(1,3,3); imagesc(result); axis image; axis off; colormap gray
saveas(gcf, 'R1R2.png')

The result is (original - three regions - two regions):

enter image description here

Notice an interesting thing in the pants of the photographer. There are two "region 2" regions in the leg - but only one of them "connects" to the "region 3" between the legs. As a consequence, in the final thresholded image you get one region showing up as bright, and the other as dark. This is indeed the expected behavior - but it's nice confirmation that the algorithm works as advertised.