charuco 교정 보드
15412 단어 C++교정OpenCVopencv_contrib이미지 처리
소개
OpenCV에서 카메라 캘리브레이션을 하는 경우, 타겟으로서 체스보드 이미지 이나 원 그리드 이미지 를 사용하는 경우가 많다고 생각합니다.
캘리브레이션 조사 중 체스보드 이미지의 하얀 송어 부분에 뭔가 QR 코드 스타일의 패턴이있는 것을 볼 수있었습니다.
조사해 보면, Opencv contrib의 AR 마커 검출등의 모듈인 aruco 모듈안의 기능의 하나, charuco 모듈이라고 하는 것이었으므로, 시험에 사용해 보기로 했습니다.
참고
소스 코드 등은 OpenCV의 레퍼런스를 참고로 하고 있습니다.
htps : // / cs. 오펜 cv. rg / 4.1.2 / df / d4 아 / 쓰리 아 l_ 캬루코_에서 c 치오. HTML
보드 이미지 만들기
우선, 캘리브레이션에 사용하는 보드의 이미지를 작성할 필요가 있습니다만, 그 이미지를 작성하는 기능도 charuco 모듈에 포함되어 있습니다.
다음 코드를 사용하여 교정 이미지를 만들 수 있습니다.
main.cpp#include <opencv2/opencv.hpp>
#include <opencv2/aruco/charuco.hpp>
int main(int argc, const char * argv[]) {
//マーカ辞書作成 6x6マスのマーカを250種類生成
cv::Ptr<cv::aruco::Dictionary> dictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_250);
//charucoボード生成 10x7マスのチェスボード、グリッドのサイズ0.04f、グリッド内マーカのサイズ0.02f
cv::Ptr<cv::aruco::CharucoBoard> board = cv::aruco::CharucoBoard::create(10, 7, 0.04f, 0.02f, dictionary);
cv::Mat boardImage;
board->draw(cv::Size(1920, 1080), boardImage, 10, 1);
cv::imwrite("BoardImage.jpg", boardImage);
}
↓와 같은 이미지를 출력할 수 있습니다.
이 이미지를 용지 등에 인쇄하여 캘리브레이션용 촬영을 수행합니다.
이번에는 귀찮았기 때문에 노트북에 모니터에 찍은 상태로 촬영해 보겠습니다.
탐지
카메라는 iPhone XS 카메라를 사용했습니다.
검색 소스 코드는 다음과 같습니다.
main.cpp#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/aruco/charuco.hpp>
int detectCharucoBoard(std::string srcPath, std::string dstPath)
{
cv::Mat image = cv::imread(srcPath);
cv::Mat imageCopy = image.clone();
//マーカ辞書作成 6x6マスのマーカを250種類生成
cv::Ptr<cv::aruco::Dictionary> dictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_250);
//charucoボード生成 10x7マスのチェスボード、グリッドのサイズ0.04f、グリッド内マーカのサイズ0.02f
cv::Ptr<cv::aruco::CharucoBoard> board = cv::aruco::CharucoBoard::create(10, 7, 0.04f, 0.02f, dictionary);
//マーカー検出時メソッドを指定
cv::Ptr<cv::aruco::DetectorParameters> params = cv::aruco::DetectorParameters::create();
params->cornerRefinementMethod = cv::aruco::CORNER_REFINE_NONE;
//マーカー検出
std::vector<int> markerIds;
std::vector<std::vector<cv::Point2f> > markerCorners;
cv::aruco::detectMarkers(image, board->dictionary, markerCorners, markerIds, params);
if (markerIds.size() > 0) {
//マーカー位置を描画
cv::aruco::drawDetectedMarkers(imageCopy, markerCorners, markerIds);
//マーカーの座標をもとに、チェスボード画像の交点を検出
std::vector<cv::Point2f> charucoCorners;
std::vector<int> charucoIds;
cv::aruco::interpolateCornersCharuco(markerCorners, markerIds, image, board, charucoCorners, charucoIds);
if (charucoIds.size() > 0)
{
//チェスボード交点位置を描画
cv::aruco::drawDetectedCornersCharuco(imageCopy, charucoCorners, charucoIds, cv::Scalar(0, 0, 255));
}
}
cv::imwrite(dstPath, imageCopy);
return 0;
}
int main(int argc, const char * argv[]) {
detectCharucoBoard("./IMG_5410.jpeg", "./IMG_5410_detect.jpg");
detectCharucoBoard("./IMG_5411.jpeg", "./IMG_5411_detect.jpg");
detectCharucoBoard("./IMG_5412.jpeg", "./IMG_5412_detect.jpg");
return 0;
}
이미지를 보자.
이 이미지는 ...
이렇게 됩니다. 마커(파란색 id)도 체스보드 교차점(빨간색 id)도 모두 검출할 수 있는 것 같습니다.
이것만이라면, 별로 보통 체스 보드에서도 좋지 않다? 라는 느낌이 듭니다.
그러나 이미지를 볼 수 있듯이 charuco 모듈에서 감지되는 체스 보드의 교차점에는 각각 별도의 ID 번호가 있습니다. 아마도이 교차점 ID는 교차점에 가장 가까운 마커 ID를 기반으로 할당하는 것 같습니다. 이렇게하면 일반 체스 보드와 약간 다른 촬영을 할 수 있습니다. 그것은...
이 방법으로 전체 보드가 보이지 않더라도 체스 보드 교차점을 감지 할 수 있습니다.
일반 체스보드 교차점 감지 함수 cv::findChessboardCorners를 사용하면 지정된 매스의 체스보드 이미지 전체가 표시되지 않으면 감지할 수 없습니다. 그래서 카메라를 보드에 가까이 하거나 보드를 화각의 가장자리에서 촬영하려고 하면 보드가 화각 밖으로 튀어나와 보드를 검출할 수 없게 되는 경우가 있었습니다. 그 때문에 통상의 체스보드라면 캘리브레이션용의 촬영 자체가 상당히 번거롭거나 어려웠던 경우가 많습니다만, 이것을 사용하면 효율적으로 촬영할 수 있을 것 같고, 체스 보드의 일부라도 좋은 것 , 전체를 찍지 않아도 좋은 것을 이용해 여러가지 응용할 수 있을 것 같습니다.
덧붙여서 더 업으로 촬영해도 OK였습니다.
요약
charuco의 보드 감지를 시도했습니다.
기존의 체스보드와는 사양이 다른 검출을 할 수 있었으므로, 어떻게 응용할지 생각해 보고 싶습니다.
Reference
이 문제에 관하여(charuco 교정 보드), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/noueezy/items/58730f09f6aa6a97faf5
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
소스 코드 등은 OpenCV의 레퍼런스를 참고로 하고 있습니다.
htps : // / cs. 오펜 cv. rg / 4.1.2 / df / d4 아 / 쓰리 아 l_ 캬루코_에서 c 치오. HTML
보드 이미지 만들기
우선, 캘리브레이션에 사용하는 보드의 이미지를 작성할 필요가 있습니다만, 그 이미지를 작성하는 기능도 charuco 모듈에 포함되어 있습니다.
다음 코드를 사용하여 교정 이미지를 만들 수 있습니다.
main.cpp#include <opencv2/opencv.hpp>
#include <opencv2/aruco/charuco.hpp>
int main(int argc, const char * argv[]) {
//マーカ辞書作成 6x6マスのマーカを250種類生成
cv::Ptr<cv::aruco::Dictionary> dictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_250);
//charucoボード生成 10x7マスのチェスボード、グリッドのサイズ0.04f、グリッド内マーカのサイズ0.02f
cv::Ptr<cv::aruco::CharucoBoard> board = cv::aruco::CharucoBoard::create(10, 7, 0.04f, 0.02f, dictionary);
cv::Mat boardImage;
board->draw(cv::Size(1920, 1080), boardImage, 10, 1);
cv::imwrite("BoardImage.jpg", boardImage);
}
↓와 같은 이미지를 출력할 수 있습니다.
이 이미지를 용지 등에 인쇄하여 캘리브레이션용 촬영을 수행합니다.
이번에는 귀찮았기 때문에 노트북에 모니터에 찍은 상태로 촬영해 보겠습니다.
탐지
카메라는 iPhone XS 카메라를 사용했습니다.
검색 소스 코드는 다음과 같습니다.
main.cpp#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/aruco/charuco.hpp>
int detectCharucoBoard(std::string srcPath, std::string dstPath)
{
cv::Mat image = cv::imread(srcPath);
cv::Mat imageCopy = image.clone();
//マーカ辞書作成 6x6マスのマーカを250種類生成
cv::Ptr<cv::aruco::Dictionary> dictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_250);
//charucoボード生成 10x7マスのチェスボード、グリッドのサイズ0.04f、グリッド内マーカのサイズ0.02f
cv::Ptr<cv::aruco::CharucoBoard> board = cv::aruco::CharucoBoard::create(10, 7, 0.04f, 0.02f, dictionary);
//マーカー検出時メソッドを指定
cv::Ptr<cv::aruco::DetectorParameters> params = cv::aruco::DetectorParameters::create();
params->cornerRefinementMethod = cv::aruco::CORNER_REFINE_NONE;
//マーカー検出
std::vector<int> markerIds;
std::vector<std::vector<cv::Point2f> > markerCorners;
cv::aruco::detectMarkers(image, board->dictionary, markerCorners, markerIds, params);
if (markerIds.size() > 0) {
//マーカー位置を描画
cv::aruco::drawDetectedMarkers(imageCopy, markerCorners, markerIds);
//マーカーの座標をもとに、チェスボード画像の交点を検出
std::vector<cv::Point2f> charucoCorners;
std::vector<int> charucoIds;
cv::aruco::interpolateCornersCharuco(markerCorners, markerIds, image, board, charucoCorners, charucoIds);
if (charucoIds.size() > 0)
{
//チェスボード交点位置を描画
cv::aruco::drawDetectedCornersCharuco(imageCopy, charucoCorners, charucoIds, cv::Scalar(0, 0, 255));
}
}
cv::imwrite(dstPath, imageCopy);
return 0;
}
int main(int argc, const char * argv[]) {
detectCharucoBoard("./IMG_5410.jpeg", "./IMG_5410_detect.jpg");
detectCharucoBoard("./IMG_5411.jpeg", "./IMG_5411_detect.jpg");
detectCharucoBoard("./IMG_5412.jpeg", "./IMG_5412_detect.jpg");
return 0;
}
이미지를 보자.
이 이미지는 ...
이렇게 됩니다. 마커(파란색 id)도 체스보드 교차점(빨간색 id)도 모두 검출할 수 있는 것 같습니다.
이것만이라면, 별로 보통 체스 보드에서도 좋지 않다? 라는 느낌이 듭니다.
그러나 이미지를 볼 수 있듯이 charuco 모듈에서 감지되는 체스 보드의 교차점에는 각각 별도의 ID 번호가 있습니다. 아마도이 교차점 ID는 교차점에 가장 가까운 마커 ID를 기반으로 할당하는 것 같습니다. 이렇게하면 일반 체스 보드와 약간 다른 촬영을 할 수 있습니다. 그것은...
이 방법으로 전체 보드가 보이지 않더라도 체스 보드 교차점을 감지 할 수 있습니다.
일반 체스보드 교차점 감지 함수 cv::findChessboardCorners를 사용하면 지정된 매스의 체스보드 이미지 전체가 표시되지 않으면 감지할 수 없습니다. 그래서 카메라를 보드에 가까이 하거나 보드를 화각의 가장자리에서 촬영하려고 하면 보드가 화각 밖으로 튀어나와 보드를 검출할 수 없게 되는 경우가 있었습니다. 그 때문에 통상의 체스보드라면 캘리브레이션용의 촬영 자체가 상당히 번거롭거나 어려웠던 경우가 많습니다만, 이것을 사용하면 효율적으로 촬영할 수 있을 것 같고, 체스 보드의 일부라도 좋은 것 , 전체를 찍지 않아도 좋은 것을 이용해 여러가지 응용할 수 있을 것 같습니다.
덧붙여서 더 업으로 촬영해도 OK였습니다.
요약
charuco의 보드 감지를 시도했습니다.
기존의 체스보드와는 사양이 다른 검출을 할 수 있었으므로, 어떻게 응용할지 생각해 보고 싶습니다.
Reference
이 문제에 관하여(charuco 교정 보드), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/noueezy/items/58730f09f6aa6a97faf5
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
#include <opencv2/opencv.hpp>
#include <opencv2/aruco/charuco.hpp>
int main(int argc, const char * argv[]) {
//マーカ辞書作成 6x6マスのマーカを250種類生成
cv::Ptr<cv::aruco::Dictionary> dictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_250);
//charucoボード生成 10x7マスのチェスボード、グリッドのサイズ0.04f、グリッド内マーカのサイズ0.02f
cv::Ptr<cv::aruco::CharucoBoard> board = cv::aruco::CharucoBoard::create(10, 7, 0.04f, 0.02f, dictionary);
cv::Mat boardImage;
board->draw(cv::Size(1920, 1080), boardImage, 10, 1);
cv::imwrite("BoardImage.jpg", boardImage);
}
카메라는 iPhone XS 카메라를 사용했습니다.
검색 소스 코드는 다음과 같습니다.
main.cpp
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/aruco/charuco.hpp>
int detectCharucoBoard(std::string srcPath, std::string dstPath)
{
cv::Mat image = cv::imread(srcPath);
cv::Mat imageCopy = image.clone();
//マーカ辞書作成 6x6マスのマーカを250種類生成
cv::Ptr<cv::aruco::Dictionary> dictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_250);
//charucoボード生成 10x7マスのチェスボード、グリッドのサイズ0.04f、グリッド内マーカのサイズ0.02f
cv::Ptr<cv::aruco::CharucoBoard> board = cv::aruco::CharucoBoard::create(10, 7, 0.04f, 0.02f, dictionary);
//マーカー検出時メソッドを指定
cv::Ptr<cv::aruco::DetectorParameters> params = cv::aruco::DetectorParameters::create();
params->cornerRefinementMethod = cv::aruco::CORNER_REFINE_NONE;
//マーカー検出
std::vector<int> markerIds;
std::vector<std::vector<cv::Point2f> > markerCorners;
cv::aruco::detectMarkers(image, board->dictionary, markerCorners, markerIds, params);
if (markerIds.size() > 0) {
//マーカー位置を描画
cv::aruco::drawDetectedMarkers(imageCopy, markerCorners, markerIds);
//マーカーの座標をもとに、チェスボード画像の交点を検出
std::vector<cv::Point2f> charucoCorners;
std::vector<int> charucoIds;
cv::aruco::interpolateCornersCharuco(markerCorners, markerIds, image, board, charucoCorners, charucoIds);
if (charucoIds.size() > 0)
{
//チェスボード交点位置を描画
cv::aruco::drawDetectedCornersCharuco(imageCopy, charucoCorners, charucoIds, cv::Scalar(0, 0, 255));
}
}
cv::imwrite(dstPath, imageCopy);
return 0;
}
int main(int argc, const char * argv[]) {
detectCharucoBoard("./IMG_5410.jpeg", "./IMG_5410_detect.jpg");
detectCharucoBoard("./IMG_5411.jpeg", "./IMG_5411_detect.jpg");
detectCharucoBoard("./IMG_5412.jpeg", "./IMG_5412_detect.jpg");
return 0;
}
이미지를 보자.
이 이미지는 ...
이렇게 됩니다. 마커(파란색 id)도 체스보드 교차점(빨간색 id)도 모두 검출할 수 있는 것 같습니다.
이것만이라면, 별로 보통 체스 보드에서도 좋지 않다? 라는 느낌이 듭니다.
그러나 이미지를 볼 수 있듯이 charuco 모듈에서 감지되는 체스 보드의 교차점에는 각각 별도의 ID 번호가 있습니다. 아마도이 교차점 ID는 교차점에 가장 가까운 마커 ID를 기반으로 할당하는 것 같습니다. 이렇게하면 일반 체스 보드와 약간 다른 촬영을 할 수 있습니다. 그것은...
이 방법으로 전체 보드가 보이지 않더라도 체스 보드 교차점을 감지 할 수 있습니다.
일반 체스보드 교차점 감지 함수 cv::findChessboardCorners를 사용하면 지정된 매스의 체스보드 이미지 전체가 표시되지 않으면 감지할 수 없습니다. 그래서 카메라를 보드에 가까이 하거나 보드를 화각의 가장자리에서 촬영하려고 하면 보드가 화각 밖으로 튀어나와 보드를 검출할 수 없게 되는 경우가 있었습니다. 그 때문에 통상의 체스보드라면 캘리브레이션용의 촬영 자체가 상당히 번거롭거나 어려웠던 경우가 많습니다만, 이것을 사용하면 효율적으로 촬영할 수 있을 것 같고, 체스 보드의 일부라도 좋은 것 , 전체를 찍지 않아도 좋은 것을 이용해 여러가지 응용할 수 있을 것 같습니다.
덧붙여서 더 업으로 촬영해도 OK였습니다.
요약
charuco의 보드 감지를 시도했습니다.
기존의 체스보드와는 사양이 다른 검출을 할 수 있었으므로, 어떻게 응용할지 생각해 보고 싶습니다.
Reference
이 문제에 관하여(charuco 교정 보드), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/noueezy/items/58730f09f6aa6a97faf5
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Reference
이 문제에 관하여(charuco 교정 보드), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/noueezy/items/58730f09f6aa6a97faf5텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)