您似乎想要图像的阈值版本,然后在阈值上标记区域,然后进行一些奇特的测量。
为方便起见,我会为您的图像序列形成一个 3D ndarray,这样任何操作都可以使用 numpy 一次性完成:
fileList = filter(lambda s: s.endswith(".asc"), os.listdir(path))
# open first image so we have its dimensions to initialize the array
firstImage = np.genfromtxt (path+fileList[0])
imageArray = np.zeros((len(filelist),) + firstImage.shape)
现在我们分配值
imageArray[0,:,:] = firstImage
for i,file in enumerate(filelist[1:]):
# skip the first item because we already have it
imageArray[i+1,:,:] = np.genfromtxt (path+file)
好的,现在我们有了您的图像的 3D 数组,让我们获取 范围图像
boolMaskRedzone = imageArray > 36000
boolMaskYellowzone = imageArray > 27000
boolMaskYellowzone = imageArray > 12000
这些现在是与您的图像大小相同但布尔值的掩码。让我们摆弄它:
redParts = image*boolMaskRedZone # images with 0 for thresholded values
plt.imshow(redParts[0,:,:],cmap="hot")
再次注意 redParts 和其他所有内容仍处于 3D 状态,因此我们制作了数组的 2D 视图以用于绘图。
现在是简单/有趣的部分:标签!
我们可以使用scipy.ndimage.measurements.label()
from scipy.ndimage import label
labelsRed, nbLabelsRed = label(boolMaskRedzone)
labelsRed 现在是一个以整数作为标签索引的数组。
理想情况下,我们应该有 nbLabelsRed == 1,如果没有,“岛屿”可以关闭
from scipy.ndimage import morphology
closedLabels = morphology.binary_closing(labelsRed)
# fiddle with the optional iterations parameter if needed
我们可以通过使用 np.where 给我们像素的位置,然后计算项目的数量来计算标签的面积 = 阈值区域:
x,y,z = np.where(labelsRed == 1) # x, y ,z are arrays
area = len(x) # the number of pixels that are brighter than red
至于计算顶部/底部像素,如果您希望线条是对角线,这可能会变得很棘手,但如果您只想要顶部/底部(与图像轴对齐),您可以在掩码变为时进行 numpy 检查每个轴都为真,这显然是在数组和偏移版本之间进行差异(推导),然后是沿每个轴的第一个非零元素
differenceArray = boolMaskRedZone - np.roll(boolMaskRedZone,1,axis=1)
# now check along each column when the array first becomes True
uselessImageIndex,xTopMostPixel,yTopMostPixel= numpy.where(differenceArray == True)
# found all the crossings and put them in 2 arrays
对于精确的对角线测量,您可能需要查看专门的图像测量库,例如scikit-image,它们可能有您想要的
如果你真的想自己做,我会推荐一些基于找到对象中心,然后计算对角线位置和测量最大长度的方法,但是如果你找到 45 度线会发生什么?它会变成“上下”还是“左右”?或者你想要最长的线接近水平?或者你想要双正交测量? (选择最大的线作为第一次测量,第二条直径线是与第一条线成 90 度的线的长度)
假设你在图像中有你的点,绘图只是一个带有 plt.plot =) 的线图
我不得不承认我没有仔细考虑推导部分,但我认为一旦你有了这个标签,你就会成为一个快乐的露营者 =)
编辑:当然,所有这些操作都可以通过迭代数组来直接计算,但我只发布了产生使用 numpy 的数组操作效率来做事情的单行代码的方法。
您确实可以通过
来完成每个操作
for x in range(image.shape[0]):
for y in range(image.shape[1]):
if(image[x,y] > 36000):
mask[x,y]=True
但与 numpy 的已编译和硬件加速函数相比,这种循环嵌套非常慢(请参阅 http://www.astro.washington.edu/users/vanderplas/Astr599/notebooks/11_EfficientNumpy 以获取有关 python/numpy 的速度演示)
编辑 2:
对于我的另一个项目,我一直在研究更多 scipy 的 ndimage 函数,并且有一些适合你的东西:ndimage.center_of_mass()。
此函数在(可能标记的)数组中找到质心。
通过找到标记数组的质心,您将可以从中找到对角线的轴中心,其余的只是小菜一碟^^