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に変更します。


今回はついでに Perlin Noise やります。サンプルプログラムはGitHubをほぼ丸パクリです
日本語解説はPOSTDです。


---Perlin_Tiled.h---
#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();
}


Prev Top Next
inserted by FC2 system