How to detect when a live DigiScan image has finis

2019-07-14 01:42发布

I am looking to take snapshots of a live DigiScan image.

However, I want to do so only when a complete (or nearly so) frame has been acquired!

Attaching an event handler to a live DigiScan image does not work, as the image 'changes' with each line acquired serially.

I am hoping to monitor just the last few pixels of the live image and only capture an image when those change. Is this possible?

标签: dm-script
2条回答
Bombasti
2楼-- · 2019-07-14 02:00

This answer is merely to post the alternate strategy mentioned in the comments to the answer with the original example script. Please note that the following altered version DOES NOT WORK since the attempt to register an image change listener seems to fail (the listener object is immediately released).

class CFrameCompleteListen2
{
    number lastPixelValue
    number listenID
    number frameCount

    void OnDataChanged( object self, number flags, image img )
    {
        Result("\n Change event." )

        number value = img.GetPixel( 0, 0 )
        if ( value == lastPixelValue )
            return 

        frameCount++
        lastPixelValue = value
        Result( "\n Image [" + img.GetLabel() + "] frame #"+ frameCount + " complete." )
        if ( 3 <= frameCount )
        {
            ImageRemoveEventListener( img, listenID )
            Result("\n Listening stopped." )
        }
    }

    object Launch( object self, image img )
    {
        lastPixelValue = img.GetPixel( 0, 0 )
        frameCount = 0
        listenID = ImageAddEventListener( img, self, "data_changed:OnDataChanged" )
        Result("\n Listening started." )
        return self
    }

    ~CFrameCompleteListen2( object self )
    {
        Result( "\n Listener released.\n" )
    }
}

void main()
{
    image targetImage := GetFrontImage()
    number targetW = targetImage.ImageGetDimensionSize(0)
    number targetH = targetImage.ImageGetDimensionSize(1)

    image lastPixelImage := targetImage[targetH - 1, targetW - 1, targetH, targetW]
    lastPixelImage.ShowImage()

    object listener = Alloc( CFrameCompleteListen2 ).Launch( lastPixelImage ) 
}

main()

Edit: by BmyGuest (see comments):

The following script shows, that displaying a "sliced" memory creates a new image with a new reference:

ClearResults()
image newFull := RealImage("Full",4,100,100)
Result("\n Image label 'full':" + newFull.ImageGetLabel() + " | ID:" + newFull.ImageGetID())
newFull.ShowImage()
Result("\n Image label 'full':" + newFull.ImageGetLabel() + " | ID:" + newFull.ImageGetID())
image getFull := GetFrontImage()
Result("\n Image label 'full' (front):" + getFull.ImageGetLabel() + " | ID:" + getFull.ImageGetID())

image slice := newFull[0,0,2,2]
Result("\n Image label 'slice':" + slice.ImageGetLabel() + " | ID:" + newFull.ImageGetID())
slice.ShowImage()
Result("\n Image label 'slice':" + slice.ImageGetLabel() + " | ID:" + newFull.ImageGetID())
image getSlice := GetFrontImage()
Result("\n Image label 'slice' (front):" + getSlice.ImageGetLabel() + " | ID:" + getSlice.ImageGetID())

The output of that script is something like:

enter image description here

Consequently, the listener script above fails and unregisters the listener because the 'lastPixelImage' does not reference the shown 1-pixel image and hence goes out of scope immediately (removing the listener in the process). The script does work, if one grabs the displayed image after showing it and using that one as reference. Accordingly, the script would also work if the sliced image variable would be held in scope.

查看更多
姐就是有狂的资本
3楼-- · 2019-07-14 02:24

Your suggestion is exactly what I did: Using the data_changed event as a trigger, and in the event handling method check the value of the last image pixel for if it has changed. (The initial value of the first pass is guaranteed to be zero. From then on, keep the value of a check.)

So, essentially you’ve answered your own question - what remains unclear?

You can check a single pixel using the GetPixel() command, or the img[x,y] notation.


Example

class CFrameCompleteListen
{
    number lastPixelValue
    number listenID
    number frameCount, sx, sy
    void OnDataChanged( object self, number flags, image img )
    {
        number value = img.GetPixel( sx-1,sy-1)
        if ( value == lastPixelValue )
            return 

        frameCount++
        lastPixelValue = value
        Result( "\n Image [" + img.GetLabel() + "] frame #"+ frameCount + " complete." )
        if ( 3 <= frameCount )
        {
            ImageRemoveEventListener( img, listenID )
            Result("\n Listening stopped." )
        }
    }

    object Launch( object self, image img )
    {
        lastPixelValue = 0
        frameCount = 0
        sx = img.ImageGetDimensionSize(0)
        sy = img.ImageGetDimensionSize(1)
        listenID = ImageAddEventListener( img, self, "data_changed:OnDataChanged" )
        Result("\n Listening started." )
        return self
    }
}

 Alloc( CFrameCompleteListen ).Launch( GetFrontImage() ) 
查看更多
登录 后发表回答