OpenCV4學習筆記(72)——ArUco模塊之aruco標記的創建與檢測

今天要整理記錄的是OpenCV中ArUco模塊的基礎內容,包含aruco標記的創建與檢測。要注意的是ArUco模塊是包含在OpenCV的contrib拓展庫中的,需要自行下載OpenCV基礎庫和contrib拓展庫進行聯合編譯纔可以使用,這裏就不整理編譯的過程了,不得不說編譯的時候還是有好多坑的。。。如果有需要的朋友可以在我的資源裏面下載 “OpenCV430(contrib).txt”,這是編譯好了的包含contrib拓展庫的OpenCV4.3.0版本,由於文件過大所以使用的是某度網盤鏈接的方式上傳,介意下載速度的朋友就還是別下載了。把壓縮包下載解壓後再進行環境配置,就可以直接使用OpenCV中拓展庫的內容了,順帶一提,編譯的時候我選擇的是AVX2指令集,相比起OpenCV默認的SSE3指令集有一定程度的優化,當然了這個需要個人的電腦CPU支持纔可以,所以下載的朋友需要注意一下。

言歸正傳,下面先來了解一下什麼是aruco標記:
aruco標記是可用於攝像機姿態估計的二進制方形基準標記。它的主要優點是檢測簡單、快速,並且具有很強的魯棒性。ArUco 標記是由寬黑色邊框和確定其標識符(id)的內部二進制矩陣組成的正方形標記。aruco標記的黑色邊框有助於其在圖像中的快速檢測,內部二進制編碼用於識別標記和提供錯誤檢測和糾正。aruco標記尺寸的大小決定內部矩陣的大小,例如尺寸爲 4x4 的標記由 16 位二進制數組成。

通俗地說,aruco標記其實就是一種編碼,就和我們日常生活中的二維碼是相似的,只不過由於編碼方式的不同,導致它們存儲信息的方式、容量等等有所差異,所以在應用層次上也會有所不同。由於單個aruco標記就可以提供足夠的對應關係,例如有四個明顯的角點及內部的二進制編碼,所以aruco標記被廣泛用來增加從二維世界映射到三維世界時的信息量,便於發現二維世界與三維世界之間的投影關係,從而實現姿態估計、相機矯正等等應用。

OpenCV中的ArUco模塊包括了對aruco標記的創建和檢測,以及將aruco標記用於姿勢估計和相機矯正等應用的相關API,同時還提供了標記板等等。本次筆記中主要先整理aruco標記的創建與檢測。

首先我們創建aruco標記時,需要先指定一個字典,這個字典表示的是創建出來的aruco標記具有怎樣的尺寸、怎樣的編碼等等內容,我們使用APIgetPredefinedDictionary()來聲明我們使用的字典。在OpenCV中,提供了多種預定義字典,我們可以通過PREDEFINED_DICTIONARY_NAME來查看有哪些預定義字典。而且字典名稱表示了該字典的aruco標記數量和尺寸,例如DICT_7X7_50表示一個包含了50種7x7位標記的字典。

確定好我們需要的字典後,就可以通過APIdrawMarker()來繪製出aruco標記,其參數含義如下:
(1)參數dictionary: 之前創建的 Dictionary 對象指針
(2)參數id:標記 id,表示繪製字典中的哪一個aruco標記。每個字典由不同數量的標記組成,id 有效範圍是 [ 0,字典包含的標記數 ),任何超出有效範圍的特定 id 都會產生異常。
(3)參數 sidepixel: 輸出標記圖像的尺寸,輸出標記圖像的尺寸爲Size(sidepixel,sidepixel);此參數應足夠大以存儲特定字典的位數,至少需要滿足(sidepixel - 標記的邊長)>= 2;
並且爲了避免輸出標記圖像變形,sidepixel應與位數 + 邊界大小成比例,或者至少比標記尺寸大得多,以使變形不明顯。
(4)參數img:輸出的標記圖像;
(5)參數borderBist:用於指定標記黑色邊框的寬度,例如borderBist=2 表示邊框的寬度等於兩個內部像素的大小,默認值 borderBist= 1。

