How to detect when a live DigiScan image has finished acquiring a complete frame with an event handler?

心已入冬 提交于 2019-12-11 00:58:51

问题


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?


回答1:


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



回答2:


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:

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.



来源:https://stackoverflow.com/questions/52050885/how-to-detect-when-a-live-digiscan-image-has-finished-acquiring-a-complete-frame

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