#目次
1.はじめに
2.環境
3.エラーが起こった関数
4.実装したコード
5.エラー内容
6.矩形の作り方
7.解決法
8.おわりに
9.参考文献
#1. はじめに
今回はOpenCVの関数Subdiv2Dを使用した際に領域外指定のエラーが出現したことの記録,およびその解決法について記述する.
#2. 環境
・OpenCV 3.4.14
・Visual Studio 2017, 2019
・C++
#3. エラーが起こった関数
今回エラーが発生した関数はOpenCVに実装されているSubdiv2Dという関数である.ドロネー三角形分割を行うためにこの関数を用いた.
関数の使い方としては,
1.矩形(Rectangle)を作成
2.矩形の大きさのSubdiv2Dオブジェクトを作成
3.領域内に母点となる点の座標を挿入
のような流れである.
#4. 実装したコード
今回実装したコードを記述する.
void drawDelaunay(cv::Mat img, cv::vector<Point> points)
{
Size size = img.size();
Rect rect(0, 0, size.width, size.height); // width, height共に500
cv::Subdiv2D subdiv;
subdiv.initDelaunay(rect); // 領域の指定
Subdiv.insert(points); // 母点の挿入
// ドロネー三角形のリストを取得する
std::vector<cv::Vec6f> triangles;
subdiv.getTriangleList(triangles);
/*----------------------------------------------------------------*/
// 以下描画の記述,今回は省略
}
上記はドロネー三角形分割を行い描画する関数drawDelaunay()である.幅と高さが500の画像imgと,母点となる配列pointsを引数として渡す.**今回pointsにはPoint(0,0) <= Point(x, y) <= Point(500, 500)の範囲の座標を格納してある.**描画する記述については,今回のエラーと関係がないので省略した.
なお,母点とはドロネー三角形分割を行うときの用語であるが,詳しいことは以下のサイトで参照してほしい.
ボロノイ図とは
最終閲覧日:2021年5月7日
#5. エラー内容
今回のエラーは以下.
OpenCV(3.4.13) Error: One of the arguments' values is out of range () in cv::Subdiv2D::locate, file C:\build\3_4_winpack-build-win64-vc15\opencv\modules\imgproc\src\subdivision2d.cpp, line 288
これを見る限り,out of range とあるので領域外指定をしているらしい.
なぜだろうか,きちんと母点となる点の座標は「0<=x<=500, 0<=y<=500」にしているというのに.
#6. 矩形の作り方
ところで,C++で矩形(Rectangle)を作るときは**Rect rect(x, y, width, height);**と書けば良い.
ここで各パラメータは,
x : TopLeftのx座標
y : TopLeftのy座標
width : 矩形の幅
height : 矩形の高さ
である.
つまり,左上の頂点座標を指定,矩形の幅と高さを与えれば良いのである.
#7. 解決法
本題に入る.
さて,2節のコードに登場したrectは,左上の頂点座標が(0, 0)で,幅と高さ(width, height)はそれぞれ500, 500であるが,rectの右下の頂点座標はいくつだろうか?
(500, 500)!
なんてふざけたことを言ってはいけない.
左上の頂点が(0, 0)で幅と高さが500,500ということは,右下の頂点座標は**(499, 499)**なのだ.
(幅 = 500 = 右端のx座標 - 左端のx座標 ( = 0 ) + 1 → 右端のx座標 = 499)
つまり,今回私が指定した領域の端は,x = y = 499であるため,pointsに格納してあるx = 500またはy = 500の点を挿入すると当然領域外となる.
さて,エラー内容が至極単純なものだから解決法も単純明快だ.
x = 500, y = 500 となるような点をx = 499, y = 499 に変更するだけである.
(画像サイズを変更しても対応できるように,width-1, height-1 のように記述すると良いだろう.)
#8. おわりに
今回のエラー内容はドロネー三角形分割に直接関わるエラーではなく,至極単純なミスだった.しかし,こういった単純なミスによるエラーは単純すぎることによって発覚が遅れることがある.うっかりミスをなくしていきたいものだ.
#9. 参考文献
ドロネー図の描画について知りたいときは以下を参照すると良いだろう.
OpenCV C++/IFでボロノイ図・ドロネー図を描く
最終閲覧日:2021年5月7日