You're an aspiring computational biologist, working with some alveolar (lung) cells to study some of the cellular machinery involved in disease progression. You've tagged the proteins you're interested in, run your experiment, and collected your data from the confocal microscope in your advisor's lab.
Unfortunately, someone didn't properly secure the confocal microscope, because some dust or something got shaken loose during your imaging slot and it seems to have corrupted your images!
You don't have enough time to completely re-do the experiments, so you'll need to use your computational skills to clean up the data post-acquisition.
The scipy.ndimage
submodule has lots of "filters" you can use to process your images. In the lecture we saw how the Gaussian filter worked for smoothing; we'll use that again here, in addition to a median filter.
The functions you'll want to use are ndimage.gaussian_filter
and ndimage.median_filter
. Check out their respective documentation pages to see how to use them.
The upshot is both functions have 2 required arguments: the first is the image (of course), and the second is an integer that indicates the filter size; for the Gaussian filter, this argument is sigma
; for the median filter, this argument is size
.
Experiment with both filters, and with a few filter sizes. Plot the results of your filters using plt.imshow()
, which has already been imported for you. Make sure you post the results!
In [ ]:
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
import scipy.ndimage as ndimage
img = ndimage.imread("noisy.png", flatten = True)
### BEGIN SOLUTION
### END SOLUTION
Use your function from Question 1, Part B to count the number of cells in this image.
Write a function which:
count_cells
It's pretty much the same deal as Part B on the last question, except this time we're also performing a median filter on the image to try and get rid of some of the noise in the image.
The threshold procedure is also different. Before, you simply set any pixel below a certain value to 0. In this case, you're still doing that, but in addition you will also set all other pixels to 1. This is known as binarization: every pixel in the entire image is either a 1 or a 0.
You can use scipy.ndimage
, skimage
, numpy
, and matplotlib
, but no other built-in functions or imported Python packages.
In [ ]:
In [ ]:
import scipy.ndimage as ndimage
img = ndimage.imread("noisy.png", flatten = True)
t1 = 30
s1 = 5
a1 = 33
assert a1 == count_cells(img, s1, t1)
In [ ]:
img = ndimage.imread("noisy.png", flatten = True)
t2 = 30
s2 = 20
a2 = 21
assert a2 == count_cells(img, s2, t2)
In [ ]:
img = ndimage.imread("noisy.png", flatten = True)
t3 = 100
s3 = 5
a3 = 97
assert a3 == count_cells(img, s3, t3)
In [ ]:
img = ndimage.imread("noisy.png", flatten = True)
t4 = 100
s4 = 20
a4 = 21
assert a4 == count_cells(img, s4, t4)
Using the function you created in the previous question, re-run the cell counter, but this time on the original noisy image. Run it a few times, changing the pixel threshold you set (but using the original noisy image each time). How does the number of objects your function finds change with the pixel threshold?
Now run it on a filtered image, but change the filter size. Make it really small and count the number of objects. Make it really large and count the number of objects. Keep the pixel threshold constant for this. How does the number of objects your function finds change with the filter size?
Put your code in the box below, and write your responses in the box below that.
In [ ]: