Counting Colonies with scikit-image


In [ ]:
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
from PIL import Image

from skimage.feature import blob_dog, blob_log, blob_doh
from skimage.color import rgb2gray

Load in the plate image


In [ ]:
image = np.array(Image.open("img/colonies.jpg"))
plt.imshow(image)

Construct a mask to remove the plate itself


In [ ]:
center = np.array(image.shape[:2])/2
cutoff = 550
sq_cutoff = cutoff**2


mask = np.zeros(image.shape[:2],dtype=np.bool)
for i in range(image.shape[0]):
    d_i = (i - center[0])**2
    
    for j in range(image.shape[1]):
        d_j = (j - center[1])**2
        
        # If this pixel is too far away from center mask it
        if d_i + d_j > sq_cutoff:
            mask[i,j] = True

Creates a mask that is False if pixel is inside the plate and True if something is outside the plate.

Apply mask

(Note cool different way to apply the mask).


In [ ]:
image[mask,:] = 255
plt.imshow(image)

Now check out scikit-image

Lay some ground work


In [ ]:
# Convert image to grayscale
image_gray = rgb2gray(image)
plt.imshow(image_gray,cmap="gray")

In [ ]:
def plot_blobs(img,blobs):
    """
    Plot a set of blobs on an image.
    """
    
    fig = plt.figure()
    ax = fig.add_subplot(1,1,1) 

    ax.imshow(img, interpolation='nearest')
    for blob in blobs:
        y, x, r = blob
        c = plt.Circle((x, y), r, color="red", linewidth=2, fill=False)
        ax.add_patch(c)

In [ ]:
# blob_log
blobs_log = blob_log(image_gray, max_sigma=30, num_sigma=10, threshold=.1)
blobs_log[:, 2] = blobs_log[:, 2] * np.sqrt(2)
        
plot_blobs(image,blobs_log)

In [ ]:
# blob_dog
blobs_dog = blob_dog(image_gray, max_sigma=30, threshold=.1)
blobs_dog[:, 2] = blobs_dog[:, 2] * np.sqrt(2)

plot_blobs(image,blobs_dog)

In [ ]:
# blob_doh
blobs_doh = blob_doh(image_gray, max_sigma=30, threshold=.01)
plot_blobs(image,blobs_doh)

Caveat LOG and DOG methods assume you are looking for bright spots. We could improve by inverting image. (but it was slow for demo)

Get rid of big blobs

  • Write a function that gets rid of any blob with a radius bigger than 15. Each blob is a tuple:

    blob1 = (y,x,r)


In [ ]:

Now get the color of each blob


In [ ]:


In [ ]:
blob_colors = []
for b in new_blobs:
    blob_colors.append(get_blob_color(image,b))

Write a function that only takes a blob with an R channel less than 100


In [ ]:


In [ ]:
def plot_colored_results(img,blobs,colors):

    fig = plt.figure()
    ax = fig.add_subplot(1,1,1) 

    ax.imshow(img, interpolation='nearest')
    for i, blob in enumerate(blobs):
        y, x, r = blob
        
        if colors[i][0] < 100:
            color = "green"
        else:
            color = "gray"
        
        c = plt.Circle((x, y), r, color=color, linewidth=2, fill=False)
        ax.add_patch(c)

In [ ]:
plt.imshow(image)
plot_colored_results(image,new_blobs,blob_colors)

In [ ]:


In [ ]: