python node.GetValue() does not update
I am making a user interface that allows user to adjust settings such as gain using a slider. I have a parallel thread that retrieves the gain values (`Gain.GetValue()`) when gain auto is set to continuous to update the UI. However, I noticed that Gain.GetValue() only updates once after gain auto is set to continous.
I have also tried the callback approach and the result is the same. The callback only gets called once after gain auto is changed from off to continous. Below is an example code.
You can find this code in my github gist
import PySpin
NUM_IMAGES = 5
class GainNodeCallback(PySpin.NodeCallback):
def __init__(self):
super(GainNodeCallback, self).__init__()
def CallbackFunction(self, node):
node_gain = PySpin.CFloatPtr(node)
print('>>>>>>>Gain changed to %f...' % node_gain.GetValue())
def register_gain_callback(nodemap):
node_gain = PySpin.CFloatPtr(nodemap.GetNode('Gain'))
callback_gain = GainNodeCallback()
PySpin.RegisterNodeCallback(node_gain.GetNode(), callback_gain)
print('Gain callback registered...')
return callback_gain
def deregister_gain_callback(callback_gain):
PySpin.DeregisterNodeCallback(callback_gain)
print('Callbacks deregistered...')
def acquire_images(cam):
try:
processor = PySpin.ImageProcessor()
processor.SetColorProcessing(PySpin.SPINNAKER_COLOR_PROCESSING_ALGORITHM_HQ_LINEAR)
for i in range(NUM_IMAGES):
try:
image_result = cam.GetNextImage(1000*1000*5)
if image_result.IsIncomplete():
print('Image incomplete with image status %d...' % image_result.GetImageStatus())
else:
print(f"Grabbed Image {i} with gain: {cam.Gain.GetValue()}")
image_converted = processor.Convert(image_result, PySpin.PixelFormat_Mono8)
image_converted.Save('Gain-%d.jpg' % (i))
image_result.Release()
except PySpin.SpinnakerException as ex:
print('Error: %s' % ex)
except PySpin.SpinnakerException as ex:
print('Error: %s' % ex)
def main():
system = PySpin.System.GetInstance()
version = system.GetLibraryVersion()
print('Library version: %d.%d.%d.%d' % (version.major, version.minor, version.type, version.build))
cam_list = system.GetCameras()
cam = cam_list[0]
try:
cam.Init()
nodemap = cam.GetNodeMap()
cam.GainAuto.SetValue(PySpin.GainAuto_Off)
callback_gain = register_gain_callback(nodemap)
cam.Gain.SetValue(0.0)
print("Gain set to 0.0 manually")
cam.AcquisitionMode.SetValue(PySpin.AcquisitionMode_Continuous)
print("Acquisition mode set to continuous")
cam.BeginAcquisition()
print("Acquisition started")
cam.GainAuto.SetValue(PySpin.GainAuto_Continuous)
print("Gain auto set to continuous")
acquire_images(cam)
cam.EndAcquisition()
deregister_gain_callback(callback_gain)
cam.DeInit()
except PySpin.SpinnakerException as ex:
print('Error: %s' % ex)
finally:
del cam
cam_list.Clear()
system.ReleaseInstance()
if __name__ == '__main__':
main()
Library version: 4.2.0.83
Gain callback registered...
>>>>>>>From callback:Gain changed to 0.000000...
Gain set to 0.0 manually
Acquisition mode set to continuous
Acquisition started
>>>>>>>From callback:Gain changed to 0.000000...
Gain auto set to continuous
Grabbed Image 0 with gain: 0.0
Grabbed Image 1 with gain: 0.0
Grabbed Image 2 with gain: 0.0
Grabbed Image 3 with gain: 0.0
Grabbed Image 4 with gain: 0.0
Callbacks deregistered...
-
Hello,
Thank you for your comment and source code. I can verify I see the same as you with your code. I have also modified our default NodeMapCallback.py code by switching to auto gain, and I also do not see it changing.
As far as our engineering team is concerned, this should work in Auto, so I will need to do some more testing to verify if the C++ example runs fine with auto to narrow down if this is a python issue or a library issue.
You should not have to refresh the nodemap for the callback to fire, so we will investigate this further and get back to you.
Thank you,
Demos
1 -
Thank you for mentioning about refreshing the nodemap. Adding cam.GetNodeMap().Poll(1000) before cam.Gain.GetValue() solves the issue. I will use this workaround while you work on a fix.
0 -
Thank you. It does seem like it is an issue with the library not auto-polling the nodemap, and we would need to change this at the library level to poll in the background instead of the user polling. The SpinView GUI polls on the software side, which is why the nodes look like they are updating.
For your code, refreshing the nodemap every time before you call GetGain I don't think is needed, as if you are polling anyways, you may as well just call Gain.GetValue() instead of looking at callbacks.
The only way I see the nodemap refresh being helpful is if you just had a separate thread that always looped and refreshed the nodemap every 1000 ms. Then you can be running your code and the callback will fire if Gain has changed.
I hope this helps you do what you are looking for at the moment. I think it will take a couple of months before we release a new Spinnaker, but I will add this feature request to the list.
Thank you,
Demos
0 -
Hi Demos,
I'm sure Poll is still needed before GetValue on my machine. Otherwise, the following terminal output would not have printed 0.0.
Grabbed Image 0 with gain: 0.0
When Poll was added, it printed the values correctly.
I am away from my work PC otherwise I would have pasted the new terminal output. I can do it on Monday if it can be of any help.
I don't remember if it fixes the callback not firing issue because in my production code I am calling GetValue every 100 ms. I'd suppose the callback method is more efficient as it saves some overhead on looking up the node map?
Thank you and have a nice weekend,
Anthony
0
Please sign in to leave a comment.
Comments
4 comments