Got Questions? Get Answers.
Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

Thread Subject:
Logical test of neighboring pixels in an image

Subject: Logical test of neighboring pixels in an image

From: Dan

Date: 31 Aug, 2009 20:04:05

Message: 1 of 10

This is probably a simple question, as I am just now starting to learn about image processing. Ultimately, I am trying to separate blobs in an image using the watershed function. The output from this gives a sea of 1s as background, the watershed pixels as 0s and regions inside the blobs being separated are numbered individually.
What I need is a way to find just the watershed pixels that separate two blobs. (That is, a 0 pixel that is adjacent to two different non-1 numbers.) I'm guessing there is an easy way to do this that I just can't find in my searching.

Example matrix:
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 0 0 0 0 0 1 1 1 1 1
1 1 1 1 1 1 1 0 3 3 3 0 0 1 1 1 1
1 1 1 1 1 1 1 0 3 3 3 3 0 1 1 1 1
1 1 1 1 1 1 1 0 0 0 0 0 0 1 1 1 1
1 1 1 1 1 1 1 0 4 4 4 4 0 1 1 1 1
1 1 1 1 1 1 1 0 4 4 4 4 0 1 1 1 1
1 1 1 1 1 1 1 0 0 0 0 0 0 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1


Here I would like to return only the 0s in row 5 which lie between a 3 and a 4.
Any help including pointing me to a tutorial would be appreciated!

Subject: Logical test of neighboring pixels in an image

From: us

Date: 31 Aug, 2009 20:22:18

Message: 2 of 10

"Dan " <sp4mmesilly@gmail.com> wrote in message <h7habk$chb$1@fred.mathworks.com>...
> This is probably a simple question, as I am just now starting to learn about image processing. Ultimately, I am trying to separate blobs in an image using the watershed function. The output from this gives a sea of 1s as background, the watershed pixels as 0s and regions inside the blobs being separated are numbered individually.
> What I need is a way to find just the watershed pixels that separate two blobs. (That is, a 0 pixel that is adjacent to two different non-1 numbers.) I'm guessing there is an easy way to do this that I just can't find in my searching.
>
> Example matrix:
> 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
> 1 1 1 1 1 1 1 0 0 0 0 0 1 1 1 1 1
> 1 1 1 1 1 1 1 0 3 3 3 0 0 1 1 1 1
> 1 1 1 1 1 1 1 0 3 3 3 3 0 1 1 1 1
> 1 1 1 1 1 1 1 0 0 0 0 0 0 1 1 1 1
> 1 1 1 1 1 1 1 0 4 4 4 4 0 1 1 1 1
> 1 1 1 1 1 1 1 0 4 4 4 4 0 1 1 1 1
> 1 1 1 1 1 1 1 0 0 0 0 0 0 1 1 1 1
> 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
>
>
> Here I would like to return only the 0s in row 5 which lie between a 3 and a 4.
> Any help including pointing me to a tutorial would be appreciated!

one of the many(!) solutions
- detect the rows...
- do the same for cols...

% the data
     m=[
          1 1 1 5 5 1 1 1 1 1
          1 1 0 0 0 0 0 1 1 1
          1 1 0 3 3 3 0 0 1 1
          1 1 0 3 3 3 3 0 1 1
          1 1 0 0 0 0 0 0 1 1
          1 1 0 4 4 4 4 0 1 1
          1 1 0 4 4 4 4 0 1 1
          1 1 0 0 0 0 0 0 1 1
          1 1 1 1 1 1 1 1 1 1
     ];
% the engine
% - detect the rows
     mm=m>1;
     r=filter2([1;1;1],mm); % <- rows...
     r=r==2&mm==0;
% the result
     disp(r);
%{
% the rows...
          0 0 0 0 0 0 0 0 0 0
          0 0 0 1 1 0 0 0 0 0
          0 0 0 0 0 0 0 0 0 0
          0 0 0 0 0 0 0 0 0 0
          0 0 0 1 1 1 1 0 0 0
          0 0 0 0 0 0 0 0 0 0
          0 0 0 0 0 0 0 0 0 0
          0 0 0 0 0 0 0 0 0 0
          0 0 0 0 0 0 0 0 0 0
%}

us

