我有一幅显示一些对象的图像,其中一个对象始终位于另一个对象内部.
背景始终为黑色.
我想知道两个物体的周长并找到解决方案.
我使用滤核来获取每个像素的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.