![]() |
OpenCV 4.12.0
開源計算機視覺
|
上一個教程: 離散傅立葉變換
下一個教程: 如何使用 OpenCV parallel_for_ 並行化你的程式碼
| 原始作者 | Bernát Gábor |
| 相容性 | OpenCV >= 3.0 |
你將找到以下問題的答案
這裡我們只討論 XML、YAML 和 JSON 檔案輸入。你的輸出(及其相應的輸入)檔案可能只有這些副檔名之一以及由此產生的結構。你可以序列化兩種資料結構:對映(如 STL map 和 Python 字典)和元素序列(如 STL vector)。它們之間的區別在於,在對映中,每個元素都有一個唯一的名稱,你可以透過該名稱訪問它。對於序列,你需要遍歷它們以查詢特定項。
XML/YAML/JSON 檔案開啟和關閉。 在向此類檔案寫入任何內容之前,你需要開啟它,並在結束時關閉它。OpenCV 中的 XML/YAML/JSON 資料結構是 cv::FileStorage。要指定此結構繫結到硬碟上的檔案,你可以使用其建構函式或此結構的 open() 函式。
無論你使用哪種方式,第二個引數都是一個常量,指定你可以對它們執行的操作型別:WRITE(寫入)、READ(讀取)或 APPEND(追加)。檔名稱中指定的副檔名也決定了將使用的輸出格式。如果指定 .xml.gz 等副檔名,輸出甚至可以被壓縮。
當 cv::FileStorage 物件被銷燬時,檔案會自動關閉。但是,你可以透過使用 release 函式顯式呼叫它。
向量(陣列)和關聯對映的輸入/輸出。 如前所述,我們也可以輸出對映和序列(陣列、向量)。同樣,我們首先列印變數的名稱,然後必須指定輸出是序列還是對映。
對於序列,在第一個元素之前列印“[”字元,在最後一個元素之後列印“]”字元。在 Python 中,呼叫 FileStorage.startWriteStruct(structure_name, struct_type),其中 struct_type 是 cv2.FileNode_MAP 或 cv2.FileNode_SEQ,以開始寫入結構。呼叫 FileStorage.endWriteStruct() 以完成結構。
對於對映,操作相同,但現在我們使用“{”和“}”分隔符。
要從這些結構中讀取資料,我們使用 cv::FileNode 和 cv::FileNodeIterator 資料結構。cv::FileStorage 類的 [] 運算子(或 Python 中的 getNode() 函式)返回 cv::FileNode 資料型別。如果節點是序列,我們可以使用 cv::FileNodeIterator 遍歷各項。在 Python 中,可以使用 at() 函式訪問序列的元素,size() 函式返回序列的長度。
對於對映,你可以再次使用 [] 運算子(Python 中的 at() 函式)來訪問給定項(或 >> 運算子)。
讀取和寫入自己的資料結構。 假設你有一個數據結構,例如
在 C++ 中,可以透過在類內部和外部新增讀寫函式來透過 OpenCV I/O XML/YAML 介面(就像 OpenCV 資料結構一樣)序列化它。在 Python 中,可以透過在類內部實現讀寫函式來接近這個目標。對於內部部分:
在這裡你可以觀察到,在讀取部分,我們定義瞭如果使用者嘗試讀取一個不存在的節點時會發生什麼。在這種情況下,我們只返回預設初始化值,但一個更詳細的解決方案是返回例如物件 ID 的負一值。
一旦你添加了這四個函式,就可以使用 >> 運算子進行寫入,使用 << 運算子進行讀取(或者 Python 中定義的輸入/輸出函式)。
或者嘗試讀取一個不存在的資料。
我們主要只是打印出定義的數字。在你的控制檯螢幕上你可以看到:
然而,更有趣的是你在輸出 XML 檔案中可能看到的內容:
或者 YAML 檔案:
你可以在此處在 YouTube 上觀看此內容的執行時例項。