Added CellProfiler sobel and prewitt functions.

This commit is contained in:
Pieter Holtzhausen
2011-04-18 00:17:48 +02:00
parent 6156182600
commit 8a35b3f950
4 changed files with 334 additions and 1 deletions
+1
View File
@@ -1,3 +1,4 @@
from lpi_filter import *
from ctmf import median_filter
from canny import canny
from edges import sobel, hsobel, vsobel, hprewitt, vprewitt, prewitt
+130
View File
@@ -0,0 +1,130 @@
'''edges.py - Sobel edge filter
Originally part of CellProfiler, code licensed under both GPL and BSD licenses.
Website: http://www.cellprofiler.org
Copyright (c) 2003-2009 Massachusetts Institute of Technology
Copyright (c) 2009-2011 Broad Institute
All rights reserved.
Original author: Lee Kamentsky
'''
import numpy as np
from scipy.ndimage import convolve, binary_erosion, generate_binary_structure
def sobel(image, mask=None):
'''Calculate the absolute magnitude Sobel to find the edges
image - image to process
mask - mask of relevant points
Take the square root of the sum of the squares of the horizontal and
vertical Sobels to get a magnitude that's somewhat insensitive to
direction.
Note that scipy's Sobel returns a directional Sobel which isn't
useful for edge detection in its raw form.
'''
return np.sqrt(hsobel(image,mask)**2 + vsobel(image,mask)**2)
def hsobel(image, mask=None):
'''Find the horizontal edges of an image using the Sobel transform
image - image to process
mask - mask of relevant points
We use the following kernel and return the absolute value of the
result at each point:
1 2 1
0 0 0
-1 -2 -1
'''
if mask == None:
mask = np.ones(image.shape, bool)
big_mask = binary_erosion(mask,
generate_binary_structure(2,2),
border_value = 0)
result = np.abs(convolve(image, np.array([[ 1, 2, 1],
[ 0, 0, 0],
[-1,-2,-1]]).astype(float)/4.0))
result[big_mask==False] = 0
return result
def vsobel(image, mask=None):
'''Find the vertical edges of an image using the Sobel transform
image - image to process
mask - mask of relevant points
We use the following kernel and return the absolute value of the
result at each point:
1 0 -1
2 0 -2
1 0 -1
'''
if mask == None:
mask = np.ones(image.shape, bool)
big_mask = binary_erosion(mask,
generate_binary_structure(2,2),
border_value = 0)
result = np.abs(convolve(image, np.array([[ 1, 0,-1],
[ 2, 0,-2],
[ 1, 0,-1]]).astype(float)/4.0))
result[big_mask==False] = 0
return result
def prewitt(image, mask=None):
'''Find the edge magnitude using the Prewitt transform
image - image to process
mask - mask of relevant points
Return the square root of the sum of squares of the horizontal
and vertical Prewitt transforms.
'''
return np.sqrt(hprewitt(image,mask)**2 + vprewitt(image,mask)**2)
def hprewitt(image, mask=None):
'''Find the horizontal edges of an image using the Prewitt transform
image - image to process
mask - mask of relevant points
We use the following kernel and return the absolute value of the
result at each point:
1 1 1
0 0 0
-1 -1 -1
'''
if mask == None:
mask = np.ones(image.shape, bool)
big_mask = binary_erosion(mask,
generate_binary_structure(2,2),
border_value = 0)
result = np.abs(convolve(image, np.array([[ 1, 1, 1],
[ 0, 0, 0],
[-1,-1,-1]]).astype(float)/3.0))
result[big_mask==False] = 0
return result
def vprewitt(image, mask=None):
'''Find the vertical edges of an image using the Prewitt transform
image - image to process
mask - mask of relevant points
We use the following kernel and return the absolute value of the
result at each point:
1 0 -1
1 0 -1
1 0 -1
'''
if mask == None:
mask = np.ones(image.shape, bool)
big_mask = binary_erosion(mask,
generate_binary_structure(2,2),
border_value = 0)
result = np.abs(convolve(image, np.array([[ 1, 0,-1],
[ 1, 0,-1],
[ 1, 0,-1]]).astype(float)/3.0))
result[big_mask==False] = 0
return result
+201
View File
@@ -0,0 +1,201 @@
from numpy.testing import *
import numpy as np
from scipy.ndimage import binary_dilation, binary_erosion
import scikits.image.filter as F
class TestSobel():
def test_00_00_zeros(self):
'''Sobel on an array of all zeros'''
result = F.sobel(np.zeros((10,10)), np.ones((10,10),bool))
assert (np.all(result==0))
def test_00_01_mask(self):
'''Sobel on a masked array should be zero'''
np.random.seed(0)
result = F.sobel(np.random.uniform(size=(10,10)),
np.zeros((10,10),bool))
assert (np.all(result == 0))
def test_01_01_horizontal(self):
'''Sobel on an edge should be a horizontal line'''
i,j = np.mgrid[-5:6,-5:6]
image = (i>=0).astype(float)
result = F.sobel(image)
# Fudge the eroded points
i[np.abs(j)==5] = 10000
assert (np.all(result[i==0] == 1))
assert (np.all(result[np.abs(i) > 1] == 0))
def test_01_02_vertical(self):
'''Sobel on a vertical edge should be a vertical line'''
i,j = np.mgrid[-5:6,-5:6]
image = (j>=0).astype(float)
result = F.sobel(image)
j[np.abs(i)==5] = 10000
assert (np.all(result[j==0] == 1))
assert (np.all(result[np.abs(j) > 1] == 0))
class TestHSobel():
def test_00_00_zeros(self):
'''Horizontal sobel on an array of all zeros'''
result = F.hsobel(np.zeros((10,10)), np.ones((10,10),bool))
assert (np.all(result==0))
def test_00_01_mask(self):
'''Horizontal Sobel on a masked array should be zero'''
np.random.seed(0)
result = F.hsobel(np.random.uniform(size=(10,10)),
np.zeros((10,10),bool))
assert (np.all(result == 0))
def test_01_01_horizontal(self):
'''Horizontal Sobel on an edge should be a horizontal line'''
i,j = np.mgrid[-5:6,-5:6]
image = (i>=0).astype(float)
result = F.hsobel(image)
# Fudge the eroded points
i[np.abs(j)==5] = 10000
assert (np.all(result[i==0] == 1))
assert (np.all(result[np.abs(i) > 1] == 0))
def test_01_02_vertical(self):
'''Horizontal Sobel on a vertical edge should be zero'''
i,j = np.mgrid[-5:6,-5:6]
image = (j>=0).astype(float)
result = F.hsobel(image)
assert (np.all(result == 0))
class TestVSobel():
def test_00_00_zeros(self):
'''Vertical sobel on an array of all zeros'''
result = F.vsobel(np.zeros((10,10)), np.ones((10,10),bool))
assert (np.all(result==0))
def test_00_01_mask(self):
'''Vertical Sobel on a masked array should be zero'''
np.random.seed(0)
result = F.vsobel(np.random.uniform(size=(10,10)),
np.zeros((10,10),bool))
assert (np.all(result == 0))
def test_01_01_vertical(self):
'''Vertical Sobel on an edge should be a vertical line'''
i,j = np.mgrid[-5:6,-5:6]
image = (j>=0).astype(float)
result = F.vsobel(image)
# Fudge the eroded points
j[np.abs(i)==5] = 10000
assert (np.all(result[j==0] == 1))
assert (np.all(result[np.abs(j) > 1] == 0))
def test_01_02_horizontal(self):
'''vertical Sobel on a horizontal edge should be zero'''
i,j = np.mgrid[-5:6,-5:6]
image = (i>=0).astype(float)
result = F.vsobel(image)
eps = .000001
assert (np.all(np.abs(result) < eps))
class TestPrewitt():
def test_00_00_zeros(self):
'''Prewitt on an array of all zeros'''
result = F.prewitt(np.zeros((10,10)), np.ones((10,10),bool))
assert (np.all(result==0))
def test_00_01_mask(self):
'''Prewitt on a masked array should be zero'''
np.random.seed(0)
result = F.prewitt(np.random.uniform(size=(10,10)),
np.zeros((10,10),bool))
eps = .000001
assert (np.all(np.abs(result) < eps))
def test_01_01_horizontal(self):
'''Prewitt on an edge should be a horizontal line'''
i,j = np.mgrid[-5:6,-5:6]
image = (i>=0).astype(float)
result = F.prewitt(image)
# Fudge the eroded points
i[np.abs(j)==5] = 10000
eps = .000001
assert (np.all(result[i==0] == 1))
assert (np.all(np.abs(result[np.abs(i) > 1]) < eps))
def test_01_02_vertical(self):
'''Prewitt on a vertical edge should be a vertical line'''
i,j = np.mgrid[-5:6,-5:6]
image = (j>=0).astype(float)
result = F.prewitt(image)
eps = .000001
j[np.abs(i)==5] = 10000
assert (np.all(result[j==0] == 1))
assert (np.all(np.abs(result[np.abs(j) > 1]) < eps))
class TestHPrewitt():
def test_00_00_zeros(self):
'''Horizontal sobel on an array of all zeros'''
result = F.hprewitt(np.zeros((10,10)), np.ones((10,10),bool))
assert (np.all(result==0))
def test_00_01_mask(self):
'''Horizontal prewitt on a masked array should be zero'''
np.random.seed(0)
result = F.hprewitt(np.random.uniform(size=(10,10)),
np.zeros((10,10),bool))
eps = .000001
assert (np.all(np.abs(result) < eps))
def test_01_01_horizontal(self):
'''Horizontal prewitt on an edge should be a horizontal line'''
i,j = np.mgrid[-5:6,-5:6]
image = (i>=0).astype(float)
result = F.hprewitt(image)
# Fudge the eroded points
i[np.abs(j)==5] = 10000
eps = .000001
assert (np.all(result[i==0] == 1))
assert (np.all(np.abs(result[np.abs(i) > 1]) < eps))
def test_01_02_vertical(self):
'''Horizontal prewitt on a vertical edge should be zero'''
i,j = np.mgrid[-5:6,-5:6]
image = (j>=0).astype(float)
result = F.hprewitt(image)
eps = .000001
assert (np.all(np.abs(result) < eps))
class TestVPrewitt():
def test_00_00_zeros(self):
'''Vertical prewitt on an array of all zeros'''
result = F.vprewitt(np.zeros((10,10)), np.ones((10,10),bool))
assert (np.all(result==0))
def test_00_01_mask(self):
'''Vertical prewitt on a masked array should be zero'''
np.random.seed(0)
result = F.vprewitt(np.random.uniform(size=(10,10)),
np.zeros((10,10),bool))
assert (np.all(result == 0))
def test_01_01_vertical(self):
'''Vertical prewitt on an edge should be a vertical line'''
i,j = np.mgrid[-5:6,-5:6]
image = (j>=0).astype(float)
result = F.vprewitt(image)
# Fudge the eroded points
j[np.abs(i)==5] = 10000
assert (np.all(result[j==0] == 1))
eps = .000001
assert (np.all(np.abs(result[np.abs(j) > 1]) < eps))
def test_01_02_horizontal(self):
'''vertical prewitt on a horizontal edge should be zero'''
i,j = np.mgrid[-5:6,-5:6]
image = (i>=0).astype(float)
result = F.vprewitt(image)
eps = .000001
assert (np.all(np.abs(result) < eps))
if __name__ == "__main__":
run_module_suite()
+2 -1
View File
@@ -1 +1,2 @@
version='unbuilt-dev'
# THIS FILE IS GENERATED FROM THE SCIKITS.IMAGE SETUP.PY
version='0.3dev'