介紹如何使用 ITK 的 observer 監看影像對準過程,繪製及時的距離變化圖,確認收斂情況。

影像對準(image registration)的計算過程需要確認結果是否正確收斂到最佳解,在 ITK 中我們可以透過設定 observer 的方式,取出每次疊代產生的 metric 數值,並及時繪製出圖形,方便開發者調整參數。

以下幾個回呼函數(callback function)可用來繪製即時的 metric 數值收斂狀況。

from IPython.display import clear_output

# 初始事件回呼函數
def cb_registration_start():
    global cb_metric_values
    global cb_current_iteration_number
    cb_metric_values = []
    cb_current_iteration_number = -1

# 結束事件回呼函數
def cb_registration_end():
    global cb_metric_values
    global cb_current_iteration_number
    del cb_metric_values
    del cb_current_iteration_number
    plt.close()

# 疊代事件回呼函數
def cb_registration_iteration():
    global cb_metric_values
    global cb_current_iteration_number

    # 忽略重覆產生的疊代事件
    if optimizer.GetCurrentIteration() == cb_current_iteration_number:
        return

    cb_current_iteration_number = optimizer.GetCurrentIteration()
    cb_metric_values.append(optimizer.GetValue())

    # 清空輸出
    clear_output(wait=True)

    # 繪製 Metric 圖形
    plt.plot(cb_metric_values)
    plt.xlabel('Iteration Number', fontsize=12)
    plt.ylabel('Metric Value', fontsize=12)
    plt.show()

定義好這些回呼函數之後,接著在 optimizer 上面加上 sbserver,設定事件與回呼函數的對應關係:

# 加上 Observer,設定事件與回呼函數的對應關係
optimizer.AddObserver(itk.StartEvent(), cb_registration_start)
optimizer.AddObserver(itk.EndEvent(), cb_registration_end)
optimizer.AddObserver(itk.IterationEvent(), cb_registration_iteration)

這樣在執行影像對準的時候,就會及時繪製出 metric 數值收斂的狀況了。

這裡我們將這些 observer 套用在影像平移線性對準的範例中,可得到向這樣的 metric 收斂圖形。

metric 數值收斂狀況

參考資料