相機屬性更新通知

介紹

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
)