さいたま開発勉強会vol.3に行ってきました

はじめに

12月3日に行われた、さいたま開発勉強会vol.3に参加してきました。

発表内容

最新鋭!Xcode4.2.1 Storyboardで作るiPhone5ブラウザ実演! (@aoi68kさん)

ドラッグ&ドロップでボタンを配置し、それを画面とつなげて画面遷移を作ると、自分でコードを書かなくても簡単に画面遷移が作ることができてすごい!という話でした。
これを利用して作ったアプリを動作させるにはiOS5以上の環境が必要だそうです。

ネットゲームつくろうぜ on Unity (@shinriyoさん)


photonElectroServer5というサーバでそれぞれUnityのサンプルを動かすまでの手順の紹介でした。
割と簡単にゲームを作れると評判のUnityですが、ネットゲームを作るとなるとサンプルを動かすのもなかなか大変なようです。

Windows Phoneの話 (@integraさん)

WindowsPhoneのアプリの開発の話で、

  • Visual StudioExpression Blendといった優れた開発環境がある
  • WP7.5から、カメラやジャイロセンサなどのデバイスが比較的簡単に使えるようになった
  • Windows Phone用のXNA Game StudioはXbox向けにビルドできない
  • TouchDevelopというWPアプリを使ってデバイス上でアプリを作ることもできる

といった内容でした。
この中でおもしろいなーと思ったのがTouchDevelopでした。コードを書くわけではなく組み込みの命令を選択する形式なのですが、スマートフォンのキーボードでコードを書くのはやっぱり厳しい気がするので、そのあたりがクリアできているのが素敵ポイントかと思います。

iPadで作るPOSシステム (@xlf01512さん)

なんとiPadでPOSシステムを作ってしまったという発表でした。iPad上で購入する商品を選択すると、しっかりレシートまで印刷されるという本格仕様。
iPadとレシートプリンタの接続は、レシートプリンタの無線LAN(802.11b)インタフェースを使っているとのことです。

App Inventorつかってみた (@f_megmeg5さん)

コードを書かずにAndroidアプリが作れるというApp Inventorの紹介でした。
Web上でコンポーネントを配置したり、動作をGUIで組み合わせるだけで「ボタンに画像を設定し、押すと音声が流れるアプリ」をその場で作ってエミュレータで動かすというデモがあり、非常に簡単にアプリが作れるんだなーという印象でした。
しかし、やはり制限も大きいようで、

  • UIの作りこみが難しい
  • 複雑な動作を作るのは難しい
  • サーバ側でビルドしてしまうので、コードはデコンパイルしないと手に入らない
  • キーストアが作れないため、Androidマーケットに出せない

とのことです。

あと、デモアプリの音声の作成には、ゆっくろいどという音声合成ソフトを使っていました。こんなのもあるんですねー。

Live○○○ing (@yoichinejiさん)

ゲームの開発に必要となる画像や音楽、3Dモデルといった素材を作るためのソフトウェアの紹介&実演でした。

  • SAI
    • ペイントツール
    • Windows用
    • 手ブレ補正がある
    • ペン入れレイヤーで、描いた線をあとから曲げた修正したりできる
    • 筆圧検知
  • EDGE2
    • ドット画像作成ツール
    • Windows用
    • EDGE2は有料のツール、EDGE1は無料で使える
    • オニオンスキンという機能がアニメーション作成に便利
      • パラパラマンガの次のページが薄く透けて見えるようになる
  • KORG iKaossilator
    • iPhone/iPad用シンセサイザ
    • iOS用
    • Ver.2になってExportできるようになったため、BGMの作成に使える
  • Sculptris
    • 3Dモデリングツール
    • Windows/Mac用
    • 無料!!!!
    • 粘土みたいな感じでモデルを作成できる
    • objファイルでエクスポートするとUnityで使える

KORG iKaossilatorはBGM作成だけでなく、普通に遊ぶだけでもおもしろそうなアプリでした。
また、Sculptrisは本当に粘土で形を作る感覚で、Blenderなどよりも簡単に操作できそうな印象でした。

まとめ

そんなわけで、さいたま開発勉強会vol.3に参加してきました。

Ubuntu 11.10インストール後の環境構築 -基本編-

