【问题标题】:How detect and plot intensity of asc file如何检测和绘制 asc 文件的强度
【发布时间】:2015-06-20 15:21:45
【问题描述】:

我有火焰的照片 - 数据作为包含像素矩阵的 asc 文件。每个像素中都有光强度值。

我的绘图代码:

import os
import numpy as np
import matplotlib.pyplot as plt
# Open a file
path = "input/"
dirs = os.listdir( path )
number_of_files = 0

# This would print all the files and directories
for file in dirs:
    if file.endswith(".asc"):
        img = np.genfromtxt (path+file)

        file = os.path.splitext(file)[0]
        #pasukamas vaizdas
        img = img.transpose ()
        # Just a figure and one subplot
        fig, ax = plt.subplots(1,figsize=(20,20))

        ax.set_title(file, fontsize=60, y=1.03)
        plt.imshow (img, interpolation='nearest', origin='lower')

        plt.colorbar ()
        plt.savefig ('output/' + file + '.png', bbox_inches = 'tight')

        number_of_files = number_of_files + 1
        plt.close(fig)
print (number_of_files)

结果:

如何在 3 个范围内绘制图像:

  1. 从最大强度到 36000(红色区域)
  2. 从最大强度到 27000(黄色区域)
  3. 从最大强度到 12000(蓝色区域)

并检测大多数底部和顶部像素? 也是最左右像素? 然后用线连接顶部和底部像素。 左右像素需要相同的东西。 如何在一条线上显示像素距离?

结果必须是这样的

【问题讨论】:

  • 查看stackoverflow.com/questions/27977303/… -- 请注意,示例代码定义了一个阈值,然后识别图像中满足该阈值的区域。这应该能让你继续前进。
  • 我重新标记你的问题,因为它主要是关于图像处理而不是绘图。

标签: python image-processing numpy matplotlib scipy


【解决方案1】:

您似乎想要图像的阈值版本,然后在阈值上标记区域,然后进行一些奇特的测量。


为方便起见,我会为您的图像序列形成一个 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()

此函数在(可能标记的)数组中找到质心。 通过找到标记数组的质心,您将可以从中找到对角线的轴中心,其余的只是小菜一碟^^

【讨论】:

  • 这是完美的答案!我会自己尝试代码。非常感谢!
  • 也许你可以提供更多帮助。我需要旋转图像 .asc 文件有行数,所以如果我旋转它,我会收到关于不适合形状的错误...我需要在整形数组时删除每行的第一位
  • 对 python 3 的事情感到抱歉,请告诉我哪些命令不喜欢我的语法(所以我会看看我缺少什么)嗯我不知道具体的 asc 文件(从未听说过的东西^^)但我从你的问题中得到的是你需要“翻译”你的数组(在这种情况下尝试np.roll(array,1,axis=1)),或者创建一个更小的数组,你可以通过编辑数组来做到这一点创建时的形状(在np.zeros 中)。我没听错吗?
  • 你可以看看我的新问题。 stackoverflow.com/questions/29720430/…
猜你喜欢
  • 2018-06-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多