給定一些ArUco標記可見的圖像,檢測過程必須返回檢測到的標記列表。 每個檢測標記包括:
- 圖像中四個角的位置(按原始順序)。
- 標記的id。
標記檢測過程包括兩個主要步驟:
- 檢測候選標記。在該步驟中,分析圖像以找到作爲標記的候選的正方形形狀。 它首先進行自適應閾值處理以對標記進行分割,然後從閾值圖像中提取輪廓,並丟棄那些非凸起或不接近正方形的輪廓。 還應用了一些額外的過濾(去除太小或太大的輪廓,去除彼此太近的輪廓等)。
- 在候選檢測之後,有必要通過分析它們的內部編碼來確定它們是否實際上是標記。 此步驟首先提取每個標記的標記位。 爲此,首先,應用透視變換以獲得其規範形式的標記。 然後,使用Otsu對規範圖像進行閾值處理以分離白色和黑色位。 根據標記大小和邊界大小將圖像分成不同的單元格,並計算每個單元格上的黑色或白色像素的數量,以確定它是白色還是黑色位。 最後,分析比特以確定標記是否屬於特定字典,並且在必要時採用糾錯技術。
在aruco模塊中,檢測在detectMarkers()
函數中執行。 此功能在模塊中是最重要的,因爲所有其餘功能都基於detectMarkers()
返回的先前檢測到的標記。
cv::Mat inputImage;
...
std::vector<int> markerIds;
std::vector<std::vector<cv::Point2f>> markerCorners, rejectedCandidates;
cv::Ptr<cv::aruco::DetectorParameters> parameters;
cv::Ptr<cv::aruco::Dictionary> dictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_250);
cv::aruco::detectMarkers(inputImage, dictionary, markerCorners, markerIds, parameters, rejectedCandidates);
detectMarkers
的參數是:
- 第一個參數是將要檢測標記的圖像。
- 第二個參數是字典對象,在這種情況下是一個預定義的字典(
DICT_6X6_250
)。 - 檢測到的標記存儲在
markerCorners
和markerIds
結構中:markerCorners
是檢測到的標記的角點列表。 對於每個標記,其四個角以其原始順序返回(從左上角開始順時針)。 因此,第一個角是左上角,然後是右上角,右下角和左下角。markerIds
是markerIds
中每個檢測到的標記的id列表。 請注意,返回的markerCorners
和markerIds
向量具有相同的大小。
- 第四個參數是
DetectionParameters
類型的對象。 此對象包括可在檢測過程中自定義的所有參數。 這些參數將在下一節中詳細說明。 - 最終參數
rejectedCandidates
是一個返回的標記候選列表,即已找到的那些方格,但它們不提供有效的編碼。 每個候選者也由其四個角定義,其格式與markerCorners
參數相同。 此參數可以省略,僅用於調試目的和“refind”策略(請參閱refineDetectedMarkers()
)。
在detectMarkers()
檢查您的標記是否已被正確檢測之後,aruco模塊提供了一個在輸入圖像中繪製檢測到的標記的功能,這個功能是drawDetectedMarkers()
。 例如:
cv::Mat outputImage
cv::aruco::drawDetectedMarkers(image, markerCorners, markerIds);
image
是輸入/輸出圖像,其中將繪製標記(它通常與檢測到標記的圖像相同)。markerCorners
和markerIds
是detectMarkers()
函數提供的相同格式的檢測到的標記的結構。
測試示例: