相机属性更新通知

介紹

GenICam 因此也包含 IC Imaging Control 4 提供了一套消息机制,允许相机属性在发生变更时通知应用程序。示例如下:

  • 手动曝光控制已锁定,因为自动曝光功能已启用

  • 单次白平衡已完成

  • 自動對焦已完成

  • 数值已更改

实现

像是 PropCommand、PropBoolean 和 PropInteger 等属性类别皆继承自基类 Property,该基类提供了eventAddNotification()eventRemoveNotification()

将一个回调函数传递给eventAddNotification(),每当属性变更时该函数便会被调用。该函数会回传一个 token,可配合eventRemoveNotification() 使用,将该属性从通知队列中移除。

示例

C++ 属性指令

例如,一个用于自动对焦的回调函数:

void auto_focus_done(ic4::Property& prop)
{       
    if (prop.asCommand().isDone())
    {
        std::cout << "Command execution finished!" << std::endl;
    }
}

该函数的注册方式是先从属性映射表中取得该属性,然后对其调用eventAddNotification():

int main()
{
    // Open device first
    auto autofocuscmd = grabber.devicePropertyMap().findCommand("FocusAuto", err);
    auto notifytoken = autofocuscmd.eventAddNotification(auto_focus_done);

    // Do other processing here
    autofocuscmd.execute();

eventAddNotification() 会回传一个NotificationToken之后在相机关闭时,可使用此 token 将该属性从通知清单中移除:

    autofocuscmd.eventRemoveNotification(notifytoken);
    grabber.streamStop();
    grabber.deviceClose();

    return 0;
}

每当程序中执行单次自动对焦时,一旦相机完成对焦,就会调用 auto_focus_done 函数。

该属性对象(在此例中为 autofocuscmd)在相机开启期间必须持续存在。因此,它不能仅在一个函数内创建,然后在调用execute() 之后立即结束并被释放。

同樣的原則也適用於 單次白平衡,它會執行一次性的白平衡調整。

Python 曝光时间

在 Python 示例中,当前的曝光时间会通过 GUI 中的QDoubleSpinBox显示。实现了以下行为:

  • 当自动曝光控制变更曝光时间时,曝光时间会随之自动更新。

  • 当自动曝光启用时,输入字段会被禁用;当自动曝光关闭时,该字段会重新启用。

目前并非所有相机型号都支持在自动模式启用的情况下读取曝光时间。然而,此功能在 TIS 的 GigE 相机上运作得非常出色。

一个继承自QDoubleSpinBox 的类别实现了此功能:

class PropertyFloatEdit(QDoubleSpinBox):
    def __init__(self):
        super().__init__()
        self.property: ic4.Property = None

    def __delete__(self, instance):
        self.property.event_remove_notification(self.notify_token)

    def set_property(self, grabber: ic4.Grabber, property_name: str):
        self.property = grabber.device_property_map.find_float(property_name)
        if self.property is not None:
            self.setMinimum(self.property.minimum)
            self.setMaximum(self.property.maximum)
            self.value = self.property.value

            self.notify_token = self.property.event_add_notification(
                self.on_property_update
            )

    def on_property_update(self, prop: ic4.Property):
        self.setEnabled(not prop.is_locked)
        self.setValue(prop.value)

当在 set_property() 中设定属性(例如ic4.PropId.EXPOSURE_TIME) 时,会调用event_add_notification() 。此函数会接收 self.on_property_update 作为回调函数(callback),并回传一个通知 token,之后可用来将该属性从通知队列中移除。

回调函数 on_property_update 非常单纯:它利用 prop.is_locked 来启用或禁用QDoubleSpinBox,并以当前的曝光时间更新显示的数值。

在 Python 主程序中,PropertyFloatEdit 的建立方式如下:

self.edt_exposuretime = PropertyFloatEdit()

在开启相机后,会指派 EXPOSURE_TIME 属性:

self.edt_exposuretime.set_property(
    self.grabber, ic4.PropId.EXPOSURE_TIME
)