高斯滤波后合并接近的物体
Merging close objects after gaussian filter
我试图计算图像中的对象数量,并从另一个问题中偶然发现了以下代码,我将它应用到我的示例图像上,如下所示:
import numpy
import matplotlib.pyplot as plt
from scipy import misc, ndimage
from skimage import feature
from skimage.filters import roberts, sobel
im = misc.imread('/home/nvp/temp/kaw.png',flatten=True)
im = im.astype('int32')
edges1 = feature.canny(im, sigma=3)
plt.imshow(edges1,interpolation='nearest')
dx = ndimage.sobel(im, 1) # horizontal derivative
dy = ndimage.sobel(im, 0) # vertical derivative
mag = numpy.hypot(dx, dy) # magnitude
mag *= 255.0 / numpy.max(mag)
dna = mag
dnaf = ndimage.gaussian_filter(dna, 7)
T = 27 # set threshold by hand to avoid installing `mahotas` or
# `scipy.stsci.image` dependencies that have threshold() functions
# find connected components
labeled, nr_objects = ndimage.label(dnaf > T) # `dna[:,:,0]>T` for red-dot case
print(dnaf, labeled,len(labeled))
print("Number of objects is %d " % nr_objects)
# show labeled image
####scipy.misc.imsave('labeled_dna.png', labeled)
####scipy.misc.imshow(labeled) # black&white image
import matplotlib.pyplot as plt
plt.imsave('labeled_dna.png', labeled)
plt.imshow(labeled)
plt.show()
然而它输出如下图像:
最终对象存储在 labeled
np.array 我想,我想做的是合并此输出数组中的关闭对象。如您所见,最后一行的第二个对象有两个部分,但它们彼此非常接近。
由于我不知道 numpy ,我想要一种方法来设置阈值并合并它们之间距离较小的对象。任何帮助表示赞赏。谢谢:)
您要合并的两个对象与第一行的对象 3 和 4 一样接近...因此仅基于对象之间的接近度的解决方案不会给您想要的结果。
一个解决方案可能是 dilate 根据对象的面积(扩大更多小对象)。
示例(未测试):
import scipy.ndimage.morphology as morpho
# parameters
max_dilat = 20 # dilation (in number of pixels) for a small object
sz_small = 100 # size of a small object (max dilated)
sz_big = 10000 # size of a big object (not dilated)
result = labeled*0
# for each detected object
for obj_id in range(1, nr_objects+1):
# creates a binary image with the current object
obj_img = (labeled==obj_id)
# computes object's area
area = numpy.sum(obj_img)
# dilatation factor inversely proportional to area
dfac = int( max_dilat*(1-min(1,(max(0,area-sz_small)/sz_big))) )
# dilates object
dilat = morpho.binary_dilation(obj_img, iterations=dfac)
result += dilat
# result is now an int array with ones where you have a single
# dilated object, and twos (or more) in overlapping parts
labeled, nr_objects = ndimage.label(result>0)
我试图计算图像中的对象数量,并从另一个问题中偶然发现了以下代码,我将它应用到我的示例图像上,如下所示:
import numpy
import matplotlib.pyplot as plt
from scipy import misc, ndimage
from skimage import feature
from skimage.filters import roberts, sobel
im = misc.imread('/home/nvp/temp/kaw.png',flatten=True)
im = im.astype('int32')
edges1 = feature.canny(im, sigma=3)
plt.imshow(edges1,interpolation='nearest')
dx = ndimage.sobel(im, 1) # horizontal derivative
dy = ndimage.sobel(im, 0) # vertical derivative
mag = numpy.hypot(dx, dy) # magnitude
mag *= 255.0 / numpy.max(mag)
dna = mag
dnaf = ndimage.gaussian_filter(dna, 7)
T = 27 # set threshold by hand to avoid installing `mahotas` or
# `scipy.stsci.image` dependencies that have threshold() functions
# find connected components
labeled, nr_objects = ndimage.label(dnaf > T) # `dna[:,:,0]>T` for red-dot case
print(dnaf, labeled,len(labeled))
print("Number of objects is %d " % nr_objects)
# show labeled image
####scipy.misc.imsave('labeled_dna.png', labeled)
####scipy.misc.imshow(labeled) # black&white image
import matplotlib.pyplot as plt
plt.imsave('labeled_dna.png', labeled)
plt.imshow(labeled)
plt.show()
然而它输出如下图像:
最终对象存储在 labeled
np.array 我想,我想做的是合并此输出数组中的关闭对象。如您所见,最后一行的第二个对象有两个部分,但它们彼此非常接近。
由于我不知道 numpy ,我想要一种方法来设置阈值并合并它们之间距离较小的对象。任何帮助表示赞赏。谢谢:)
您要合并的两个对象与第一行的对象 3 和 4 一样接近...因此仅基于对象之间的接近度的解决方案不会给您想要的结果。
一个解决方案可能是 dilate 根据对象的面积(扩大更多小对象)。
示例(未测试):
import scipy.ndimage.morphology as morpho
# parameters
max_dilat = 20 # dilation (in number of pixels) for a small object
sz_small = 100 # size of a small object (max dilated)
sz_big = 10000 # size of a big object (not dilated)
result = labeled*0
# for each detected object
for obj_id in range(1, nr_objects+1):
# creates a binary image with the current object
obj_img = (labeled==obj_id)
# computes object's area
area = numpy.sum(obj_img)
# dilatation factor inversely proportional to area
dfac = int( max_dilat*(1-min(1,(max(0,area-sz_small)/sz_big))) )
# dilates object
dilat = morpho.binary_dilation(obj_img, iterations=dfac)
result += dilat
# result is now an int array with ones where you have a single
# dilated object, and twos (or more) in overlapping parts
labeled, nr_objects = ndimage.label(result>0)