Visual Studio 2013 Express Visual C++( アンマネージドコード ) OpenCV 3.1 |
■239.OpenCV事始 | Prev Top Next | |
|
今回は Visual C++ で OpenCV やります。
まずは開発環境を構築します。 公式パッケージをダウンロードして Visual Studio 上でインクルードおよびライブラリのパスを設定します。
公式パッケージのダウンロードはOpenCVから行います。2016/02/27 現在の最新バージョンは 3.1 です。 ダウンロードしたら任意のディレクトリに解凍します。
OpenCV用の実行ファイルを自身で作成したプロジェクト内にコピーします。 64ビット環境でコンパイルするため x64 、Visual Studio 2013 を使用するため vc12 配下にある実行ファイルをコピーします。 D:\Program Files\opencv-3.0.0\build\x64\vc12\bin 環境変数にパスを追加してもいいです。
追加のインクルード ディレクトリ( D:\Program Files\opencv-3.0.0\build\include )
追加のライブラリ ディレクトリ( D:\Program Files\opencv-3.0.0\build\x64\vc12\lib )
構成マネージャーのプラットフォームをx64に変更します。
#pragma once #include <math.h> #include <stdlib.h> #include <memory> class Perlin { private: int _repeat = -1; std::unique_ptr<int[]> p; double fade(double t); int inc(int num); double lerp(double a, double b, double x); double dot( double x1, double x2, double y1, double y2, double z1, double z2 ); double grad(int hash, double x, double y, double z); public: Perlin(int repeat = -1); ~Perlin(); double perlin(double x, double y, double z); };---Perlin_Tiled.cpp---
#include "Perlin_Tiled.h" Perlin::Perlin( int repeat ) : p(new int[512]), _repeat( repeat ) { // 0 - 255 int permutation[] = { 151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140, 36, 103, 30, 69, 142, 8, 99, 37, 240, 21, 10, 23, 190, 6, 148, 247, 120, 234, 75, 0, 26, 197, 62, 94, 252, 219, 203, 117, 35, 11, 32, 57, 177, 33, 88, 237, 149, 56, 87, 174, 20, 125, 136, 171, 168, 68, 175, 74, 165, 71, 134, 139, 48, 27, 166, 77, 146, 158, 231, 83, 111, 229, 122, 60, 211, 133, 230, 220, 105, 92, 41, 55, 46, 245, 40, 244, 102, 143, 54, 65, 25, 63, 161, 1, 216, 80, 73, 209, 76, 132, 187, 208, 89, 18, 169, 200, 196, 135, 130, 116, 188, 159, 86, 164, 100, 109, 198, 173, 186, 3, 64, 52, 217, 226, 250, 124, 123, 5, 202, 38, 147, 118, 126, 255, 82, 85, 212, 207, 206, 59, 227, 47, 16, 58, 17, 182, 189, 28, 42, 223, 183, 170, 213, 119, 248, 152, 2, 44, 154, 163, 70, 221, 153, 101, 155, 167, 43, 172, 9, 129, 22, 39, 253, 19, 98, 108, 110, 79, 113, 224, 232, 178, 185, 112, 104, 218, 246, 97, 228, 251, 34, 242, 193, 238, 210, 144, 12, 191, 179, 162, 241, 81, 51, 145, 235, 249, 14, 239, 107, 49, 192, 214, 31, 181, 199, 106, 157, 184, 84, 204, 176, 115, 121, 50, 45, 127, 4, 150, 254, 138, 236, 205, 93, 222, 114, 67, 29, 24, 72, 243, 141, 128, 195, 78, 66, 215, 61, 156, 180 }; const int len = _countof(permutation); for (int x = 0; x < 512; x++) { p[x] = permutation[x % len]; } // int* p2 = p.get(); } Perlin::~Perlin() { } double Perlin::perlin(double x, double y, double z) { if (_repeat > 0) { x = fmod(x, _repeat); y = fmod(y, _repeat); z = fmod(z, _repeat); } int xi = (int)floor(x); int yi = (int)floor(y); int zi = (int)floor(z); double xf = x - xi; double yf = y - yi; double zf = z - zi; // フェード関数 double u = fade(xf); double v = fade(yf); double w = fade(zf); // ハッシュ関数 int aaa, aba, aab, abb, baa, bba, bab, bbb; aaa = p[p[p[xi] + yi] + zi]; aba = p[p[p[xi] + inc(yi)] + zi]; aab = p[p[p[xi] + yi] + inc(zi)]; abb = p[p[p[xi] + inc(yi)] + inc(zi)]; baa = p[p[p[inc(xi)] + yi] + zi]; bba = p[p[p[inc(xi)] + inc(yi)] + zi]; bab = p[p[p[inc(xi)] + yi] + inc(zi)]; bbb = p[p[p[inc(xi)] + inc(yi)] + inc(zi)]; // 線形合成 double x1, x2, y1, y2, l; x1 = lerp(grad(aaa, xf, yf, zf), // + Vec3( 0, 0, 0 ) grad(baa, xf - 1, yf, zf), // + Vec3( -1, 0, 0 ) u); x2 = lerp(grad(aba, xf, yf - 1, zf), // + Vec3( 0, -1, 0 ) grad(bba, xf - 1, yf - 1, zf), // + Vec3( -1, -1, 0 ) u); y1 = lerp(x1, x2, v); x1 = lerp(grad(aab, xf, yf, zf - 1), // + Vec3( 0, 0, -1 ) grad(bab, xf - 1, yf, zf - 1), // + Vec3( -1, 0, -1 ) u); x2 = lerp(grad(abb, xf, yf - 1, zf - 1), // + Vec3( 0, -1, -1 ) grad(bbb, xf - 1, yf - 1, zf - 1), // + Vec3( -1, -1, -1 ) u); y2 = lerp(x1, x2, v); l = lerp(y1, y2, w); return ( l + 1.0 ) * 0.5; // [ -1, 1 ] → [ 0, 1 ] } // フェード関数 double Perlin::fade(double t) { // 6t^5 - 15t^4 + 10t^3 return t * t * t * (t * (t * 6.0 - 15.0) + 10.0); } // p配列のオーバーラン防止 int Perlin::inc(int num) { num++; if (_repeat > 0) { num %= _repeat; } return num; } double Perlin::dot( double x1, double x2, double y1, double y2, double z1, double z2 ) { return x1 * x2 + y1 * y2 + z1 * z2; } // 線形合成 double Perlin::lerp(double a, double b, double x) { return a + x * (b - a); } // グラディエント関数 double Perlin::grad(int hash, double x, double y, double z) { float g[][3] = { { 1, 1, 0 }, { -1, 1, 0 }, { 1, -1, 0 }, { -1, -1, 0 }, { 1, 0, 1 }, { -1, 0, 1 }, { 1, 0, -1 }, { -1, 0, -1 }, { 0, 1, 1 }, { 0, -1, 1 }, { 0, 1, -1 }, { 0, -1, -1 }, { 1, 1, 0 }, { 0, -1, 1 }, { -1, 1, 0 }, { 0, -1, -1 } }; int index = 15 * hash / 255; return dot( g[index][0], x, g[index][1], y, g[index][2], z ); }---main.cpp---
#include <memory> #include <opencv2\highgui\highgui.hpp> #include "Perlin_Tiled.h" #pragma comment( lib, "opencv_world300d.lib" ) void createWindow(cv::Mat& img, std::string winname) { // ウィンドウを生成する cv::namedWindow(winname, cv::WINDOW_AUTOSIZE); // ウィンドウに画像を表示する cv::imshow(winname, img); // キー入力待機 cv::waitKey(0); // ウィンドウの破棄 cv::destroyAllWindows(); } int createPerlin2D() { // CV_8UC3: 符号なし8bit整数、チャンネル数3( RGB ) // cv::Scalar(0, 0, 255):画像の色をBGRで指定 cv::Mat img = cv::Mat(cv::Size(640, 480), CV_8UC3, cv::Scalar(0, 0, 0)); std::unique_ptr<Perlin> perlin( new Perlin() ); for (int i = 0; i < img.rows; i++) // 高さ { for (int j = 0; j < img.cols; j++) // 幅 { double x = (double)j * 0.03; double y = (double)i * 0.03; double p = perlin->perlin(x, y, 0); img.at<cv::Vec3b>(i, j)[0] = (uchar)( p * 255 ); img.at<cv::Vec3b>(i, j)[1] = (uchar)( p * 255 ); img.at<cv::Vec3b>(i, j)[2] = (uchar)( p * 255 ); } } // ウィンドウ表示 createWindow(img, "perlin noise"); return 0; } int main(int argc, const char* argv[]) { return createPerlin2D(); }