使用digitalmicrograph(DM)脚本创建相邻像素差异的图像

时间:2014-11-27 21:16:52

标签: image-processing dm-script

以下数字微观图像功能尝试通过获取图像的行的子行中的相邻像素的差异来创建图像。用这样创建的子行的差分结果的平均值替换第一像素。

E.g。如果输入图像宽8像素,高1行,子行大小为4 - In_img = {8,9,2,4,9,8,7,5} 然后输出图像将是 - Out_img = {mean(8,9,2,4)= 5.75,9-8 = 1,2-9 = -7,4-2 = 2,mean(9,8,7,5)= 7.25,8- 9 = -1,7-8 = -1,5-7 = -2}

enter image description here

当我运行此脚本时,第一行的第一个像素是正确的,但其余像素不正确。当我将循环限制设置为仅一个子行和一行,即x = 1和y = 1时,脚本正常工作。

关于脚本可能发生什么或可能出现什么问题的任何想法?

test image is hereresult is here

    // Function to compute the standard deviation (sigma n-1) of an image, or
    // a set of values passed in as pixel values in an image. The
    // number of data points (n) the mean and the sum are also returned.
    // version:20080229
    // D. R. G. Mitchell, adminnospam@dmscripting.com (remove the nospam to make this email address work)
    // v1.0, February 2008
    void StandardDeviation(image arrayimg, number &stddev, number &n, number &mean, number &sum)
    {
        mean=mean(arrayimg)
        number xsize, ysize
        getsize(arrayimg,xsize, ysize)
        n=xsize*ysize
        sum=sum(arrayimg)
        image imgsquared=arrayimg*arrayimg
        number sumofvalssqrd=sum(imgsquared)
        stddev=sqrt(((n*sumofvalssqrd)-(sum*sum))/(n*(n-1)))
    }

image getVectorImage(image refImage, number rowsize)
{
    number fh, fv, fhx
    getsize(refImage, fh, fv)

    fhx=trunc(fh/rowsize)

    //result("ByteSize of refimage = "+refImage.ImageGetDataElementByteSize()+"\n")
    //create image to save std of each row of the ref image.  
    //The std values are saved as pixels of one row.  The row size is same as number of rows.
    //use fhx*rowsize for the new imagesize as fhx is truncated value.
    image retImage:=RealImage("",4,fhx*rowsize,fv)
    image workImage=slice1(refImage,rowsize+1,0,0,0,rowsize-1,1)

    number stddev,nopix,mean,sum

    for ( number y=0;y<fv;y++)
        {
        for (number x=0;x<fhx;x++) 
            {
                //result ("x,y="+x+","+y+"; fhx="+fhx+"; rowsize="+rowsize+"\n")
                workImage=slice1(refImage,x*rowsize+1,y,0,0,rowsize-1,1)-slice1(refImage,x*rowsize,y,0,0,rowsize-1,1)
                showimage(workImage)
                StandardDeviation(workImage,stddev,nopix,mean,sum )
                retImage[y,x*rowsize+1,y+1,x*rowsize+rowsize]=workImage
                retImage[y,x]=mean
                result("mean @ row "+y+" = "+mean+"\n")
            }
        }

    return retImage
}
showimage(getVectorImage(getfrontimage(),rowsize))

2 个答案:

答案 0 :(得分:1)

我的脚本中有一些观察结果:

  • 您可以使用以下方法轻松地从任何图像img获取这些数字,而不是定义获取图像的 mean / sum / stdev / n 的方法。 :

    表示:number m = mean( img )

    总和:number s = sum( img )

    stdev:number sd = sqrt( variance( img ) )

    像素:number n = sum( 0 * img + 1 )

  • 如果你想得到一个图像与图像的差异&#34;移动一个&#34;你不必遍历行/列,但可以直接使用slice2()命令; a []表示法使用 icol irow ;或命令offset()就个人而言,我更喜欢slice2()命令。

如果我想要一个脚本,它给出了每一行与其后继行的差异的标准偏差,即stdDev(row_(y) - row_(y + 1))对于所有y&lt; sizeY,我的脚本将是:

Image img :=  GetFrontImage()
number sx,sy
img.GetSize(sx,sy)
number dy = 1

Image dif = img.Slice2(0,0,0, 0,sx,1, 1,sy-1,1 ) - img.Slice2(0,dy,0, 0,sx,1, 1,sy-1,1)
Image sDevs := RealImage( "Row's stDev", 4, sy-1 )
for ( number y=0; y<sy-1; y++ )
    sDevs[y,0] = SQRT( Variance( dif.Slice1(0,y,0, 0,sx,1) ) )

sDevs.ShowImage()

这是你试图实现的目标吗?如果没有,请编辑您的问题以获得一些澄清。

答案 1 :(得分:1)

编辑完成后,我明白你想做这样的事情:

example

并且应该分别对图像的每一行执行此操作。

以下脚本执行此操作。 (以下说明。)

image Modify( image in, number subsize )
{
    // Some checking
    number sx,sy
    in.GetSize(sx,sy)
    if ( 0 != sx%subsize )
        Throw( "The image width is not an integer multiplication of the subsize." )

    // Do the means...
    number nTile = sx/subsize
    image meanImg := RealImage( "Means", 4, nTile , sy )
    meanImg = 0
    for ( number i=0; i<subsize; i++ )
        meanImg += in.Slice2( i,0,0, 0,nTile,subsize, 1,sy,1 )

    meanImg *= 1/subsize

    // Do the shifted difference
    image dif := RealImage( "Diff", 4, sx-1, sy )
    dif = in.slice2( 1,0,0, 0,sx-1,1, 1,sy,1) - in.slice2( 0,0,0, 0,sx-1,1, 1,sy,1) 

    // Compile the result
    image out := in.ImageClone()
    out.SetName( in.getName() + "mod" )

    out.slice2( 1,0,0, 0,sx-1,1, 1,sy,1 ) = dif
    out.slice2( 0,0,0, 0,nTile,subsize, 1,sy,1 ) = meanImg

    return out
}


number sx = 8, sy = 4
image img := RealImage( "test", 4, 8, 4 )
img = icol*10 + trunc( Random()*10 )

img.ShowImage()
Modify(img,4).ShowImage()

一些解释:

  • 你想在图像中做两件不同的事情,所以你必须小心不要覆盖你随后用于计算的像素数据!图像是逐像素处理的,因此如果您首先计算平均值并将其写入第一个像素,则第二个像素的评估将是“9”与刚刚存储的平均值的差值(不是原来的“8”)。所以你必须拆分计算并使用“缓冲”副本。

  • slice2命令非常方便,因为它允许在采样时定义 stepsize 。您可以使用它直接处理深灰色像素。

  • 请注意图像表达式中:==之间的区别。第一个是内存分配:

    • A := B表示A now 与B的内存位置相同 .A基本上是B的另一个名称

      < / LI>
    • A = B表示A获取B(已复制)的值。 A和B是两个不同的内存位置,只复制 值。