5
$\begingroup$

I need help processing a biology bacteria picture. I just started learning Mathematica and I hope you guys can use a simple method to help me solve the problem, please do not use super complicated methods.

Below is what I want to do, it was done by my friend and he refuses to teach me. I want to label each bacteria cell on the picture with numbers.

My thoughts are as follows:

  1. Binarize the image and use ComponentMeasurements to find the centroids of all bacteria cells.
  2. Convert the centroids (coordinates) to numbers 1 to 12 and make it into a graphic.
  3. Show my original picture together with the picture numbered 1 to 12 to get my end result.

However, my problem is that I do not know how to convert centroids (which are coordinate positions) into numbers. enter image description here


Thanks Simon Woods! Here is my code and my attempt. Please correct me and see which part am I wrong.

Firstly, This is the picture I started off with (named "bacteria") and I want it to be labelled as shown on the above picture. enter image description here

And this is my code. I did not include how I sharpen and binarize the picture because it is quite straightforward. I will only start with the part whereby I get the centroids. i named my binarized picture as "image".

morpData = MorphologicalComponents[image]
Tally@Flatten@morpData
cenData = ComponentMeasurements[morpData, {"Centroid"}]
getCenData = centroidData[[All, 2, 1]]

After these 4 steps, I managed to get the list of centroid coordinates which are

{{483.727, 478.227}, {422., 442.5}, {289.862, 331.534}, {245.261, 299.542}, {140.959, 259.041}, {404.427, 224.821}, {538.261, 223.39}, {56., 174.192}, {41., 140.844}, {190.529, 95.6238}, {277.262, 65.4048}, {491.833, 34.2778}}

This is good because I managed to identify all 12 bacteria in the picture. However, I need to know how to convert centroid coordinates to labeled numbers!!

I tried, but I still cannot do it. And to prove that I really tried, this is my latest effort at trying to convert the 12 centroid coordinates into numbering and overlay with the original image. Please tell me where I went wrong:

Show[bacteria,Map[Graphics[Text[Style[getCenData[[1]], Red], getCenData[[2]]]], getCenData]]

And please, do not tell me to convert one by one, that is too troublesome.

$\endgroup$
10
  • 1
    $\begingroup$ You should also post the raw image (without numbers) $\endgroup$ Commented Jan 24, 2014 at 17:38
  • $\begingroup$ Also, you should post the code for the steps you already know how to implement (perhaps only step 1 in your list above) to convert this question in something else than "plz gimme teh codez" $\endgroup$ Commented Jan 24, 2014 at 17:41
  • $\begingroup$ This may be of help: reference.wolfram.com/mathematica/example/… $\endgroup$
    – DavidC
    Commented Jan 24, 2014 at 17:52
  • 2
    $\begingroup$ BTW, please specify whether this is homework or not (sounds like it) $\endgroup$ Commented Jan 24, 2014 at 17:53
  • 1
    $\begingroup$ IMO it would be cleaner not to wrap the centroids in the extra list in the first place (by removing the list braces from {"Centroid"}) and then just use Text @@@ cenData $\endgroup$ Commented Jan 25, 2014 at 15:50

2 Answers 2

10
$\begingroup$

You are most of the way there! Here is the setup: import the image and binarize, then get the locations of the centroids of the components (the positions of the bacteria).

img = Import["https://i.sstatic.net/Xj143.jpg"];
binImg = Dilation[Binarize[img, 2/3], 5];
centroidData = ComponentMeasurements[binImg, {"Centroid"}]
getCenData = centroidData[[All, 2, 1]];

All that remains is to plot and superimpose the numbers:

Show[Image[img, ImageSize -> 600], 
Graphics[{Red, Table[Inset[ToString[i], getCenData[[i]]], {i, 1, Length[getCenData]}]}]]

enter image description here

$\endgroup$
8
$\begingroup$

You haven't posted the code you already have, nor a source image so we can reproduce your results (and see where you're stuck), so you won't get a full answer to your question. Consider this a long comment.

Your seem to have 4 separate questions:

  1. How do I find the cells?
  2. How do I draw something?
  3. How do I draw something over my microscope image?
  4. How do I draw the cell indices at the positions where I found the cells?

As far as I understand, you've already solved the first question. I'll assume you have a list of rules like 1 -> {100,200}, 2 -> {110,250}, 3 -> ..., and have this list assigned to a variable called e.g. cellLocations.

The answer to question 2 is the built-in function Graphics: Graphics takes a list of graphics primitives like lines, circles, text objects, colors, fill styles and so on, and renders them. For example:

Graphics[{Red, Line[{{10, 10}, {20, 20}}], Text["Hello World", {20, 20}]}]

draws a red line and a line of text. Read the documentation on graphics carefully if you want to draw anything more complex than a straight line.

The answer to question 3 is the built-in function Show: You can use it to render a graphics object in front of an image object, like this:

Show[myImage, Graphics[{ ... }]

Finally, the last question: how do you turn a list of cell locations in some format (as returned by ComponentMeasurements) into a list of graphics primitives? As @David Carraher explained in a comment: Mathematica's Replace function (or it's short form /.) is very useful for that. Be sure to read the documentation, too.

Finally, a word of advice: Mathematica is perfectly suited for what you're trying to do, but piecing it together by trial and error, documentation and stackexchange is bound to be frustrating. (At least, it was for me.) Do yourself a favor and get a good introductory book. It'll save you a lot of time, and possibly a few gray hairs, too.

$\endgroup$
4
  • $\begingroup$ thank you guys for helping me, i am amazed that you guys are so helpful. can i have you guy's email so I can send you my notebook directly? It is very hard to speak on this chat. I dont really know how to input my code here. Please tell me your email and I will show you what I did. $\endgroup$
    – andy
    Commented Jan 25, 2014 at 1:13
  • $\begingroup$ currently, I can able to ListPlot the centroid coordinates and show the 2 pictures together. However, when I ListPlot, I will only have a red dot on the bacteria samples I have, I want to have a number on each one of them. One of you said to use Graphics[Text[Style[]]] but I dont know how to use it. Can someone give me your email and you can show me? $\endgroup$
    – andy
    Commented Jan 25, 2014 at 1:19
  • 1
    $\begingroup$ @andy: I'm sorry, but no, I won't give you my email address. I'm not a private tutor. And if I were, I would tell you the same thing: get a good book, read the documentation. It'll be quicker, more fun and you'll learn more that way than by having someone doing your homework. $\endgroup$ Commented Jan 25, 2014 at 8:13
  • $\begingroup$ @andy, you can edit your question (click the edit button beneath the question) and simply copy and paste your code in. To format it as a code block you select the code and click the "Code Sample" button (looks like {}). There is more detailed formatting help here and general advice on asking a good question here $\endgroup$ Commented Jan 25, 2014 at 11:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.