OpenNH

日常のひとこま(自分用のメモとかあれこれ)

OpenCVでchArUcoマーカー/コーナー検出

使用する関数の説明

  • cv::aruco::detectMarkers(...) : マーカー検出関数

<引数>

  1. 入力画像
  2. 検索するマーカーの種類
  3. 検出されたマーカーコーナーのベクトル(Nx4配列)
  4. 検出されたマーカーIDのベクトル(int Nx1配列)
  5. マーカー検出パラメータ

>>OpenCV: ArUco Marker Detection

  • cv::aruco::PREDEFINED_DICTIONARY_NAME : マーカー種類のインデックス

>>OpenCV: ArUco Marker Detection

  • cv::aruco::drawDetectedMarkers(...) : 検出マーカー描画関数

<引数>

  1. 入出力画像
  2. 検索するマーカーの種類
  3. 検出されたマーカーコーナーのベクトル(Nx4配列)
  4. 検出されたマーカーIDのベクトル(int Nx1配列)

>>OpenCV: ArUco Marker Detection

  • cv::aruco::CharucoBoard::create(...) : ChArUcoボードオブジェクトの生成

<引数>

  1. X方向のパターン数
  2. Y方向のパターン数
  3. パターン1個の物理サイズ [m]
  4. マーカー1個の物理サイズ [m]
  5. マーカー種類のディクショナリ

>>OpenCV: cv::aruco::CharucoBoard Class Reference



C++サンプルプログラム(単純な検出&描画)

#include <iostream>
#include <vector>
#include <opencv2/opencv.hpp>
#include <opencv2/aruco/charuco.hpp>

#ifndef _DEBUG
// Releaseモードのみで動作
#pragma comment(lib,"opencv_calib3d330.lib")
#pragma comment(lib,"opencv_core330.lib")
#pragma comment(lib,"opencv_highgui330.lib")
#pragma comment(lib,"opencv_imgproc330.lib")
#pragma comment(lib,"opencv_imgcodecs330.lib")
#pragma comment(lib,"opencv_aruco330.lib")
#endif

int readImage(cv::Mat &mat_image, char *dire);

int main() {
	// Read ChArUco stereo images
	cv::Mat img, dstimg;
	readImage(img, "< yourpath >");

	// Create dictionary
	const cv::aruco::PREDEFINED_DICTIONARY_NAME  dictionary_name = cv::aruco::DICT_6X6_250;
	cv::Ptr<cv::aruco::Dictionary> dictionary = cv::aruco::getPredefinedDictionary(dictionary_name);

	// Detect markers
	std::vector<int> markerIdx;
	std::vector<std::vector<cv::Point2f>> markerCorners, rejectedImgPoints;
	cv::Ptr<cv::aruco::DetectorParameters> detectorParams = cv::aruco::DetectorParameters::create();
	cv::aruco::detectMarkers(img, dictionary, markerCorners, markerIdx, detectorParams, rejectedImgPoints);
        
       	// create charuco board object
	const int   squaresX     = 8;
	const int   squaresY     = 11;
	const float squareLength = 0.031;
	const float markerLength = 0.0185;
	cv::Ptr<cv::aruco::CharucoBoard> charucoboard_obj =
	     cv::aruco::CharucoBoard::create(squaresX, squaresY, squareLength, markerLength, dictionary);
	cv::Ptr<cv::aruco::Board> charucoboard = charucoboard_obj.staticCast<cv::aruco::Board>();

        // refind strategy to detect more markers
	cv::aruco::refineDetectedMarkers(img, charucoboard, markerCorners, markerIdx, rejectedImgPoints);

	// Draw detected markers
	cv::cvtColor(img.clone(), dstimg, cv::COLOR_GRAY2BGR);
	cv::aruco::drawDetectedMarkers(dstimg, markerCorners, markerIdx);
	cv::imshow("Detected result", dstimg);
	cv::waitKey(0);

	return -1;
}

int readImage(cv::Mat &mat_image, char *dire)
{
	// read stereo images in as grayscale (CV_8U):
	mat_image= cv::imread(dire, 0);
	if (mat_image.empty()) {
		printf("ERROR! failed to read one or both images, exiting...\n");
		return 0;
	}
	return 1;
}

マーカー検出結果

f:id:FounderLeis:20181202171230p:plain

 
 

C++サンプルプログラム(ChArUcoボードのコーナー検出)

        // refind strategy to detect more markers
        ...

	// Interpolate charuco corners
	// if at least one marker detected
	std::vector<cv::Point2f> charucoCorners;
	std::vector<int> charucoIdx;
	if (markerIdx.size() > 0) {
		cv::aruco::interpolateCornersCharuco(
			markerCorners, markerIdx, img, charucoboard_obj, charucoCorners, charucoIdx);
	}
        
        // Draw detected corners
        ...
        if (charucoIdx.size() > 0) 
		cv::aruco::drawDetectedCornersCharuco(dstimg, charucoCorners, charucoIdx, cv::Scalar(0, 0, 255));
        ...

コーナー検出結果

f:id:FounderLeis:20181202171327p:plain
 


説明文の折り畳み方法に関してはこちらの記事を参考にさせていただきました。
はてなブログでソースコードを折りたたむ方法 - おもちゃラボ

 
Amazon: 

詳解 OpenCV 3 ―コンピュータビジョンライブラリを使った画像処理・認識

詳解 OpenCV 3 ―コンピュータビジョンライブラリを使った画像処理・認識