ArUco Moduleで生成したマーカのIDを取得

# 概要
OpenCVのContribにあるArUco Moduleで生成したマーカのIDをコンソールに出してみました。マーカを生成した後、そのマーカ画像をWebカメラから取得し、画面内に表示されているマーカのIDをコンソールに出力しました。以下の手順では、マーカの生成からID取得プログラム及び実行を示します。Visual studioでArUco Moduleを使えるようにする手順は参考URLを示すので、その手順通りに進めれば使えるようになると思います。

# 実行環境
次に実行環境を示します。

| Soft and Hard       |       バージョン | 
|:-----------------:|:------------------:|
| Visual Studio         |              2017 |  
| OpneCV         |              4.0.0 |
| OpenCVContrib         |              4.0.0 | 

Visual studioでArUco Moduleを使えるようにする手順は次の参考URLがとても分かりやすかったです。

- [Visual Studio 2017にOpenCV3.2.0とopencv_contribを導入する方法](https://qiita.com/tomochiii/items/fa26404ebc5fcd4481b9)

以下に示す大まかな流れは次の通りです。

- マーカの生成
- マーカID取得プログラム
- マーカID取得プログラム実行

# マーカ生成
ArUco Moduleのマーカ生成に関しては、以下のgithubに分かりやすく書いてあるプログラムを実行することで、生成できます。また、使用している関数の内容も簡単にかいてあるので、自分でちょこちょこいじる事ができると思います。


- [arucoモジュールでマーカーを生成する](https://github.com/atinfinity/lab/wiki/aruco%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB%E3%81%A7%E3%83%9E%E3%83%BC%E3%82%AB%E3%83%BC%E3%82%92%E7%94%9F%E6%88%90%E3%81%99%E3%82%8B)

# マーカID取得プログラム

次に作成したマーカID取得プログラムを示します。カメラはUSBカメラを使いました。

```c++:get_markers_id.cpp
#include <iostream>
#include "opencv2/opencv.hpp"
#include "opencv2/aruco.hpp"

// Get MarkersID
void ShowMarkerIdsFunction(cv::OutputArray in) {
	std::vector<cv::Mat> marker_ids;
	in.getMatVector(marker_ids);
	std::cout << "Marker IDs : "<< std::endl;
	for (auto marker_ids : marker_ids) {
		std::cout << marker_ids << std::endl;
	}
}

int main(int argh, char* argv[])
{
	// Create Marker Dictionary, Type of marker : 7X7,1000
	const cv::aruco::PREDEFINED_DICTIONARY_NAME dictionary_name = cv::aruco::DICT_7X7_1000;
	cv::Ptr<cv::aruco::Dictionary> dictionary = cv::aruco::getPredefinedDictionary(dictionary_name);
	std::vector<int> marker_ids;
	std::vector<std::vector<cv::Point2f>> marker_corners;
	int sum_ids = 0;
	cv::Mat web_camera_frame;
	cv::VideoCapture cap(1);

	// Confirm web camera connection
	if (!cap.isOpened())
	{
		printf("web camera : Bad Connection\n");
		return -1;
	}

	// Recognition MarkersID with ArUco
	while (cap.read(web_camera_frame))
	{
		// Detect markers
		cv::Ptr<cv::aruco::DetectorParameters> parameters = cv::aruco::DetectorParameters::create();
		cv::aruco::detectMarkers(web_camera_frame, dictionary, marker_corners, marker_ids, parameters);
		cv::aruco::drawDetectedMarkers(web_camera_frame, marker_corners, marker_ids);

		sum_ids = marker_ids.size();
		cv::imshow("from camera", web_camera_frame);
		
		// Show MarkerID and  sum of IDs in console
 		ShowMarkerIdsFunction(marker_ids);
		std::cout << "sum IDs:" << sum_ids << std::endl;

		const int key = cv::waitKey(1);
		if (key == 'q'){
			break;
		}
		else if (key == 's'){
			cv::imwrite("Marker_ids_recognized.png", web_camera_frame);
		}
	}
	cv::destroyAllWindows();
	return 0;
}

```

# マーカID取得プログラム実行

実行したときのカメラ画像とコンソールの状態を次に示します。

- 全体画像
![1.png](https://qiita-image-store.s3.amazonaws.com/0/169342/d4b92860-82a6-37cc-6589-729c18a98696.png)

- カメラ取得画像
![2.png](https://qiita-image-store.s3.amazonaws.com/0/169342/5526944e-fb2f-76a2-5b5d-000254ba9dd1.png)

- コンソール画像
![3.png](https://qiita-image-store.s3.amazonaws.com/0/169342/d3a58bff-2818-b4dc-2f32-e77b21a9a4f4.png)

# まとめ
ArUco Moduleは簡単にARを試すことができるので、とても楽しいです。また、間違っているところや、追加したほうがいい、こういう書き方の方がいいよ！という箇所がありましたら、お教え頂けるととても嬉しいです。