如何检测和绘制 asc 文件的强度
How detect and plot intensity of asc file
我有一张火焰照片 - 数据为包含像素矩阵的 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 个范围内绘制图像:
- 从最大强度到 36000(红色区域)
- 从最大强度到 27000(黄色区域)
- 从最大强度到 12000(蓝色区域)
并检测最底部和顶部的像素?
还有最左和最右像素?
然后用线连接顶部和底部像素。
左右像素需要相同的东西。
如何显示直线上的像素距离?
结果一定是这样的
您似乎想要图像的阈值版本,然后在阈值上标记区域,然后再进行一些奇特的测量。
为了方便起见,我会形成一个 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
这些现在是与您的图像大小相同但布尔值的蒙版。让我们 fiddle :
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,如果不是,"islands" 可以用
关闭
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
至于计算 top/bottommost 像素,如果您希望这条线是对角线,它可能会变得棘手,但如果您只想要顶部/底部(与图像轴对齐),您可以进行 numpy 检查当每个轴的掩码变为 True 时,这显然是在数组和偏移版本之间进行差异(推导),然后是每个轴上的第一个非零元素
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 度角的线会怎样?它会变成 "top-bottom" 还是 "left-right" ?或者你想要最长的线接近水平?或者你想要双正交测量? (选择最大的线作为第一次测量,第二条直径线是与第一条线成 90 度的任何长度)
假设你在图像中有你的点,绘图只是一个线图 plt.plot =)
我不得不承认我并没有想太多推导部分,但我认为一旦你有了标签,你就会成为一个快乐的露营者 =)
EDIT :当然,所有这些操作都可以通过遍历数组直接计算,但我只发布了产生使用 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 的编译函数和硬件加速函数相比,这种循环嵌套 非常 慢(有关 python/numpy 上的速度演示,请参见 http://www.astro.washington.edu/users/vanderplas/Astr599/notebooks/11_EfficientNumpy )
编辑 2:
对于我的另一个项目,我一直在研究更多 scipy 的 ndimage 函数,这里有适合您的东西:ndimage.center_of_mass().
此函数在(可能标记的)数组中找到质心。
通过找到标记数组的质心,您可以从轴的中心找到对角线,其余的只是小菜一碟 ^^
我有一张火焰照片 - 数据为包含像素矩阵的 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 个范围内绘制图像:
- 从最大强度到 36000(红色区域)
- 从最大强度到 27000(黄色区域)
- 从最大强度到 12000(蓝色区域)
并检测最底部和顶部的像素? 还有最左和最右像素? 然后用线连接顶部和底部像素。 左右像素需要相同的东西。 如何显示直线上的像素距离?
结果一定是这样的
您似乎想要图像的阈值版本,然后在阈值上标记区域,然后再进行一些奇特的测量。
为了方便起见,我会形成一个 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
这些现在是与您的图像大小相同但布尔值的蒙版。让我们 fiddle :
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,如果不是,"islands" 可以用
关闭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
至于计算 top/bottommost 像素,如果您希望这条线是对角线,它可能会变得棘手,但如果您只想要顶部/底部(与图像轴对齐),您可以进行 numpy 检查当每个轴的掩码变为 True 时,这显然是在数组和偏移版本之间进行差异(推导),然后是每个轴上的第一个非零元素
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 度角的线会怎样?它会变成 "top-bottom" 还是 "left-right" ?或者你想要最长的线接近水平?或者你想要双正交测量? (选择最大的线作为第一次测量,第二条直径线是与第一条线成 90 度的任何长度)
假设你在图像中有你的点,绘图只是一个线图 plt.plot =)
我不得不承认我并没有想太多推导部分,但我认为一旦你有了标签,你就会成为一个快乐的露营者 =)
EDIT :当然,所有这些操作都可以通过遍历数组直接计算,但我只发布了产生使用 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 的编译函数和硬件加速函数相比,这种循环嵌套 非常 慢(有关 python/numpy 上的速度演示,请参见 http://www.astro.washington.edu/users/vanderplas/Astr599/notebooks/11_EfficientNumpy )
编辑 2: 对于我的另一个项目,我一直在研究更多 scipy 的 ndimage 函数,这里有适合您的东西:ndimage.center_of_mass().
此函数在(可能标记的)数组中找到质心。 通过找到标记数组的质心,您可以从轴的中心找到对角线,其余的只是小菜一碟 ^^