LoginSignup
0
1

More than 1 year has passed since last update.

Subdiv2D使用時における領域外指定について

Last updated at Posted at 2021-05-07

#目次
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)

スクリーンショット (29).png

つまり,今回私が指定した領域の端は,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日

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1