我们知道,DigitalMicrograph中的内部变量虽然有点难以理解,但非常有用,特别是在图像处理方面,这比传统的for-循环要快得多。我想知道这些变量是否能够完成以下任务:
(1)对具有给定值范围的图像进行滤波。例如,逐像素检查图像,如果像素值介于5-10之间,则将像素设置为0。
(2)将三维数据立方体投影到二维图像中。例如,将所有能量通道投影到真实空间中的2D平面上,以获得平均图像(对于EDS或EELS频谱图像)。这实际上类似于DM中可用的“投影Z”函数。
在项目2D至1D线型的情况下,这可以通过以下方式实现:
image Projection := RealImage ("Integrated lineprofile", 4, sizeX, 1)
Projection [icol, 0] += Img_source它也有可能用于3D吗?
谢谢你的帮助。
发布于 2019-11-23 22:03:01
这些内在变量并没有什么真正的神秘之处。我会试着给你个机会
图像前兆
当您编写如下脚本时:
image img
img = 10在幕布后面的第二行,它真正做的是:
for (i=0; i<nPixels; i++)
img[i] = 10它迭代图像数组的所有像素(这是内存中nPixel值的一维列表,即使图像是2D或3D的),并将每个像素设置为10。
因此,如果您不使用10,而是使用不同的图像,如:
image img1, img2
img1 = img2它变成
for (i=0; i<nPixels; i++)
img1[i] = img2[i]img1的每个数组值都得到img2数组的相应值。因此,这两个图像必须是相同的大小,否则您将得到一个错误。实际上,尽管实际值是一维列表的值,解释器将检查维度的数量和尺寸是否相同。在这样的脚本代码中,不能将100x1图像设置为等于10x10图像。
本征变量入门
这些只不过是像素坐标位置的位置持有者.以icol为例。当计算时,它将被当前处理的像素的X坐标所取代。例如,脚本:
image img
img = icol真的变成
for (i=0; i<nPixels; i++)
img[i] = xCoordinate_of_pixel_i到目前为止,我们只在方程的右边使用icol,我们的“内部”for-循环遍历了左边图像的所有nPixels。但这不是一个条件。你也可以像你自己的例子那样在左手边使用icol,但是它是如何工作的呢?
为了工作,必须有一个明确的含义,icol。它必须清楚哪个像素的"x“坐标是指,以及有多少像素。或者,用其他术语来说:整个方程中的某些东西必须是一个固定大小的已知图像。(当然,所有固定大小的已知图像都必须大小相同,就像在简单的img1 = img2情况下一样。)
因此,我们不能写这样的东西:
img[icol,0] = 10但人们可以写这样的东西:
img1[icol,0] = img2 * icol它是如何“翻译”的呢?img2是已知大小的,所以在整个表达式中(- -只是方程的另一个词,因为它实际上不是数学意义上的方程。)-) icol指的是该图像和大小。然后,真正执行的代码变成:
for (i=0; i<nPixels_of_img2; i++)
img1[xCoordinate_of_pixel_i_of_img2,0] = img2[i] * xCoordinate_of_pixel_i_of_img2在上面,索引单个值[i]意味着仅取内存中数据的第一个值(这是一个1D列表),但是用两个[i,j]索引实际上是寻址在(x/y)=(i/j)上的像素。这对在内部转换为一维列表的“真实”位置,简单地由i + j * image_width。
但是现在再看一遍“翻译”代码:它需要什么才能不失败?好吧,就这一次:img1[xCoordinate_of_pixel_i_of_img2,0]必须存在。
img1必须有至少和img2一样大的宽度。
但即便如此,如果您仔细查看for-循环,您将注意到img1的值将被重写多次!img2的第一行将被设置为img1,但是循环继续,第二行img2的第一个值也被写入img1[xCoordinate_of_pixel_i_of_img2,0]!
(因为xCoordinate_of_pixel_i_of_img2在img2的第二行再次变为0。)
这正是为什么示例中的“投影”代码有效的原因,因为
Dst [icol, 0] += Src真正意味着
for (i=0; i<nPixels_of_Src; i++)
Dst[ xCoordinate_of_Src_of_pixel_i, 0 ] += src[i]也就是说,你是在一排排地加起来。
实际问题答案
( ad 1)
不,本征变量处理图像中的位置,而不是其强度值。但是,在脚本中,按值进行阈值处理甚至更简单。您只需要一个三元操作符(或'tert()‘命令,这是相同的。)
只需使用:
img = ( (img < 5) || (img > 10) ? img : 0 )
或相当于:
img = tert( (img < 5) || (img > 10) , img , 0 )
该操作再次逐像素执行,并对每个像素的值执行检查--如果不满足条件,则将像素替换为0,否则保留该值。
(第二章)
是的,它直接从您的示例扩展而来。你只需要:
图像投影:= RealImage (“集成平面”,4,sizeX,sizeY)投影icol,irow,0 += Img_source
注1
然而,它并没有延伸到4D和5D。原因是,虽然img[x]、img[x,y]和img[x,y,z]被定义为表示1D、2D和3D中的值,但是带有4参数img[t,l,b,r]的语法已经被定义用于在2D图像中指定rect区域。
注2
使用内部变量非常多(真的很多!)比编写脚本的循环要快。然而,这不是你可以禁食的。原因是这样的表达式只能在单个线程上计算。然而,脚本功能推荐内部是多线程的。因此,在一个坐标上设置一个脚本循环并对用slice2命令提取的2D图像进行汇总实际上更快。
https://stackoverflow.com/questions/59006266
复制相似问题