我有很多三个物体的图像,白色背景被白色空间隔开。例如,
是否可以将此图像(以及类似图像)自动分割为三个图像?如果这也可以从命令行工作,那将会很棒。
答案 0 :(得分:1)
正如@ypnos所说,你想通过求和或平均来折叠行。这将为您留下图像宽度的向量。接下来将所有内容剪辑到高阈值以下,记住高数字对应于高亮度。这将选择空白区域:
然后,您只需对其余索引进行聚类并选择中间的两个聚类(因为外部两个聚类属于边界白色空间)。在python中看起来像这样:
import sklearn.cluster, PIL.Image, numpy, sys, os.path
# import matplotlib.pyplot as plt
def split(fn, thresh=200):
img = PIL.Image.open(fn)
dat = numpy.array(img.convert(mode='L'))
h, w = dat.shape
dat = dat.mean(axis=0)
# plt.plot(dat*(dat>thresh);
path, fname = os.path.split(fn)
fname = os.path.basename(fn)
base, ext = os.path.splitext(fname)
guesses = numpy.matrix(numpy.linspace(0, len(dat), 4)).T
km = sklearn.cluster.KMeans(n_clusters=2, init=guesses)
km.fit(numpy.matrix(numpy.nonzero(dat>thresh)).T)
c1, c2 = map(int, km.cluster_centers_[[1,2]])
img.crop((0, 0, c1, h)).save(path + '/' + base + '_1' + ext)
img.crop((c1, 0, c2, h)).save(path + '/' + base + '_2' + ext)
img.crop((c2, 0, w, h)).save(path + '/' + base + '_3' + ext)
if __name__ == "__main__":
split(sys.argv[1], int(sys.argv[2]))
该方法的一个缺点是它可能在具有明亮物体的图像上发现绊倒(未能正确地识别白色空间),或者没有被干净的垂直线分开(例如,在复合物中重叠)。在这种情况下,不受垂直线约束的线检测将更好地工作。我将其实施给其他人。
答案 1 :(得分:0)
您需要对图像中的每一列进行总结,并将总和与该列中所有像素的理论总和进行比较(即,#lines乘以255)。将符合条件的所有列添加到索引列表中。如果对象之间并不总是完全清晰的线条(例如由于压缩失真),您可以设置较低的阈值而不是全白色的总和。
现在浏览一下索引列表。删除从第一列开始的所有相邻索引。同时删除以图像最右侧结尾的所有相邻索引。创建彼此相邻的索引组。在每组中计算指数的数量并计算平均指数。
现在取两个最大的群体,取其平均值作为裁剪位置的指标。
您可以使用OpenCV或C ++ OpenCV程序在Python中使用相当小的脚本执行此操作。