10月13日にUbuntu 11.10がリリースされました!
そんなわけで、いつものように環境設定でやったことを書いておきます。
例によって開発環境以外のものだけです。開発環境はまたあとで。

環境

環境構築

ホームディレクトリのディレクトリ名を英語にする
$ LANG=C xdg-user-dirs-gtk-update
CapsLockキーをCtrlキーにする

1. システム設定→キーボード→レイアウトの設定→オプションで「キーボードレイアウトのオプション」を表示
2. 「Ctrlの位置」で「Make CapsLock an additional Ctrl」を選択

Ctrl+spaceで入力切り換えしないようにする

1. 上段パネルのキーボードアイコンをクリックして「設定」→「一般」タブを開いて「キーボードショートカット」の「切り替え」の右側の「...」をクリック
2. 「キーボードショートカット」で「Ctrl+space」を選択して削除

CompizConfig 設定マネージャのインストール
$ sudo apt-get install compizconfig-settings-manager

または

Dashでcompizconfigで検索して「CompizConfig設定マネージャー」を選択→Ubuntuソフトウェアセンターが開くので、そこからインストール

Chromiumのインストール
$ sudo apt-get install chromium-browser

または Dashでchromiumで検索して(ry

zshのインストール
$ sudo apt-get install zsh zsh-dev
$ chsh -s /bin/zsh

一旦ログアウトし、ログインし直せば完了

tmuxのインストール
$ sudo apt-get install tmux
StarDictをインストール
$ sudo apt-get install stardict stardict-tools

辞書は
$HOME/.stardict/dic
に配置。 /usr/share/stardict/dic でもいいけど。

Adobe Readerのインストール
$ sudo apt-get install adobereader-jpn
Mozcのインストール

インストール

$ sudo apt-get install ibus-mozc

Mozcを有効化

1. ibusを再起動(上段パネルのキーボードアイコンをクリック→再起動)
2. 上段パネルのキーボードアイコンをクリックして「設定」→インプットメソッド→「インプットメソッドの選択」でMozcを選択して追加し、「上へ」で順序を上にする
3. ibusを再起動

Emacsのインストールと設定

Emacsのインストール

$ sudo apt-get install emacs


ibus-elのインストール

$ sudo apt-get install ibus-el


C/Migemoのインストール
UbuntuにC/MigemoをインストールしてEmacsで使う


Emacs利用時にXIMを無効化
ホームディレクトリの.Xresourcesファイル(なかったら作成)に

Emacs*useXIM: false

という行を追加して

$ xrdb ~/.Xresources

を実行(またはログアウトしてXサーバを再起動)します。

VirtualBoxのインストール

1. /etc/apt/sources.list に下記を追記

deb http://download.virtualbox.org/virtualbox/debian oneiric contrib

2. リポジトリの追加

$ wget -q http://download.virtualbox.org/virtualbox/debian/oracle_vbox.asc -O- | sudo apt-key add -

3. インストール

$ sudo apt-get update
$ sudo apt-get install virtualbox-4.1

4. VirtualBox Extension Packのインストール

1. Download VirtualBoxからVirtualBox Extension Packをダウンロード
2. VirtualBoxを起動し、ダウンロードしたファイルをドラッグ&ドロップしてインストール

参考: Download VirtualBox for Linux Hosts

その他、ちょっとしたツールなどのインストール

rlwrapのインストール

$ sudo apt-get install rlwrap

xselのインストール

$ sudo apt-get install xsel

VLゴシックのインストール

$ sudo apt-get install ttf-vlgothic

まとめ

Ubuntu 11.10の環境構築を行いました。

メールサーバ勉強会 #mailerstudy 01に行ってきました

はじめに

10月1日に行われた、メールサーバ勉強会 #mailerstudy 01に行ってきました。

 

メールシステムのおはなし (@ar1さん)

Postfix詳解の著者の@ar1さんによる、メールの仕組みの解説です。
前半は「メールシステム 超基本編」として、メールの転送の仕組みやMTA、MUAなどの用語解説といったメールの基本的な仕様(@ar1さんいわく、「キレイゴトの世界」)について説明していただきました。また、後半は「メールシステム 現実編」として、ログやSPAM対策など、メールサーバを運用していく上で必要となるものを紹介していただきました。

知らなかったこととかおもしろかったこととか
  • メールのエンベロープ
    • メールの転送、という観点から説明するときは、封筒のイメージ
    • セキュリティの観点から説明するときは、普通のはがき
    • 封筒の図(資料のp.9)を使えば、お客さんに「わかったつもりになってお帰りいただく」ことができるw
  • 昔あったメールアドレスの形式
    • user % example.com @ relay
      • 中継メールサーバを指定できたころに使われていた形式
    • @relay: user@example.com
      • 同上
    • example.com ! user
      • UUCPで使われていた形式
  • メーリングリスト配送で一度に送信できる数
    • SMTPの規定では少なくとも50まで(メールサーバ側で設定可能)
    • もしこれを超えたら、エラーコードがかえってきて切断される
  • DNSBL(DNS Blacklist)
    • フィルタリング情報をDNSにのせて配布
    • DNSBLのためにGoogleの8.8.8.8を使ってみたら速かったのでおすすめ

POP3/IMAP4 入門 (@ttkzwさん)

@ttkzwさんによる、POP3とIMAP4の解説です。@ar1さんの説明でさらっと触れられていたプロトコルについて、デモを交えて詳しく説明していただきました。

知らなかったこととかおもしろかったこととか。
  • APOPはセキュリティ的に脆弱性があるので使っちゃだめ
  • POP3でメールが削除されるタイミング
    • DELEコマンドを実行した直後は削除マークがつくだけ
    • 実際に削除されるのはQUITするとき

パネルディスカッション (@ttkzwさん、@nagi100さん、@ar1さん)

会場から質問を受け付けて討論…だったはずですが、いつの間にか「qmailをDisる会」にw

おもしろかった話
  • qmailはオワコン
    • 開発が終了しており、困っても誰もサポートしてくれない(作者ですら)
    • RFCの新しい規格に対応してない
    • DNSSECとかにも対応してない
    • ほかのMTAへの移行はそんなに難しくない
  • 会社の環境がExchangeになってPOPもIMAPも使えなくなった話
    • ExchangeもPOP,IMAPの機能はあるが、会社のポリシーとして塞いであるという状態
    • Thunderbird拡張機能でなんが便利なのがあるらしい
  • 普段使っているメーラ

まとめ

そんなわけで、メールサーバ勉強会に行ってきました。

Google Developer Day 2011のDevQuizをやってみました

はじめに

Google Developer Day 2011のDevQuizをやってみたので、回答を晒してみます。

Web Game

問題

シンプルな神経衰弱ゲームです。カードはクリックすることでめくることができます。全 64 セットを解くことで問題クリアとなります。


解き方
1枚目のカードを開いてその色を取得するChrome Extensionのサンプルが公開されていましたが、Chrome Extensionは作成せずにJavaScriptコンソール上でJavaScriptを直接実行する、という方法で対応しました。

// -*- coding: utf-8 -*-
/**
   Google Developer Day 2011 DevQuiz - Web Game
   http://gdd-2011-quiz-japan.appspot.com/problems?problem=webgame

   solve_webgame.js

   1. ChromeでWeb Game(http://gdd-2011-quiz-japan.appspot.com/webgame/problem)を開く
   2. Chromeの設定→ツール→JavaScriptコンソール を開く
   3. JavaScriptコンソール の Console を選択し、コンソールウィンドウに下記をコピペして Enter を押す
*/
(function () {
    function getColor(i) {
	var element = document.getElementById('card' + i);
	if (element == null) {
	    return null;
	}
	else {
	    var myevent = document.createEvent('MouseEvents');
	    myevent.initEvent('click', false, true);
	    element.dispatchEvent(myevent);
	    return element.style.backgroundColor;
	}
    }

    function solve(colors) {
	var i, j;
	var size = colors.length;
	var answer = [];
	for (i = 0; i < size; i++) {
	    for (j = 0; j < size; j++) {
		if (i == j)
		    continue;
		if (colors[i] == colors[j]) {
		    answer[i] = j;
		    answer[j] = i;
		    break;
		}
	    }
	}
	return answer;
    }

    function main() {
	var i = 0;
	var color;
	var colors = [];
	while ((color = getColor(i)) != null) {
	    colors[i] = color;
	    i++;
	}
	var answer = solve(colors);
	$("#answer").val(answer.join(","));
	$("#solve").submit();
    }
    
    main();
})();

一人ゲーム

問題

数がいくつか与えられます。なるべく少ない手数で数を全て取り除いてください。
あなたは 1 手で、

  • 全ての数を半分にする(端数は切り捨て)
  • 5 の倍数 (0 を含む) を全て取り除く

のどちらかの操作をすることができます。


解き方
単純な幅優先探索です。

  • 全部5の倍数だったら、「全ての数を半分にする」をしない
  • 5の倍数が1つも無ければ、「5の倍数を全て取り除く」をしない

という枝刈りを入れています。

#!/usr/bin/env ruby
# -*- mode: ruby; coding: utf-8-unix -*- 

# Google Developer Day 2011 DevQuiz - Algorithm
# http://gdd-2011-quiz-japan.appspot.com/problems?problem=algorithm
#
# solve_hitorigame.rb
#
class Problem
  attr_reader :count
  
  def initialize(numbers, count = 0)
    @numbers = numbers
    @count = count
    @num_factor5 = numbers.count { |n| n % 5 == 0 }
  end

  def half
    Problem.new(@numbers.map { |n| n >> 1 }, @count + 1)
  end

  def remove5
    Problem.new(@numbers.delete_if { |n| n % 5 == 0 }, @count + 1)
  end

  def finished?
    @numbers.size == 0
  end

  def all_x5?
    @num_factor5 == @numbers.size
  end

  def has_x5?
    @num_factor5 > 0
  end
end

def parse_question(filename)
  questions = []
  open(filename, 'r') { |f| f.read.lines }.map { |line| line.chomp }.each_with_index { |line, i|
    questions << line.split(/\s/).map { |n| n.to_i }.to_a if i > 0 and i.even?
  }
  questions
end

def breadth_first_search(numbers)
  queue = [Problem.new(numbers)]
  
  while queue.size > 0
    a = queue.shift
    return a.count if a.finished?
    queue << a.half unless a.all_x5?
    queue << a.remove5 if a.has_x5?
  end
  
  raise 'solve: should not reach here'
end

if ARGV.size == 0
  puts "Usage: ruby #{__FILE__} problem_file"
  exit
end

parse_question(ARGV[0]).each { |numbers|
  puts breadth_first_search(numbers)
}

スライドパズル

問題
3×3〜6×6まで、壁ありのスライドパズルを5000問解く、という問題です。

回答
反復深化深さ優先探索をCでゴリゴリ書き*1、マシンパワーに任せて解きました。
タイムアウト時間を60秒に設定し、Core i5 M520 2.40GHz、メモリ4GBのマシンで5プロセス同時に実行して、全体の75%(37.42点)まで回答できました。こんなのでも、たしか数時間で終わったはず。

/* -*- mode: c; coding: utf-8-unix -*- */
/**
   Google Developer Day 2011 DevQuiz - Sliding Puzzle
   http://gdd-2011-quiz-japan.appspot.com/problems?problem=slidingpuzzle

   iterative_deeping_solver.c
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define LIMIT 100
#define ANSWER_POSITIONS_SIZE ('Z' - '0')
#define CHAR2IDX(c) (c - '0')
#define ABS(n) ((n < 0) ? -n : n)

const char* ALNUM = "123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ0";
const int ALNUM_SIZE = 36;

const char DIRECTIONS[] = {'L', 'R', 'U', 'D'};

int glimit = 0;
char groute[LIMIT];
char* gboard_original = NULL;
char* gboard = NULL;
int gwidth = 0;
int gheight = 0;

char* ganswer;
char ganswer_positions_x[ANSWER_POSITIONS_SIZE];
char ganswer_positions_y[ANSWER_POSITIONS_SIZE];

void init_answer(int width, int height, const char* board)
{
  int board_size = width * height;
  ganswer = (char*)malloc(sizeof(char) * (board_size + 1));
  int i;
  for (i = 0; i < board_size; i++) {
    ganswer[i] = (board[i] == '=') ? '=' : ALNUM[i];
  }
  ganswer[board_size - 1] = '0';
  ganswer[board_size] = '\0';

  for (i = 0; i < board_size; i++) {
    int y = (int)(i / width);
    int idx = CHAR2IDX(ALNUM[i]);
    ganswer_positions_y[idx] = y;
    ganswer_positions_x[idx] = i - width * y;
  }
  int idx = CHAR2IDX('0');
  ganswer_positions_y[idx] = height - 1;
  ganswer_positions_x[idx] = width - 1;
}

void release_all()
{
  if (ganswer != NULL) {
    free(ganswer);
  }
  if (gboard != NULL) {
    free(gboard);
  }
}

int distance(char c, int x, int y)
{
  int idx = CHAR2IDX(c);
  x -= ganswer_positions_x[idx];
  y -= ganswer_positions_y[idx];
  return ABS(x) + ABS(y);
}

int total_distance(int width, int height, const char* board)
{
  int dist = 0;
  int i, j;
  for (j = 0; j < height; j++) {
    int jw = j * width;
    for (i = 0; i < width; i++) {
      char c = gboard_original[jw + i];
      if (c != '=') {
	dist += distance(c, i, j);
      }
    }
  }
  return dist;
}

int solve(int count, int x0, int y0, int lower_limit, char prev_dir)
{
  if (count > glimit) {
    return 0;
  }
  if (strcmp(gboard, ganswer) == 0) {
    return 1;
  }

  int i;
  int x1, y1;
  for (i = 0; i < 4; i++) {
    switch (DIRECTIONS[i]) {
    case 'L':
      if (prev_dir == 'R') {
	continue;
      }
      x1 = x0 - 1;
      y1 = y0;
      break;
    case 'R':
      if (prev_dir == 'L') {
	continue;
      }
      x1 = x0 + 1;
      y1 = y0;
      break;
    case 'U':
      if (prev_dir == 'D') {
	continue;
      }
      x1 = x0;
      y1 = y0 - 1;
      break;
    case 'D':
      if (prev_dir == 'U') {
	continue;
      }
      x1 = x0;
      y1 = y0 + 1;
      break;
    default:
      puts("error");
      exit(-1);
      break;
    }

    int pos0 = y0 * gwidth + x0;
    int pos1 = y1 * gwidth + x1;
    if (x1 < 0 || x1 >= gwidth || y1 < 0 || y1 >= gheight || gboard[pos1] == '=') {
      continue;
    }

    groute[count] = DIRECTIONS[i];
    char tmp = gboard[pos1];
    gboard[pos0] = gboard[pos1];
    gboard[pos1] = '0';

    int next_lower = lower_limit - distance(tmp, x1, y1) + distance(tmp, x0, y0);
    if (next_lower + count <= glimit) {
      if (solve(count + 1, x1, y1, next_lower, DIRECTIONS[i])) {
	return 1;
      }
    }

    groute[count] = '\0';
    gboard[pos0] = '0';
    gboard[pos1] = tmp;
  }
  
  return 0;
}

void parse_line(const char* line)
{
  gwidth = line[0] - '0';
  gheight = line[2] - '0';
  gboard_original = (char*)(line + 4);
  gboard = (char*)malloc(sizeof(char) * (gwidth * gheight + 1));
}

int main(int argc, char *argv[])
{
  if (argc != 2) {
    exit(-1);
  }
  parse_line(argv[1]);
  init_answer(gwidth, gheight, gboard_original);

  int x0, y0;
  int i, j;
  for (j = 0; j < gheight; j++) {
    int jw = j * gwidth;
    for (i = 0; i < gwidth; i++) {
      if (gboard_original[jw + i] == '0') {
	x0 = i;
	y0 = j;
	j = gheight;
	break;
      }
    }
  }

  int board_size = gwidth * gheight;
  int lower_limit = total_distance(gwidth, gheight, gboard_original);

  for (i = 0; i < LIMIT; i++) {
    glimit = i;
    memset(groute, 0, LIMIT);
    strcpy(gboard, gboard_original);
    if (solve(0, x0, y0, lower_limit, '0')) {
      puts(groute);
      break;
    }
  }

  release_all();
  
  return 0;
}


実行する際はこんな感じのスクリプトを使用し、プロセスを監視して制限時間を超えたらkillするようにしています。

#!/usr/bin/env ruby
# -*- mode: ruby; coding: utf-8-unix -*- 
# solve_slidingpuzzle.rb

if ARGV.size < 2
  puts "Usage: ruby #{__FILE__} problems.txt output-filename"
  exit
end

result = {}
LIMIT_TIME = 60
CMD = './solver/iterative_deeping_solver'

begin
  lines = nil
  open(ARGV[0], 'r') { |f|
    lines = f.read.lines.map { |m| m.chomp }
    lines.reject! { |line| line !~ /^(\d),(\d),[\d\w=]+$/ }
  }
  
  lines.each { |line|
    begin
      pid = nil
      result[line] = 'Timeout'
      th = Thread.new {
        IO.popen("#{CMD} #{line}") { |io|
          pid = io.pid
          ret = io.gets
          result[line] = ret.chomp unless ret.nil?
        }
      }
      Process.kill('SIGHUP', pid) if th.join(LIMIT_TIME).nil?
      Thread::kill(th)
    rescue => e
      result[line] = e.message
      Thread::list.each { |t| Thread::kill(t) if t != Thread::current }
      GC.start
    end
  }
ensure
  begin
    open(ARGV[1], 'w') { |f|
      lines.each { |line|
        f.puts "#{line}\t#{result[line]}"
      }
    }
  rescue
    lines.each { |line|
      puts "#{line}\t#{result[line]}"
    }
  end
end

スライドパズルはしばらくRubyで単純な幅優先探索→A*アルゴリズム→双方向A*→反復深化深さ優先探索という順に試していたのですが、思ったような速度が出なかったため、Cに切り替えました。するとどうでしょう、いままで全く歯が立たなかった4×4がいとも簡単に解けていく…。やっぱC速いですね。書くのは超めんどくさいですが。
双方向A*版をCで書いて評価関数を工夫する、というアプローチも試したかったのですが、今回は時間切れで断念。気が向いたらやってみます。

結果

合計137.4点でした。最終的なボーダーラインの目安が101点前後らしいので、たぶん大丈夫なはず。

ウォームアップクイズ 40.0点
Web Game 30.0点
一人ゲーム 30.0点
スライドパズル 37.4点
合計 137.4点

まとめ

Google Developer Day 2011のDevQuizを解いてみました。こういうのに挑戦すると、普段使わないようなアルゴリズムを使うことができて楽しいですねー。10月にGoogle Code Jam Japan 2011も開催されるようなので、こちらも挑戦してみようかと思います。

*1:もちろん-O4で最適化

OpenCVをホームディレクトリ以下にインストールする -Mac OS X Lion編-

環境

  • Mac OS X 10.7 Lion
  • OpenCV 2.3.1
  • gcc version 4.2.1 (LLVM build 2335.15.00)
  • homebrew 0.8

手順

1. まずは依存ライブラリやツールをインストール
Xcodeをインストールしたりhomebrewをインストールしたりするのは済んでいる前提で。

homebrewを使って依存ライブラリ等をインストールします。今回はGtk+ではなく、Qtにしました。

$ brew install cmake
$ brew install pkg-config
$ brew install libtiff
$ brew install jasper
$ brew install tbb
$ brew install ffmpeg
$ brew install qt


2. OpenCVをダウンロードして解凍
http://sourceforge.net/projects/opencvlibrary/ からソースコードをダウンロードします。
前回と同じく、Unix版のOpenCV 2.3.1を使用しました。
ダウンロードしたファイルは、

$ tar xvf OpenCV-2.3.1.tar.bz2

で解凍しておきます。


2. CMAKE_INSTALL_PREFIXにインストールするパスを指定してcmake
OpenCVをインストールする場所をCMAKE_INSTALL_PREFIXで指定してcmakeを実行します。
前回と同じく、インストールする場所は

$HOME/local/opencvlibrary

です。
下記のようにオプションを指定し、cmakeを実行します。

$ cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=$HOME/local/opencvlibrary \
 -D BUILD_PYTHON_SUPPORT=ON -D WITH_TBB=ON -D WITH_QT=ON \
 ./OpenCV-2.3.1

他のディレクトリにインストールする場合は、$HOME/local/opencvlibraryの部分を適宜読み替えてください。


3. ビルドしてインストール
そのまんまです。

$ make
$ make install


4. パスの設定
ビルド時にライブラリを見つけられるようにするため、

  • ビルド時に使用する pkg-config のパス (PKG_CONFIG_PATH)
  • 共有ライブラリのパス (DYLD_FALLBACK_LIBRARY_PATH)

の2つを設定します。
PKG_CONFIG_PATH には opencv.pc が配置されているディレクトリ([OpenCVをインストールしたディレクトリ]/lib/pkgconfig)、 DYLD_FALLBACK_LIBRARY_PATH は共有ライブラリが配置されているディレクトリ([OpenCVをインストールしたディレクトリ]/lib)を指定すればOKです。
今回はそれぞれ $HOME/local/opencvlibrary/lib/pkgconfig 、$HOME/local/opencvlibrary/lib となるので、.zshrcなどに下記のように設定を記述します。

# .zshrcに追記
PKG_CONFIG_PATH=$HOME/local/opencvlibrary/lib/pkgconfig:$PKG_CONFIG_PATH
export PKG_CONFIG_PATH
DYLD_FALLBACK_LIBRARY_PATH=$HOME/local/opencvlibrary/lib:$DYLD_FALLBACK_LIBRARY_PATH
export DYLD_FALLBACK_LIBRARY_PATH

最後に、シェルを再起動するか

$ source ~/.zshrc

で設定ファイルを再読込みすれば完了です。


5. 動作確認
OpenCVのサンプルコードの find_obj.cpp で動作確認をしてみます。

$ cd OpenCV-2.3.1/samples/c/
$ g++ find_obj.cpp -o find_obj `pkg-config --libs --cflags opencv`
$ ./find_obj

のようにコマンドを実行すれば、正常に動くはずです。

まとめ

以上、Mac OS X LionでOpenCVをホームディレクトリ以下にインストールする手順でした。

Ubuntu 11.04にOpenJDK 7をインストール

はじめに

Java 7がだいぶ前に出てたので、Ubuntuにインストールしてみました。

環境

  • Ubuntu 11.04 (32bit)
  • OpenJDK 1.7.0

手順

1. OpenJDKのPPAリポジトリを追加してインストール

OpenJDK PPA : Damien Lecanの手順どおり、OpenJDKのPPAリポジトリを追加してインストールします。

$ sudo add-apt-repository ppa:dlecan/openjdk
$ sudo apt-get update
$ sudo apt-get install openjdk-7-jdk


2. Javaの切り替え
そのままだとJava 6を使うようになっているはずなので、Java 7を設定します。

$ sudo update-alternatives --config java
[sudo] password for user: 
alternative java (/usr/bin/java を提供) には 2 個の選択肢があります。

   選択肢    パス                                    優先度  状態
 ------------------------------------------------------------
 * 0            /usr/lib/jvm/java-6-openjdk/jre/bin/java   1061      自動モード
   1            /usr/lib/jvm/java-6-openjdk/jre/bin/java   1061      手動モード
   2            /usr/lib/jvm/java-7-openjdk/jre/bin/java   1051      手動モード

現在の選択 [*] を保持するには Enter、さもなければ選択肢の番号のキーを押してください: 2
update-alternatives: /usr/bin/java (java) を提供するために 手動モード で /usr/lib/jvm/java-7-openjdk/jre/bin/java を使います。

バージョンを確認。ちゃんとJava 7になっているようです。

$ java -version
java version "1.7.0_147-icedtea"
OpenJDK Runtime Environment (IcedTea7 2.0pre) (7~b147-2.0~pre2-3ubuntu1~ppa3)
OpenJDK Server VM (build 21.0-b17, mixed mode)

まとめ

UbuntuにOpenJDK 7をインストールしました。EclipseJava 7を使うには、このへんから取ってくる必要があるようです。NetBeansはもう対応してるとのことなので、そっちでもいいかも。

OpenCVをホームディレクトリ以下にインストールする

はじめに

OpenCVをホームディレクトリ以下にインストールしてみたので、手順を書いておきます。
cmakeのときにディレクトリを指定するだけではなく、PKG_CONFIG_PATHとかLD_LIBRARY_PATHあたりのパスの設定も必要でしたというお話しです。

環境

手順

1. まずは依存ライブラリやツールをインストール

$ sudo apt-get install cmake pkg-config build-essential \
 libtbb2 libtbb-dev \
 libgtk2.0-0 libgtk2.0-dev \
 libpng12-0 libpng12-dev libpng++-dev libpng3 libpnglite-dev libpngwriter0-dev libpngwriter0c2 \
 libjpeg62 libjpeg62-dev libjpeg-progs \
 zlib1g zlib1g-dev libjasper-dev libjasper-runtime libjasper1 \
 pngtools libtiff4-dev libtiff4 libtiffxx0c2 libtiff-tools \
 ffmpeg libavcodec-dev libavcodec52 libavformat52 libavformat-dev \
 libgstreamer0.10-0 libgstreamer0.10-dev libgstreamer-plugins-base0.10-dev \
 libxine1-ffmpeg libxine-dev libxine1-bin libunicap2 libunicap2-dev \
 libdc1394-22-dev libdc1394-22 libdc1394-utils swig libv4l-0 libv4l-dev \
 python-numpy libpython2.7 python python-dev \
 openexr libswscale0 libswscale-dev libeigen2-dev libopenexr-dev


2. OpenCVをダウンロードして解凍
http://sourceforge.net/projects/opencvlibrary/ からソースコードをダウンロードします。
今回はUnix版のOpenCV 2.3.1を使用しました。

解凍は普通に

$ tar xvf OpenCV-2.3.1.tar.bz2

でOKです。


2. CMAKE_INSTALL_PREFIXにインストールするパスを指定してcmake
OpenCVをインストールする場所をCMAKE_INSTALL_PREFIXで指定してcmakeを実行します。
今回は、

$HOME/local/opencvlibrary

にインストールするため、下記のように指定してcmakeを実行します。

$ cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=$HOME/local/opencvlibrary \
 -D BUILD_PYTHON_SUPPORT=ON -D WITH_TBB=ON -D WITH_GTK=ON \
 ./OpenCV-2.3.1

他のディレクトリにインストールする場合は、$HOME/local/opencvlibraryの部分を適宜読み替えてください。


3. ビルドしてインストール
そのまんまです。

$ make
$ make install


4. パスの設定
今回はホームディレクトリ以下にインストールするため、そのままではプログラムのビルド時にライブラリが見つからず、エラーとなってしまいます。そこで、パスの設定が必要となります。
OpenCVで必要なのは、

  • ビルド時に使用する pkg-config のパス (PKG_CONFIG_PATH)
  • 共有ライブラリのパス (LD_LIBRARY_PATH)

の2つです。
PKG_CONFIG_PATH には opencv.pc が配置されているディレクトリ([OpenCVをインストールしたディレクトリ]/lib/pkgconfig)、LD_LIBRARY_PATH は共有ライブラリが配置されているディレクトリ([OpenCVをインストールしたディレクトリ]/lib)を指定すればOKです。
今回はそれぞれ $HOME/local/opencvlibrary/lib/pkgconfig 、$HOME/local/opencvlibrary/lib となるので、.zshrcなど*1に下記のように設定を記述します。

# .zshrcに追記
PKG_CONFIG_PATH=$HOME/local/opencvlibrary/lib/pkgconfig:$PKG_CONFIG_PATH
export PKG_CONFIG_PATH
LD_LIBRARY_PATH=$HOME/local/opencvlibrary/lib:$LD_LIBRARY_PATH
export LD_LIBRARY_PATH


最後に、シェルを再起動するか

$ source ~/.zshrc

で設定ファイルを再読込みすれば完了です。


5. 動作確認
OpenCVのサンプルコードの find_obj.cpp で動作確認をしてみます。

$ cd OpenCV-2.3.1/samples/c/
$ g++ find_obj.cpp -o find_obj `pkg-config --libs --cflags opencv`
$ ./find_obj

のようにコマンドを実行すれば、正常に動くはずです。

まとめ

そんなわけで、OpenCVをホームディレクトリ以下にインストールする手順でした。

*1:bashの人は.bashrcに。cshtcshの人は.cshrcだけど設定の書き方が異なるので注意。