fei*_*ann 23 python numpy image scipy
from PIL import Image
import numpy as np
from scipy.ndimage.filters import maximum_filter
import pylab
# the picture (256 * 256 pixels) contains bright spots of which I wanna get positions
# problem: data has high background around value 900 - 1000
im = Image.open('slice0000.png')
data = np.array(im)
# as far as I understand, data == maximum_filter gives True-value for pixels
# being the brightest in their neighborhood (here 10 * 10 pixels)
maxima = (data == maximum_filter(data,10))
# How can I get only maxima, outstanding the background a certain value, let's say 500 ?
Run Code Online (Sandbox Code Playgroud)
我恐怕我不太了解这个scipy.ndimage.filters.maximum_filter()功能.有没有办法只在斑点内而不是在背景中获得像素坐标?
http://i.stack.imgur.com/RImHW.png(16位灰度图片,256*256像素)
unu*_*tbu 52
import numpy as np
import scipy
import scipy.ndimage as ndimage
import scipy.ndimage.filters as filters
import matplotlib.pyplot as plt
fname = '/tmp/slice0000.png'
neighborhood_size = 5
threshold = 1500
data = scipy.misc.imread(fname)
data_max = filters.maximum_filter(data, neighborhood_size)
maxima = (data == data_max)
data_min = filters.minimum_filter(data, neighborhood_size)
diff = ((data_max - data_min) > threshold)
maxima[diff == 0] = 0
labeled, num_objects = ndimage.label(maxima)
slices = ndimage.find_objects(labeled)
x, y = [], []
for dy,dx in slices:
x_center = (dx.start + dx.stop - 1)/2
x.append(x_center)
y_center = (dy.start + dy.stop - 1)/2
y.append(y_center)
plt.imshow(data)
plt.savefig('/tmp/data.png', bbox_inches = 'tight')
plt.autoscale(False)
plt.plot(x,y, 'ro')
plt.savefig('/tmp/result.png', bbox_inches = 'tight')
Run Code Online (Sandbox Code Playgroud)
给出data.png:

上述程序产率result.png用threshold = 1500.降低threshold以获取更多局部最大值:

参考文献:
小智 12
import numpy as np
import scipy
import scipy.ndimage as ndimage
import scipy.ndimage.filters as filters
import matplotlib.pyplot as plt
fname = '/tmp/slice0000.png'
neighborhood_size = 5
threshold = 1500
data = scipy.misc.imread(fname)
data_max = filters.maximum_filter(data, neighborhood_size)
maxima = (data == data_max)
data_min = filters.minimum_filter(data, neighborhood_size)
diff = ((data_max - data_min) > threshold)
maxima[diff == 0] = 0
labeled, num_objects = ndimage.label(maxima)
xy = np.array(ndimage.center_of_mass(data, labeled, range(1, num_objects+1)))
plt.imshow(data)
plt.savefig('/tmp/data.png', bbox_inches = 'tight')
plt.autoscale(False)
plt.plot(xy[:, 1], xy[:, 0], 'ro')
plt.savefig('/tmp/result.png', bbox_inches = 'tight')
Run Code Online (Sandbox Code Playgroud)
上一个条目对我来说非常有用,但for循环减慢了我的应用程序.我发现ndimage.center_of_mass()可以很快地获得坐标...因此这个建议.
现在可以使用 skimage 完成此操作。
from skimage.feature import peak_local_max
xy = peak_local_max(data, min_distance=2,threshold_abs=1500)
Run Code Online (Sandbox Code Playgroud)
在我的计算机上,对于 VGA 图像大小,它的运行速度比上述解决方案快 4 倍,并且在某些情况下还返回了更准确的位置。
| 归档时间: |
|
| 查看次数: |
28686 次 |
| 最近记录: |