這樣,我們就創建了一個選定字典的aruco標記了,下面我們創建5個不同的aruco標記來對比下,演示代碼如下:

	//創建aruco標記
	Mat marker;
	auto dictionary = aruco::getPredefinedDictionary(aruco::PREDEFINED_DICTIONARY_NAME::DICT_6X6_250);
	for (int i = 0;i < 5;i++)
	{
		aruco::drawMarker(dictionary, i, 200, marker, 1);
		string windowName = "marker" + to_string(i);
		imshow(windowName, marker);
		string path ="D:\\"+ windowName + ".jpg";
		imwrite(path, marker);
	}

創建的aruco標記如下:
在這裏插入圖片描述

接下來,當我們把aruco標記打印出來後貼在任意其它地方後,再進行拍攝,就可以對aruco標記進行檢測。檢測aruco標記的API是detectMarkers(),其參數含義如下:
(1)參數image:輸入的需要檢測標記的圖像;
(2)參數dictionary:進行檢測的字典對象指針,這裏的字典就是我們創建aruco標記時所使用的字典,檢測什麼類型的aruco標記就使用什麼類型的字典;
(3)參數corners:檢測到的aruco標記的角點列表,對於每個標記,其四個角點均按其原始順序返回(從右上角開始順時針旋轉),第一個角是右上角,然後是右下角,左下角和左上角。
注意這裏的返回角點順序,在OpenCV官方文檔中記錄的是從左上角開始進行旋轉,而經過我的測試,發現是以右上角爲起點的,這應該是官方文檔中的筆誤,而且官方文檔中關於contrib拓展庫部分的內容可能由於更新頻率低,其中還存在着不少小問題,朋友們在看的時候要注意自己檢驗一下里面的內容,千萬不用拿來即用,很可能掉坑。
(4)參數ids:檢測到的每個標記的 id,需要注意的是第三個參數和第四個參數具有相同的大小;
(5)參數parameters: DetectionParameters 類的對象,該對象包括在檢測過程中可以自定義的所有參數;
(6)參數rejectedImgPoints:拋棄的候選標記列表,即檢測到的、但未提供有效編碼的正方形。每個候選標記也由其四個角定義,其格式與第三個參數相同,該參數若無特殊要求可以省略。

當我們進行aruco標記檢測後,爲了方便我們觀察,通常需要進行可視化操作,也就是把檢測到的aruco標記繪製出來,我們使用drawDetectedMarkers()這個API來繪製檢測到的aruco標記,其參數含義如下:
(1)參數image: 是將繪製標記的輸入 / 輸出圖像(通常就是檢測到標記的圖像)
(2)參數corners:檢測到的aruco標記的角點列表
(3)參數ids:檢測到的每個標記對應到其所屬字典中的id
(4)參數borderColor:繪製標記外框的顏色

對aruco標記進行檢測並繪製的演示代碼如下:

		auto dictionary = aruco::getPredefinedDictionary(aruco::PREDEFINED_DICTIONARY_NAME::DICT_6X6_250);
		vector<vector<Point2f>>corners, rejectedImgPoints;
		vector<int>ids;
		auto parameters = aruco::DetectorParameters::create();
		aruco::detectMarkers(test_image, dictionary, corners, ids, parameters, rejectedImgPoints);
		aruco::drawDetectedMarkers(test_image, corners, ids, Scalar(0, 255, 0));

效果如下:

在這裏插入圖片描述
放大觀察:
在這裏插入圖片描述
在這裏插入圖片描述
可以看到每個aruco標記的邊框上,都有一個綠色矩形框,而在標記的中心,有一個id值,這個id就是該標記在其所屬字典中的id。

那麼到這裏,我們就完成了對aruco標記的創建和檢測工作,這是一個基礎操作,後續的姿態估計、相機標定等等操作都是建立在此基礎之上的。本次筆記就先到此爲止,下次再來整理一下對aruco標記進行實時姿態估計的相關內容。

PS:本人的註釋比較雜,既有自己的心得體會也有網上查閱資料時摘抄下的知識內容,所以如有雷同,純屬我向前輩學習的致敬,如果有前輩覺得我的筆記內容侵犯了您的知識產權,請和我聯繫,我會將涉及到的博文內容刪除,謝謝!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章