【发布时间】:2018-06-24 09:45:18
【问题描述】:
我有一张显示一些对象的图像,其中一个对象总是在另一个对象之内。 背景总是黑色的。
我想知道两个物体的周长并找到一个解决方案。 我使用过滤器内核来获取每个像素的 4 邻域。然后我计算像素周围的零像素数。这给了我形状的像素单位的长度。如果中心像素是所需的颜色,我只计算这种情况。
from scipy import misc, ndimage
import numpy as np
import time
def get_circumference(arr, only=50, repl=50):
def c_length(values):
# 3rd value is the pixel
if values[2] == only:
return sum([x == 0 or (repl == 0 and x != only) for x in values[[0,1,3,4]]])
return 0
fp = np.array([[0, 1, 0], [1, 1, 1], [0, 1, 0]])
res = ndimage.generic_filter(arr, c_length, footprint=fp)
return np.sum(res, axis=None)
x = ndimage.imread("image.png", mode='L')
tic = time.time()
inner = get_circumference(x, only=255, repl=0)
outer = get_circumference(x, only=128, repl=128)
print("Inner object: {}, outer object: {}, took: {}".format(inner, outer, time.time() - tic))
给我:
Inner object: 510, outer object: 1054, took: 0.8387038707733154
它工作得很好。但这很慢。 单张图像大约需要 500 到 1000 毫秒。 由于我需要对数千张图像执行此操作,因此会花费太多时间。
有什么办法可以加快速度吗?我知道,图像将始终包含三种颜色,并且内部部分将始终被外部完全包围。此外,永远不会出现形状跨越图像边界的情况。
当然,实际计算周长有不同的方法。 给定一个像素,有两种可能的解决方案:1 或 4。 第一种方法只计算像素的数量,即单个像素计为单个周长单位。在后一种情况下,计算像素的实际边缘。 在我的解决方案中,我使用后一种方法来计算周长。 如果你只通过边缘检测和直方图来计算,你会得到第一个解决方案。
它由 8 个灰色像素和 1 个白色像素组成。 因此外圆周为 3+3+3+3 = 12,内圆周为 4。 按直方图计算的像素将改为 8 表示外部,1 表示内部。
【问题讨论】:
-
很酷的问题!请问您是否有给定图像的“正确答案”以供验证?图像在大小和格式方面是否具有代表性?您能否提供一两张其他示例图片 - 请同时附上您的正确答案?
-
@MarkSetchell 我更新了计数的方法,还添加了另一个例子(非常极端的情况)
-
请问大图的正确答案是什么?
标签: python numpy opencv image-processing scipy