首页 文章

如何检测和绘制asc文件的强度

提问于
浏览
1

我有火焰照片 - 数据作为包含像素矩阵的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)

结果:
plotted image

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

  • 从最大强度到36000(红色区域)

  • 从最大强度到27000(黄区)

  • 从最大强度到12000(蓝色区域)

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

结果必须看起来像
wanted result

1 回答

  • 2

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


    为方便起见,我会形成一个 3D ndarray of your image sequences ,这样任何操作都可以用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数组,所以让我们得到 range images

    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视图,用于绘图 .


    现在简单/有趣的部分: labeling !我们可以用 scipy.ndimage.measurements.label()

    from scipy.ndimage import label
    labelsRed, nbLabelsRed = label(boolMaskRedzone)
    

    labelsRed现在是一个以int作为标签索引的数组 .

    理想情况下,我们会有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
    

    至于计算顶部/最底部的像素,如果你想让这条线成为对角线,它会变得很棘手,但是如果你只想要顶部/底部(与图像轴对齐),你可以在每个面具变为True时进行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:对于我的另一个项目我是've been researching some more of scipy'的ndimage函数,并且有适合你的东西:ndimage.center_of_mass() .

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

相关问题