目標
ランダムに生成した2次元点を入力として,ドロネー三角形分割を行い,結果を描画する.この際,以下の2つのライブラリを利用する. * OpenCVのSubdiv2D * Fade2D
実装環境
- OpenCV 3.2
- Fade2D 1.5
- Windows 10 64bit
- Visual Studio 2015
OpenCV Subdiv2D
Visual Studioの設定
ググればすぐに有用な情報が見つかるので,他のサイトをご参照下さい.
プログラム
こちらを参考に実装した.
#include <iostream> using namespace std; #include <random> #include <opencv2/opencv.hpp> // Constants const int PTS_NUM(100); const int PTS_RANGE(600); const string WND_NAME("Delaunay OpenCV Subdiv2D"); int main() { // ----- Generate 2D points // Mersenne twister (random value generator) mt19937 mt; uniform_int_distribution<int> distribution(0, ::PTS_RANGE - 1); vector<cv::Point2f> pts; for (int i = 0; i < ::PTS_NUM; ++i) { int x = distribution(mt); int y = distribution(mt); pts.push_back(cv::Point2f(x, y)); } // ----- Initialize Subdiv2D cv::Subdiv2D subdiv; subdiv.initDelaunay(cv::Rect(0, 0, ::PTS_RANGE, ::PTS_RANGE)); subdiv.insert(pts); // ----- Draw Delaunay triangles cv::Mat img = cv::Mat::zeros(::PTS_RANGE, ::PTS_RANGE, CV_8UC3); // Draw points for (auto pt = pts.begin(); pt != pts.end(); ++pt) { cv::circle(img, *pt, 4, cv::Scalar(0, 0, 255), -1); } // Draw lines vector<cv::Vec6f> vDtTri; subdiv.getTriangleList(vDtTri); for (auto tri = vDtTri.begin(); tri != vDtTri.end(); ++tri) { cv::Vec6f &vec = *tri; cv::Point p1(vec[0], vec[1]); cv::Point p2(vec[2], vec[3]); cv::Point p3(vec[4], vec[5]); cv::line(img, p1, p2, cv::Scalar(64, 255, 128)); cv::line(img, p2, p3, cv::Scalar(64, 255, 128)); cv::line(img, p3, p1, cv::Scalar(64, 255, 128)); } cv::namedWindow(::WND_NAME); cv::imshow(::WND_NAME, img); cv::waitKey(); return 0; }
実行結果
動いた!点を入力していないところにも線が伸びている… なぜだ?
Fade2D
ダウンロードとインストール
- ここの中ほどにある「Getting started」内のリンクから「fadeRelease_v1.50.zip」をダウンロード
- 「C:\Libraries\」に解凍したとする
- 解凍したフォルダ名を「fadeRelease」から「Fade2D-1.5」に変更した
- 以降,「C:\Libraries\Fade2D-1.5」を「Path」と呼ぶ
- 環境変数に「Path\x64」を設定し,PCを再起動
Visual Studioのプロジェクト作成
- Visual Studioを開いて「新しいプロジェクト」を作成
- 「インクルードディレクトリ」に以下を追加
- Path\include_fade2d
- 「ライブラリディレクトリ」に以下を追加
- Path\x64
- 「追加の依存ファイル」に必要なライブラリを追加
- Debug設定: fade2D_x64_v140_Debug.lib
- Release設定: fade2D_x64_v140_Release.lib
プログラム
「Path\examples_2D」にあるサンプルプログラムを参考に実装した.
#include <iostream> using namespace std; #include <random> #include <Fade_2D.h> namespace fade = GEOM_FADE2D; #include <opencv2/opencv.hpp> // Constants const int PTS_NUM(100); const int PTS_RANGE(600); const string WND_NAME("Delaunay Fade 2D"); int main() { // ----- Generate 2D points // Mersenne twister (random value generator) mt19937 mt; uniform_int_distribution<int> distribution(0, ::PTS_RANGE - 1); vector<fade::Point2> pts; for (int i = 0; i < ::PTS_NUM; ++i) { int x = distribution(mt); int y = distribution(mt); pts.push_back(fade::Point2(x, y)); } // ----- Initialize Fade 2D fade::Fade_2D dt((unsigned int)pts.size()); vector<fade::Point2 *> vDtVertPtr; dt.insert(pts, vDtVertPtr); // ----- Draw Delaunay triangles cv::Mat img = cv::Mat::zeros(::PTS_RANGE, ::PTS_RANGE, CV_8UC3); // Draw points for (auto pt = pts.begin(); pt != pts.end(); ++pt) { cv::circle(img, cv::Point(pt->x(), pt->y()), 4, cv::Scalar(0, 0, 255), -1); } // Draw lines vector<fade::Triangle2 *> vDtTri; dt.getTrianglePointers(vDtTri); for (auto tri = vDtTri.begin(); tri != vDtTri.end(); ++tri) { fade::Point2 *pt[3] = { (*tri)->getCorner(0), (*tri)->getCorner(1), (*tri)->getCorner(2) }; cv::Point p1(pt[0]->x(), pt[0]->y()); cv::Point p2(pt[1]->x(), pt[1]->y()); cv::Point p3(pt[2]->x(), pt[2]->y()); cv::line(img, p1, p2, cv::Scalar(64, 255, 128)); cv::line(img, p2, p3, cv::Scalar(64, 255, 128)); cv::line(img, p3, p1, cv::Scalar(64, 255, 128)); } cv::namedWindow(::WND_NAME); cv::imshow(::WND_NAME, img); cv::waitKey(); return 0; }
実行結果
動いた!入力した点にだけ線が伸びている.
以下は,昔に作った実時間デモの映像です.