Creating an image of difference of adjacent pixels with digitalmicrograph (DM) script

陌路散爱 提交于 2019-12-23 02:19:24

问题


The following digitalmicrograph function tries to create an image by taking difference of neighboring pixel in a sub-row of a row of the image. The first pixel is replaced with a mean of the difference result of the sub-row thus created.

E.g. If the input image is 8 pixels wide and 1 rows tall and the sub-row size is 4 - In_img = {8,9,2,4,9,8,7,5} Then the output image will be - 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}

When I run this script, the first pixel of the first row is correct but rest of the pixels are incorrect. When I set the loop limit to only one sub-row and one row i.e. x=1 and y=1, then the script works correctly.

Any ideas as to what may be happening or what may be wrong with the script?

The test image is here and the result 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))

回答1:


After your edit, I understood that you want to do something like this:

and that this should be performed for each line of the image individually.

The following script does this. (Explanations below.)

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()

Some explanations:

  • You want to do two different things in the image, so you have to be careful not to overwrite data in pixels you will subsequently use for computation! Images are processed pixel by pixel, so if you first compute the mean and write it in the first pixel, the evaluation of the second pixel will be the difference of "9" and the just stored mean-value (not the original "8"). So you have to split computation and use "buffer" copies.

  • The slice2 command is extremely convenient, because it allows to define a stepsize when sampling. You can use it to address the dark-grey pixels directly.

  • Be aware of the difference between := and = in image expressions. The first is a memory assignment:

    • A := B means that A now is the same memory location as B. A is basically another name for B.

    • A = B means A gets the values of B (copied). A and B are two different memory locations and only values are copied over.




回答2:


I have some observations in your script:

  • Instead of the defined method for getting mean/sum/stdev/n of an image, you can as easily get to those numbers from any image img using the following:

    mean: number m = mean( img )

    sum: number s = sum( img )

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

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

  • if you want to get the difference of an image with an image "shifted by one" you don't have to loop over the lines/columns but can directly use the slice2() command; a [ ] notation using icol and irow; or the command offset() Personally, I prefer the slice2() command.

If I want a script which gives me the standard deviation of the difference of each row with its successor row, i.e. stdDev( row_(y) - row_(y+1) ) for all y < sizeY, my script would be:

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()

Is this, what you try to achieve? If not, please edit your question for some clarification.



来源:https://stackoverflow.com/questions/27178748/creating-an-image-of-difference-of-adjacent-pixels-with-digitalmicrograph-dm-s

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!