scikit-image
is a pretty awesome all-purpose lightweight image analysis package for Python. In this part, you'll write a function to help prepare an image for analysis.
In the first step, you'll need to convert the image to a grayscale format that is amenable to use by the rest of the scikit-image API. Write a function which:
to_grayscale_uint
(for "unsigned integer")You can't use any built-in Python functions or imports beyond NumPy and skimage.color
; you're welcome to use Matplotlib as well for debugging your code.
Some relevant hints:
skimage.color
subpackage for some useful conversion functions.np.uint8
(for 8-bit unsigned integer).np.array
function takes an option argument dtype
to specify the type of the underlying array.
In [ ]:
In [ ]:
import numpy as np
import skimage.data
q1 = np.load("coffee_gray.npy")
np.testing.assert_allclose(to_grayscale_uint(skimage.data.coffee()), q1)
In [ ]:
q2 = np.load("chelsea_gray.npy")
np.testing.assert_allclose(to_grayscale_uint(skimage.data.chelsea()), q2)
Next, you'll write some code to start segmenting the 8-bit grayscale image. This will involve thresholding it, applying a possible smoothing filter, and connecting the objects that remain.
Write a function which:
segment
None
)To do the object connecting, you'll need to look at the skimage.measure.label
function.
You can assume that the image your function receives is effectively the output of your Part A function above (i.e. it's already in grayscale, and has pixel values that range from 0 to 255). Your job is to
None
)The third item comes from the aforementioned skimage.measure.label
function. That function can return the number of objects (which is what your function is supposed to return, too), but take careful notice of how to activate this ability, as it is turned OFF by default.
You can't use any built-in Python functions or other imports aside from skimage
and numpy
, though you may use matplotlib
to debug.
In [ ]:
In [ ]:
import numpy as np
img1 = np.load("chelsea_gray.npy")
obj1 = 91585
assert obj1 == segment(img1)
In [ ]:
img1 = np.load("chelsea_gray.npy")
obj2 = 88223
t1 = 50
assert obj2 == segment(img1, t1)
In [ ]:
img2 = np.load("ihc_gray.npy")
obj3 = 217299
assert obj3 == segment(img2)
In [ ]:
img2 = np.load("ihc_gray.npy")
obj4 = 76677
t2 = 180
assert obj4 == segment(img2, t2)
In [ ]:
img3 = np.load("coffee_gray.npy")
obj5 = 150792
assert obj5 == segment(img3)
In this part, you'll use the function you wrote in Part B to compute some properties of the objects that are revealed using the skimage.measure.label
output.
Your goal is to find the object with the largest area, and return a ratio of that object's other properties. Write a function which:
ratio_largest_area
None
)Yes, this takes the same arguments as the function you wrote in Part B. You'll need to perform the same operations, but instead of computing the number of objects, you'll need the other output from the skimage.measure.label
function: the actual labeled array.
After thresholding the input image (or not) and determining the labeled array, you'll need to feed that array to the skimage.measure.regionprops
function. This computes a variety of properties on each object that's found by the label
function.
In this list of region properties, find the one with the largest area. Then, take that region's minor and major axis lengths, and create the ratio:
$$ \frac{minor}{major} $$This should be somewhere between 0 and 1. Your function should return that ratio.
You can use loops (len
and range
, though you shouldn't really need them), NumPy, and scikit-image. Nothing else.
In [ ]:
In [ ]:
import numpy as np
img1 = np.load("ihc_gray.npy")
rat1 = 0.4251056202959775
np.testing.assert_allclose(ratio_largest_area(img1), rat1)
In [ ]:
img1 = np.load("ihc_gray.npy")
t1 = 240
rat2 = 0.38196601125010504
np.testing.assert_allclose(ratio_largest_area(img1, t1), rat2)
In [ ]:
img2 = np.load("chelsea_gray.npy")
t2 = 50
rat3 = 0.7494253874318644
np.testing.assert_allclose(ratio_largest_area(img2, t2), rat3)