Subject: Logical test of neighboring pixels in an image

From: ImageAnalyst

Date: 31 Aug, 2009 20:32:36

Message: 3 of 10

On Aug 31, 4:04 pm, "Dan " <sp4mmesi...@gmail.com> wrote:
> This is probably a simple question, as I am just now starting to learn about image processing.  Ultimately, I am trying to separate blobs in an image using the watershed function.  The output from this gives a sea of 1s as background, the watershed pixels as 0s and regions inside the blobs being separated are numbered individually.
> What I need is a way to find just the watershed pixels that separate two blobs.  (That is, a 0 pixel that is adjacent to two different non-1 numbers.)  I'm guessing there is an easy way to do this that I just can't find in my searching.
>
> Example matrix:
> 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
> 1 1 1 1 1 1 1 0 0 0 0 0 1 1 1 1 1
> 1 1 1 1 1 1 1 0 3 3 3 0 0 1 1 1 1
> 1 1 1 1 1 1 1 0 3 3 3 3 0 1 1 1 1
> 1 1 1 1 1 1 1 0 0 0 0 0 0 1 1 1 1
> 1 1 1 1 1 1 1 0 4 4 4 4 0 1 1 1 1
> 1 1 1 1 1 1 1 0 4 4 4 4 0 1 1 1 1
> 1 1 1 1 1 1 1 0 0 0 0 0 0 1 1 1 1
> 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
>
> Here I would like to return only the 0s in row 5 which lie between a 3 and a 4.
> Any help including pointing me to a tutorial would be appreciated!

------------------------------------------------------------------------
Dan:
I'm not sure you can do this without some special purpose ad-hoc code.
After all, why are the zeros between the 3s and 4s any different than
those between the 3s and the 1s (or any other number for that matter).
How would it know not to get the 0 at the center of the 1-3-4
triangle?
You're going to have to look SPECIFICALLY for the 4s (and not the 1s)
or else make some other assumption, like the zeros have non-zero
numbers both above and below them, and more zeros to the left and
right of them. Like I said, custom ad hoc code. And I can't give
that because I don't know the criteria.
You can maybe do it if you define your problem more precisely and
cobble together a bunch of functions but there is no built-in, out-of-
the-box function that will give you that vector of 4 x-y coordinates
(or intensity values) in the row between the 3s and 4s.

One general purpose way that works if you've done some kinds of
segmentation to get a binary image of the 3's and 4s (and no 1s and
0s) is to take the skiz of the binary image, which is basically the
skeleton of the background. Here's a link for you to learn more:
http://homepages.inf.ed.ac.uk/rbf/HIPR2/thick.htm

Other than that, here's a tutorial I uploaded. Talks about
thresholding, labeling, and measuring, but not watershed.
http://www.mathworks.com/matlabcentral/fileexchange/25157
Hope it helps you...

Good luck,
ImageAnalyst

Subject: Logical test of neighboring pixels in an image

From: ImageAnalyst

Date: 31 Aug, 2009 20:50:07

Message: 4 of 10

Ah, it looks like us have given you some specialized code to do
exactly what you said. He's very good, and speedy. Hope that exactly
what you said is what you want. Note that if it's not, you'll need to
do something else. For example what if your matrix looks like this:
     m=[
          1 1 1 5 5 1 1 1 1 1
          1 1 0 0 0 0 0 1 1 1
          1 4 0 3 3 3 3 0 1 1
          1 4 0 3 0 3 0 0 1 1
          1 4 0 0 0 0 4 0 1 1
          1 4 4 4 4 4 4 0 1 1
          1 1 0 4 4 4 4 0 1 1
          1 1 0 0 0 0 0 0 1 1
          1 1 1 1 1 1 1 1 1 1
     ];
Do you want the 0's in the columns between the 4s and 3s? What about
the case where there are two zeros between the 3 and the 4 below it?
So, if you want something different than what you said, you better
spell it out very precisely.

How did your blobs all get surrounded by 0's and sit in a background
of 1s anyway? What gave rise to this image? A watershed lines image
multiplied by your original image? Why do you want the separation
lines? Why not just label and make your measurements? Would
graycomatrix() be a better way of doing this than watershed and
finding separation lines (very possibly I think)? I think I'm missing
the big picture.

This is the link I have for watershed:
http://cmm.ensmp.fr/~beucher/wtshed.html
A nice wide diversity of watershed examples are there.
Good luck,
ImageAnalyst

Subject: Logical test of neighboring pixels in an image

From: us

Date: 31 Aug, 2009 20:54:19

Message: 5 of 10

ImageAnalyst <imageanalyst@mailinator.com> wrote in message <80e2de15-b73d-4ba1-9868-95eaf7b800eb@q35g2000vbi.googlegroups.com>...
> On Aug 31, 4:04?pm, "Dan " <sp4mmesi...@gmail.com> wrote:
> > This is probably a simple question, as I am just now starting to learn about image processing. ?Ultimately, I am trying to separate blobs in an image using the watershed function. ?The output from this gives a sea of 1s as background, the watershed pixels as 0s and regions inside the blobs being separated are numbered individually.
> > What I need is a way to find just the watershed pixels that separate two blobs. ?(That is, a 0 pixel that is adjacent to two different non-1 numbers.) ?I'm guessing there is an easy way to do this that I just can't find in my searching.
> >
> > Example matrix:
> > ...
> > Here I would like to return only the 0s in row 5 which lie between a 3 and a 4.
> > Any help including pointing me to a tutorial would be appreciated!
>
> ------------------------------------------------------------------------
> Dan:
> I'm not sure you can do this without some special purpose ad-hoc code...

...the simple engine suggested in an earlier post seems to work, though...

us

Subject: Logical test of neighboring pixels in an image

From: us

Date: 31 Aug, 2009 21:07:23

Message: 6 of 10

"us " <us@neurol.unizh.ch> wrote in message <h7hd9r$om5$1@fred.mathworks.com>...
> ImageAnalyst <imageanalyst@mailinator.com> wrote in message <80e2de15-b73d-4ba1-9868-95eaf7b800eb@q35g2000vbi.googlegroups.com>...
> > On Aug 31, 4:04?pm, "Dan " <sp4mmesi...@gmail.com> wrote:
> > > This is probably a simple question, as I am just now starting to learn about image processing. ?Ultimately, I am trying to separate blobs in an image using the watershed function. ?The output from this gives a sea of 1s as background, the watershed pixels as 0s and regions inside the blobs being separated are numbered individually.
> > > What I need is a way to find just the watershed pixels that separate two blobs. ?(That is, a 0 pixel that is adjacent to two different non-1 numbers.) ?I'm guessing there is an easy way to do this that I just can't find in my searching.
> > >
> > > Example matrix:
> > > ...
> > > Here I would like to return only the 0s in row 5 which lie between a 3 and a 4.
> > > Any help including pointing me to a tutorial would be appreciated!
> >
> > ------------------------------------------------------------------------
> > Dan:
> > I'm not sure you can do this without some special purpose ad-hoc code...
>
> ...the simple engine suggested in an earlier post seems to work, though...

sorry, ia, i didn't see your 2nd post...
seems the two of us are pretty speedy - and the feeding time of TMW's reader cannot keep up with the pace...

anyhow, you are - of course - correct: the OP must probably refine his/her problem to make sure we're not coding-in-the-dark...

urs

Subject: Logical test of neighboring pixels in an image

From: Dan

Date: 1 Sep, 2009 13:53:01

Message: 7 of 10

Wow, thanks for the speedy replies guys! Sounds like I may not just be one simple function short of what I want, and I'd better explain in more detail.

Here's a better explanation of what I'm trying to do:
I am trying to quantify images of synapses (blobs with bright intensity). I want to both count the total number in an image AND measure the area of each one. There are often one or more in a cluster near each other that get grouped into a single blob, however. I essentially just need to slice up these grouped blobs into individual ones, but without affecting their shape or area too much.
As of two days ago I didn't even realize I had the image processing toolbox, so I'm a total newb to this stuff. But hunting around online and in the help documentation I found that watershedding was pretty close to what I needed. The only problem is that it would significantly reduce the areas of the blobs that get watershedded.

Here is an example image (zoomed way in on one part of the total image):
http://picasaweb.google.com/somedanguy/MatlabExample#5376492680784268306

Top left is the original image with various bright spots.
Top right is binary mask set by thresholding for intensity. Here you can see that the two spots in the center get grouped into one.
Bottom left is what I'd like to do: simply slice them into two. (I removed the other surrounding blobs for clarity)
Bottom right is the result of watershedding, with the two colors indicating that those regions have been given non-0-or-1 values, distinct from each other. The problem is that if I just use these regions, (or use all the pixels labeled as watershed to slice out of the original mask), the resulting regions are much smaller than in the original binary mask.

Thanks again for any help!

Subject: Logical test of neighboring pixels in an image

From: ImageAnalyst

Date: 1 Sep, 2009 14:24:07

Message: 8 of 10

On Sep 1, 9:53 am, "Dan " <sp4mmesi...@gmail.com> wrote:
> Wow, thanks for the speedy replies guys!  Sounds like I may not just be one simple function short of what I want, and I'd better explain in more detail.
>
> Here's a better explanation of what I'm trying to do:
> I am trying to quantify images of synapses (blobs with bright intensity).  I want to both count the total number in an image AND measure the area of each one.  There are often one or more in a cluster near each other that get grouped into a single blob, however.  I essentially just need to slice up these grouped blobs into individual ones, but without affecting their shape or area too much.
> As of two days ago I didn't even realize I had the image processing toolbox, so I'm a total newb to this stuff.  But hunting around online and in the help documentation I found that watershedding was pretty close to what I needed.  The only problem is that it would significantly reduce the areas of the blobs that get watershedded.
>
> Here is an example image (zoomed way in on one part of the total image):http://picasaweb.google.com/somedanguy/MatlabExample#5376492680784268306
>
> Top left is the original image with various bright spots.  
> Top right is binary mask set by thresholding for intensity.  Here you can see that the two spots in the center get grouped into one.
> Bottom left is what I'd like to do: simply slice them into two. (I removed the other surrounding blobs for clarity)
> Bottom right is the result of watershedding, with the two colors indicating that those regions have been given non-0-or-1 values, distinct from each other.  The problem is that if I just use these regions, (or use all the pixels labeled as watershed to slice out of the original mask), the resulting regions are much smaller than in the original binary mask.
>
> Thanks again for any help!

---------------------------------------------------------------------------------------------------------------------
Dan:
You want "Marker-controlled watershed segmentation" - this will give
you the original size (except for the thin dividing line.. MATLAB has
a demo specifically on this - look in the Help navigator for it.
After you've split them then you can do the standard process of
thresholding, labeling, regionprops to make your measurements.
Regards,
ImageAnalyst

Subject: Logical test of neighboring pixels in an image

From: Dan

Date: 1 Sep, 2009 15:01:06

Message: 9 of 10

---------------------------------------------------------------------------------------------------------------------
> Dan:
> You want "Marker-controlled watershed segmentation" - this will give
> you the original size (except for the thin dividing line.. MATLAB has
> a demo specifically on this - look in the Help navigator for it.
> After you've split them then you can do the standard process of
> thresholding, labeling, regionprops to make your measurements.
> Regards,
> ImageAnalyst

Great, I'll take a closer look at that demo. I figured this would be a common thing people needed to do.
Thanks for your help!

Subject: Logical test of neighboring pixels in an image

From: Dan

Date: 3 Sep, 2009 19:24:02

Message: 10 of 10

In case anyone comes by this thread for a search later, I thought I'd post my solution, which turned out to be a simple error. The tutorial I was following had me setting all the background pixels in the distance transform to negative infinity, which made them infinitely deep catchment basins. Instead, I just needed to set them to POSITIVE infinity, and then everything worked just as I wanted. A bit of the final below:

% 'bigBlobs' is a binary image containing numerous blobs that probably need to be divided up into smaller component blobs

% distance transform
D = -bwdist(~bigBlobs);
% Set background pixels to positive infinity
D(~bigBlobs) = Inf;
%watershed, resulting in lines of '0' value dividing blobs
L = watershed(D,8);
% Cut the original blobs with the lines resulting from the watershed
bigBlobs(L==0)=0;

Tags for this Thread

What are tags?

A tag is like a keyword or category label associated with each thread. Tags make it easier for you to find threads of interest.

Anyone can tag a thread. Tags are public and visible to everyone.

Contact us