<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Rest Term</title>
	<atom:link href="http://rest-term.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://rest-term.com</link>
	<description>Web関連技術や雑記など</description>
	<lastBuildDate>Sun, 28 Feb 2010 15:53:35 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Tech Note「OpenMP」加筆</title>
		<link>http://rest-term.com/archives/2716/</link>
		<comments>http://rest-term.com/archives/2716/#comments</comments>
		<pubDate>Sun, 28 Feb 2010 14:13:40 +0000</pubDate>
		<dc:creator>wellflat</dc:creator>
				<category><![CDATA[tech/study]]></category>

		<guid isPermaLink="false">http://rest-term.com/?p=2716</guid>
		<description><![CDATA[Tech Note で OpenMP の加筆を再開しました。
情報量がもう少し増えてきたら、ページを分割して見やすく整理しようと思ってます。
PThreadsと比べるとOpenMPは使うだけなら楽です。
ただ、マルチスレッドプログラミング一般の知識を持たずに使ってもあまり効果は出ないでしょう。
それどころか危険なコードに化けてしまう可能性の方が高いです。。
基礎は大事ですね。
]]></description>
			<content:encoded><![CDATA[<p><a href="http://rest-term.com/contents/other/technote/index.php/Top" title="Top - Tech Note">Tech Note</a> で <strong>OpenMP</strong> の加筆を再開しました。<br />
情報量がもう少し増えてきたら、ページを分割して見やすく整理しようと思ってます。</p>
<p>PThreadsと比べるとOpenMPは使うだけなら楽です。<br />
ただ、マルチスレッドプログラミング一般の知識を持たずに使ってもあまり効果は出ないでしょう。<br />
それどころか危険なコードに化けてしまう可能性の方が高いです。。<br />
基礎は大事ですね。</p>
]]></content:encoded>
			<wfw:commentRss>http://rest-term.com/archives/2716/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>HTML5でSymmetric Nearest Neighbor</title>
		<link>http://rest-term.com/archives/2685/</link>
		<comments>http://rest-term.com/archives/2685/#comments</comments>
		<pubDate>Sat, 20 Feb 2010 17:19:35 +0000</pubDate>
		<dc:creator>wellflat</dc:creator>
				<category><![CDATA[tech/study]]></category>
		<category><![CDATA[cv/im]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://rest-term.com/?p=2685</guid>
		<description><![CDATA[久しぶりの投稿；

Demo: HTML5 Image Processing (Symmetric Nearest Neighbor)
(Firefox3.5とSafari4で動作確認しています)
HTML5でConvolutionFilterに続いて、簡単な画像処理を試してみます。
以前、ActionScriptで書いたSymmetric Nearest NeighborをJavaScriptで。
半径を大きくするとそれなりに絵画っぽくなってくれますが、やはり重いです；
・クライアント
[javascript]
var context = document.getElementById(&#8216;Canvas&#8217;).getContext(&#8216;2d&#8217;);
var bmp = new Bitmap(&#8217;sample.jpg&#8217;, context);
var radius = 3;
bmp.applyFilter(new SNNFilter(radius));
[/javascript]
bitmap.js
(関係ある箇所だけ抜粋)
[javascript]
var Bitmap =  function(source, context) {
  this.initialize.apply(this, arguments);
};
var SNNFilter = function(radius) {
  this.initialize.apply(this, arguments);
};
Bitmap.prototype = {
  initialize : function(source, context) {
    this.bitmapData = new Image();
    [...]]]></description>
			<content:encoded><![CDATA[<p>久しぶりの投稿；</p>
<p><img src="http://rest-term.com/wp-content/uploads/2010/02/snn.jpg" alt="" title="snn" width="550" height="198" class="alignnone size-full wp-image-2708" /></p>
<p>Demo: <a href="http://rest-term.com/contents/other/html5/snn.html" title="HTML5 Image Processing (Symmetric Nearest Neighbor)">HTML5 Image Processing (Symmetric Nearest Neighbor)</a><br />
(Firefox3.5とSafari4で動作確認しています)</p>
<p><a href="http://rest-term.com/archives/2566/" title="HTML5でConvolutionFilter">HTML5でConvolutionFilter</a>に続いて、簡単な画像処理を試してみます。<br />
以前、ActionScriptで書いた<a href="http://rest-term.com/archives/2103/" title="Symmetric Nearest Neighbor « Rest Term">Symmetric Nearest Neighbor</a>をJavaScriptで。<br />
半径を大きくするとそれなりに絵画っぽくなってくれますが、やはり重いです；</p>
<p>・クライアント<br />
[javascript]<br />
var context = document.getElementById(&#8216;Canvas&#8217;).getContext(&#8216;2d&#8217;);<br />
var bmp = new Bitmap(&#8217;sample.jpg&#8217;, context);<br />
var radius = 3;<br />
bmp.applyFilter(new SNNFilter(radius));<br />
[/javascript]</p>
<p><a href="http://rest-term.com/contents/other/html5/js/bitmap.js" title="bitmap.js">bitmap.js</a><br />
(関係ある箇所だけ抜粋)<br />
[javascript]<br />
var Bitmap =  function(source, context) {<br />
  this.initialize.apply(this, arguments);<br />
};</p>
<p>var SNNFilter = function(radius) {<br />
  this.initialize.apply(this, arguments);<br />
};</p>
<p>Bitmap.prototype = {<br />
  initialize : function(source, context) {<br />
    this.bitmapData = new Image();<br />
    this.bitmapData.src = source;<br />
    this.width = this.bitmapData.width;<br />
    this.height = this.bitmapData.height;<br />
    this.context = context;<br />
    this.bitmapData.addEventListener(&#8216;error&#8217;, function() { alert(&quot;can&#8217;t load image&quot;); }, false);<br />
  },<br />
  applyFilter : function(filter) {<br />
    try {<br />
      this.context.drawImage(this.bitmapData, 0, 0);<br />
      var src = this.context.getImageData(0, 0, this.width, this.height);<br />
      var dst = this.context.createImageData(this.width, this.height);<br />
      filter.apply(src, dst);<br />
      this.context.putImageData(dst, 0, 0);<br />
    }catch(e) {<br />
      alert(e);<br />
    }<br />
  }<br />
};</p>
<p>SNNFilter.prototype = {<br />
  initialize : function(radius) {<br />
    this.radius = radius;<br />
  },<br />
  apply : function(src, dst) {<br />
    var w = src.width, h = src.height;<br />
    var srcData = src.data;<br />
    var dstData = dst.data;<br />
    var sunR, sumG, sumB;<br />
    var rc, gc, bc, r1, g1, b1, r2, g2, b2;<br />
    var cnt = 0;<br />
    var xyPos, uvPos;</p>
<p>    for(var y=0;y&lt;h;++y) {<br />
      for(var x=0;x&lt;w;++x) {<br />
        xyPos = (w*y + x) &lt;&lt; 2;<br />
        sumR = 0, sumG = 0, sumB = 0;<br />
        cnt = 0;<br />
        rc = srcData[xyPos];<br />
        gc = srcData[xyPos + 1];<br />
        bc = srcData[xyPos + 2];<br />
        for(var v=-this.radius;v&lt;=this.radius;++v) {<br />
          for(var u=-this.radius;u&lt;=this.radius;++u,++cnt) {<br />
            uvPos = (w*v + u) &lt;&lt; 2;<br />
            try {<br />
              r1 = srcData[xyPos + uvPos];<br />
              g1 = srcData[xyPos + uvPos + 1];<br />
              b1 = srcData[xyPos + uvPos + 2];<br />
              r2 = srcData[xyPos - uvPos];<br />
              g2 = srcData[xyPos - uvPos + 1];<br />
              b2 = srcData[xyPos - uvPos + 2];<br />
            }catch(e) {<br />
              break;<br />
            }<br />
            if(this.delta.apply(this, [rc, gc, bc, r1, g1, b1]) &lt; this.delta.apply(this, [rc, gc, bc, r2, g2, b2])) {<br />
              sumR += r1;<br />
              sumG += g1;<br />
              sumB += b2;<br />
            }else {<br />
              sumR += r2;<br />
              sumG += g2;<br />
              sumB += b2;<br />
            }<br />
          }<br />
        }<br />
        dstData[xyPos] = sumR/cnt;<br />
        dstData[xyPos + 1] = sumG/cnt;<br />
        dstData[xyPos + 2] = sumB/cnt;<br />
        dstData[xyPos + 3] = 255;<br />
      }<br />
    }<br />
  },<br />
  delta : function(rc, gc, bc, r1, g1, b1) {<br />
    return Math.sqrt((rc &#8211; r1)*(rc &#8211; r1) + (gc &#8211; g1)*(gc &#8211; g1) + (bc &#8211; b1)*(bc &#8211; b1));<br />
  }<br />
};<br />
[/javascript]</p>
<p>最近、HTML5とFlashの話題が盛んですね。<br />
これまでは 主に canvas を利用したものしか試してないんですが、<br />
業務で動画配信に携わっているので video に関することも調査中です。<br />
技術の外側でH.264/Theoraを巡る政治的な争いを見守りつつ、<br />
来年度からのスタートに出遅れないように今の内にしっかり勉強しておきたいです。</p>
<p>・関連記事<br />
<a href="http://rest-term.com/archives/2103/" title="Symmetric Nearest Neighbor « Rest Term">Symmetric Nearest Neighbor « Rest Term</a><br />
<a href="http://rest-term.com/archives/2555/" title="HTML5の勉強 « Rest Term">HTML5の勉強 « Rest Term</a></p>
]]></content:encoded>
			<wfw:commentRss>http://rest-term.com/archives/2685/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>メイリオ</title>
		<link>http://rest-term.com/archives/2670/</link>
		<comments>http://rest-term.com/archives/2670/#comments</comments>
		<pubDate>Fri, 08 Jan 2010 11:50:28 +0000</pubDate>
		<dc:creator>wellflat</dc:creator>
				<category><![CDATA[font]]></category>

		<guid isPermaLink="false">http://rest-term.com/?p=2670</guid>
		<description><![CDATA[実はメイリオまだ進化中！ 誕生秘話を河野氏に聞いた － ＠IT
たくさんはてブされてる記事なので読んだ人も多いかもしれませんがこれは熟読すべき！
河野氏は熱い人だなぁ。一文字へのこだわりがすごい。
Wikipediaの項目もなんだか熱い気がする。。(メイリオ &#8211; Wikipedia)
社内プレゼンで使うフォントはメイリオにしよう。
あと、Windows 7には Meiryo UI が入っているので要確認。
・関連記事
 XPでも「メイリオ」が正式利用可能に 
]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.atmarkit.co.jp/news/201001/07/meiryo.html" title="実はメイリオまだ進化中！ 誕生秘話を河野氏に聞いた － ＠IT">実はメイリオまだ進化中！ 誕生秘話を河野氏に聞いた － ＠IT</a></p>
<p>たくさんはてブされてる記事なので読んだ人も多いかもしれませんがこれは熟読すべき！<br />
河野氏は熱い人だなぁ。一文字へのこだわりがすごい。<br />
Wikipediaの項目もなんだか熱い気がする。。(<a href="http://ja.wikipedia.org/wiki/%E3%83%A1%E3%82%A4%E3%83%AA%E3%82%AA" title="メイリオ - Wikipedia">メイリオ &#8211; Wikipedia</a>)</p>
<p>社内プレゼンで使うフォントはメイリオにしよう。<br />
あと、Windows 7には Meiryo UI が入っているので要確認。</p>
<p>・関連記事<br />
<a href="http://rest-term.com/archives/17/" title=" XPでも「メイリオ」が正式利用可能に "> XPでも「メイリオ」が正式利用可能に </a></p>
]]></content:encoded>
			<wfw:commentRss>http://rest-term.com/archives/2670/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>libevent</title>
		<link>http://rest-term.com/archives/2660/</link>
		<comments>http://rest-term.com/archives/2660/#comments</comments>
		<pubDate>Tue, 05 Jan 2010 12:21:33 +0000</pubDate>
		<dc:creator>wellflat</dc:creator>
				<category><![CDATA[tech/study]]></category>
		<category><![CDATA[c/c++]]></category>

		<guid isPermaLink="false">http://rest-term.com/?p=2660</guid>
		<description><![CDATA[libeventを使ったhello, world的な小さなプログラム。
(libeventはmemcachedやThriftなどでも利用されているイベント通知API)
・ファイルが更新されたら内容を表示する
[csharp]
#include 
#include 
#include 
#include 
#include 
#define BUF 256
void callback(int fd, short event, void* arg);
int main(int argc, char** argv) {
	int fd;
	struct event ev;
	if((fd = open(argv[1], O_RDONLY)) == -1) {
		perror(&#8220;open&#8221;);
		return -1;
	}
	event_init();
	event_set(&#038;ev, fd, EV_READ &#124; EV_PERSIST, callback, &#038;ev);
	event_add(&#038;ev, NULL);
	event_dispatch();
	return 0;
}
void callback(int fd, short event, void* arg) {
	char buf[BUF];
	int len;
	//  event_add((struct event*)arg, NULL);
	if((len = read(fd, buf, sizeof(buf) [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.monkey.org/~provos/libevent/">libevent</a>を使ったhello, world的な小さなプログラム。<br />
(libeventはmemcachedやThriftなどでも利用されているイベント通知API)</p>
<p>・ファイルが更新されたら内容を表示する<br />
[csharp]<br />
#include <stdio.h><br />
#include <unistd.h><br />
#include <sys/types.h><br />
#include <fcntl.h><br />
#include <event.h></p>
<p>#define BUF 256</p>
<p>void callback(int fd, short event, void* arg);</p>
<p>int main(int argc, char** argv) {<br />
	int fd;<br />
	struct event ev;<br />
	if((fd = open(argv[1], O_RDONLY)) == -1) {<br />
		perror(&#8220;open&#8221;);<br />
		return -1;<br />
	}<br />
	event_init();<br />
	event_set(&#038;ev, fd, EV_READ | EV_PERSIST, callback, &#038;ev);<br />
	event_add(&#038;ev, NULL);<br />
	event_dispatch();<br />
	return 0;<br />
}</p>
<p>void callback(int fd, short event, void* arg) {<br />
	char buf[BUF];<br />
	int len;<br />
	//  event_add((struct event*)arg, NULL);<br />
	if((len = read(fd, buf, sizeof(buf) &#8211; 1)) == -1) {<br />
		perror(&#8220;read&#8221;);<br />
		return;<br />
	}<br />
	buf[len] = &#8216;\0&#8242;;<br />
	printf(&#8220;%s&#8221;, buf);<br />
}<br />
[/csharp]</p>
<p>event_set 関数で EV_PERSIST を指定すると、イベント通知を継続して受け取ります。<br />
これを指定しない場合は、コールバック関数内で再度 event_add 関数を呼び出す必要があります。<br />
また、登録したイベントを削除したい場合は event_del 関数を利用します。</p>
<p>・参考<br />
<a href="http://www.ninxit.com/blog/2008/02/13/libevent-%E4%BD%BF%E3%81%84%E6%96%B9/" title="libevent + 使い方 | NINXIT-BLOG">libevent + 使い方 | NINXIT-BLOG</a></p>
]]></content:encoded>
			<wfw:commentRss>http://rest-term.com/archives/2660/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>welcome 2010</title>
		<link>http://rest-term.com/archives/2644/</link>
		<comments>http://rest-term.com/archives/2644/#comments</comments>
		<pubDate>Mon, 04 Jan 2010 14:13:53 +0000</pubDate>
		<dc:creator>wellflat</dc:creator>
				<category><![CDATA[tech/study]]></category>

		<guid isPermaLink="false">http://rest-term.com/?p=2644</guid>
		<description><![CDATA[新年あけましておめでとうございます。
今年も思いっきり走り抜けたいと思います！
Webエンジニアとしても学びたいことはたくさん。
今年の目標としては、


KVS(Key-Value Store)について深く学ぶ


モダンPerlなコードを書く


システム運用(トラフィックの監視、負荷分散など)を学ぶ


一つめはKey-Value Store。
僕が一番最初に担当した案件からKVSを利用したメディア配信系のシステムだったりして、
全社的にNoSQLへの流れが強くなっています。
業界全体としても大規模なWebアプリケーションを開発するには必要不可欠な技術なので、
これは最優先で取り組むべき課題としたいです。
二つめはPerl。
弊社のサービスフロントエンドの多くはPHPで構築されるようになりましたが、
新規開発案件でPerlが採用されるケースも多いです(Rubyはまだ残念ながら、、)。
僕は会社に入るまでPerlをまともに触ったことがなかったので、一からの勉強に苦労しました。
Perlのモジュールを速く丁寧に書けるようになりたいと思い二つめの目標に。
三つ目はシステム運用。
インフラ寄りの部署に所属しているので、システム運用の業務も行います。
ある程度人のいる会社では開発と運用の分離をしていて、開発担当が運用業務を行うことはあまりないかもしれません。
ただ、こういった分野は大規模な設備で実務を通して学ばないとあまり身に付かないので、
この部署にいる内に一生懸命勉強しておきたいと思います。
あと、もちろんFlashも。
ASはともかくライブラリ/フレームワークには疎くなってしまったので、
そういった制作寄りの情報も追いかけつつ、Webサイト作りなどもやっていきたいと思います。
2010年もよろしくおねがいします。
]]></description>
			<content:encoded><![CDATA[<p>新年あけましておめでとうございます。<br />
今年も思いっきり走り抜けたいと思います！</p>
<p>Webエンジニアとしても学びたいことはたくさん。<br />
今年の目標としては、</p>
<dl>
<dt>
<dd>KVS(Key-Value Store)について深く学ぶ</dd>
</dt>
<dt>
<dd>モダンPerlなコードを書く</dd>
</dt>
<dt>
<dd>システム運用(トラフィックの監視、負荷分散など)を学ぶ</dd>
</dt>
</dl>
<p>一つめはKey-Value Store。<br />
僕が一番最初に担当した案件からKVSを利用したメディア配信系のシステムだったりして、<br />
全社的に<a href="http://en.wikipedia.org/wiki/Nosql">NoSQL</a>への流れが強くなっています。<br />
業界全体としても大規模なWebアプリケーションを開発するには必要不可欠な技術なので、<br />
これは最優先で取り組むべき課題としたいです。</p>
<p>二つめはPerl。<br />
弊社のサービスフロントエンドの多くはPHPで構築されるようになりましたが、<br />
新規開発案件でPerlが採用されるケースも多いです(Rubyはまだ残念ながら、、)。<br />
僕は会社に入るまでPerlをまともに触ったことがなかったので、一からの勉強に苦労しました。<br />
Perlのモジュールを速く丁寧に書けるようになりたいと思い二つめの目標に。</p>
<p>三つ目はシステム運用。<br />
インフラ寄りの部署に所属しているので、システム運用の業務も行います。<br />
ある程度人のいる会社では開発と運用の分離をしていて、開発担当が運用業務を行うことはあまりないかもしれません。<br />
ただ、こういった分野は大規模な設備で実務を通して学ばないとあまり身に付かないので、<br />
この部署にいる内に一生懸命勉強しておきたいと思います。</p>
<p>あと、もちろんFlashも。<br />
ASはともかくライブラリ/フレームワークには疎くなってしまったので、<br />
そういった制作寄りの情報も追いかけつつ、Webサイト作りなどもやっていきたいと思います。</p>
<p>2010年もよろしくおねがいします。</p>
]]></content:encoded>
			<wfw:commentRss>http://rest-term.com/archives/2644/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>2009年の振り返り</title>
		<link>http://rest-term.com/archives/2627/</link>
		<comments>http://rest-term.com/archives/2627/#comments</comments>
		<pubDate>Wed, 30 Dec 2009 10:16:23 +0000</pubDate>
		<dc:creator>wellflat</dc:creator>
				<category><![CDATA[nonsorted]]></category>

		<guid isPermaLink="false">http://rest-term.com/?p=2627</guid>
		<description><![CDATA[同期のブログもみんな振り返りをやってるので僕も今年1年を簡単に振り返ってみます。
&#8212;&#8212;
大学院修了
無事に大学院を修了する。M1の時は正直まったく研究をしておらず、TAとかパン屋のバイトでお金を稼ぐ日々だったが、M2になってからは姿勢を改めて真面目に研究をしていた。学部生向けに画像処理の基礎をwikiにまとめたり、みんなが好きな環境で研究(開発)できるように環境整備したりと雑務もそれなりに忙しかったが、研究室の良い後輩達に恵まれて充実していたと思う。
就職
Web業界に身を投じる。&#8221;組織&#8221;と&#8221;Webビジネス&#8221;を学んでいる中で、コンテンツの&#8221;価値&#8221;と&#8221;権利&#8221;について深く考えさせられた。&#8221;技術&#8221;で解決できる問題ならどんなに楽だろう、とエンジニアは口を揃えてそう言う。同じような経験(勉強)ができる企業はそう多くはないと思うので、これからもしっかり勉強していきたい。もちろん技術的にも新人の間は勉強することばかりで、社内セミナーや同期に教えてもらった勉強会などに参加していろんな技術を勉強した。インフラ寄りの部署に配属され、そこで学ぶこと全てが新鮮で楽しかった。そう思うと同時に、今までやったきた事がいかに表面的で浅い内容だったのかを思い知らされて少しヘコんだ。
&#8212;&#8212;
今年はインプットがメインだったので、来年は会社で学んだことを活かしてアウトプットに変えていきたいです。
2010年もよろしくおねがいします。
]]></description>
			<content:encoded><![CDATA[<p>同期のブログもみんな振り返りをやってるので僕も今年1年を簡単に振り返ってみます。</p>
<p>&#8212;&#8212;</p>
<h3>大学院修了</h3>
<p>無事に大学院を修了する。M1の時は正直まったく研究をしておらず、TAとかパン屋のバイトでお金を稼ぐ日々だったが、M2になってからは姿勢を改めて真面目に研究をしていた。学部生向けに画像処理の基礎をwikiにまとめたり、みんなが好きな環境で研究(開発)できるように環境整備したりと雑務もそれなりに忙しかったが、研究室の良い後輩達に恵まれて充実していたと思う。</p>
<h3>就職</h3>
<p>Web業界に身を投じる。&#8221;組織&#8221;と&#8221;Webビジネス&#8221;を学んでいる中で、コンテンツの&#8221;価値&#8221;と&#8221;権利&#8221;について深く考えさせられた。&#8221;技術&#8221;で解決できる問題ならどんなに楽だろう、とエンジニアは口を揃えてそう言う。同じような経験(勉強)ができる企業はそう多くはないと思うので、これからもしっかり勉強していきたい。もちろん技術的にも新人の間は勉強することばかりで、社内セミナーや同期に教えてもらった勉強会などに参加していろんな技術を勉強した。インフラ寄りの部署に配属され、そこで学ぶこと全てが新鮮で楽しかった。そう思うと同時に、今までやったきた事がいかに表面的で浅い内容だったのかを思い知らされて少しヘコんだ。</p>
<p>&#8212;&#8212;<br />
今年はインプットがメインだったので、来年は会社で学んだことを活かしてアウトプットに変えていきたいです。<br />
2010年もよろしくおねがいします。</p>
]]></content:encoded>
			<wfw:commentRss>http://rest-term.com/archives/2627/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>HTML5でConvolutionFilter</title>
		<link>http://rest-term.com/archives/2566/</link>
		<comments>http://rest-term.com/archives/2566/#comments</comments>
		<pubDate>Sat, 05 Dec 2009 12:11:00 +0000</pubDate>
		<dc:creator>wellflat</dc:creator>
				<category><![CDATA[tech/study]]></category>
		<category><![CDATA[cv/im]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://rest-term.com/?p=2566</guid>
		<description><![CDATA[HTML5のcanvasを使って簡単な画像処理をやってみます。
試してみたのは基本的な畳み込みフィルタ。
今回はAS3のConvolutionFilter風のインタフェースで作りました。
Demo: HTML5 Image Processing (Convolution Filter)　(Firefox3.5とSafari4で動作確認しています)
汎用的に作ろうとすると少し時間がかかりそうだったので、ひとまず畳み込みフィルタの部分だけ。
引数はAS3のものよりずっと少なく、matrix, divisor, bias の3つ。
matrixXやmatrixYも用意してないのでフィルタカーネルのサイズは3×3限定だし、
異常系の処理も不十分で修正が必要ですが；；
他のフィルタ類は時間を見つけて作ってみようと思います。
・クライアント例
[javascript]
var context = document.getElementById(&#8216;Canvas&#8217;).getContext(&#8216;2d&#8217;);
var bmp = new Bitmap(&#8217;sample.jpg&#8217;, context);
var matrix = [-1, -1, -1,  -1,  8, -1,  -1, -1, -1];　// フィルタカーネル
var divisor = 1;
var bias = 0;
bmp.applyFilter(new ConvolutionFilter(matrix, divisor, bias));
[/javascript]
bitmap.js
[javascript]
  var Bitmap =  function(source, context) {
    this.initialize.apply(this, arguments);
  [...]]]></description>
			<content:encoded><![CDATA[<p>HTML5のcanvasを使って簡単な画像処理をやってみます。<br />
試してみたのは基本的な畳み込みフィルタ。<br />
今回はAS3のConvolutionFilter風のインタフェースで作りました。</p>
<p>Demo: <a href="http://rest-term.com/contents/other/html5/convolution.html" title="HTML5 Image Processing">HTML5 Image Processing (Convolution Filter)</a>　(Firefox3.5とSafari4で動作確認しています)</p>
<p>汎用的に作ろうとすると少し時間がかかりそうだったので、ひとまず畳み込みフィルタの部分だけ。<br />
引数はAS3のものよりずっと少なく、matrix, divisor, bias の3つ。<br />
matrixXやmatrixYも用意してないのでフィルタカーネルのサイズは3×3限定だし、<br />
異常系の処理も不十分で修正が必要ですが；；<br />
他のフィルタ類は時間を見つけて作ってみようと思います。</p>
<p>・クライアント例<br />
[javascript]<br />
var context = document.getElementById(&#8216;Canvas&#8217;).getContext(&#8216;2d&#8217;);<br />
var bmp = new Bitmap(&#8217;sample.jpg&#8217;, context);<br />
var matrix = [-1, -1, -1,  -1,  8, -1,  -1, -1, -1];　// フィルタカーネル<br />
var divisor = 1;<br />
var bias = 0;<br />
bmp.applyFilter(new ConvolutionFilter(matrix, divisor, bias));<br />
[/javascript]</p>
<p><a href="http://rest-term.com/contents/other/html5/js/bitmap.js" title="bitmap.js">bitmap.js</a></p>
<p>[javascript]<br />
  var Bitmap =  function(source, context) {<br />
    this.initialize.apply(this, arguments);<br />
  };</p>
<p>  var ConvolutionFilter = function(matrix, divisor, bias) {<br />
    this.initialize.apply(this, arguments);<br />
  };</p>
<p>  Bitmap.prototype = {<br />
    initialize : function(source, context) {<br />
      this.bitmapData = new Image();<br />
      this.bitmapData.src = source;<br />
      this.width = this.bitmapData.width;<br />
      this.height = this.bitmapData.height;<br />
      this.context = context;<br />
      this.bitmapData.addEventListener(&#8216;error&#8217;, function() { alert(&#8220;can&#8217;t load image&#8221;); }, false);<br />
    },<br />
    applyFilter : function(filter) {<br />
      try {<br />
        this.context.drawImage(this.bitmapData, 0, 0);<br />
        var src = this.context.getImageData(0, 0, this.width, this.height);<br />
        var dst = this.context.createImageData(this.width, this.height);<br />
        //var gray = context.createImageData(this.width, this.height);<br />
        filter.apply(src, dst);<br />
        this.context.putImageData(dst, 0, 0);<br />
      }catch(e) {<br />
        alert(e);<br />
      }<br />
    }<br />
  };</p>
<p>  ConvolutionFilter.prototype = {<br />
    initialize : function(matrix, divisor, bias) {<br />
      this.matrix = matrix;<br />
      this.divisor = divisor;<br />
      this.bias = bias;<br />
    },<br />
    apply : function(src, dst) {<br />
      var w = src.width, h = src.height;<br />
      var srcData = src.data;<br />
      var dstData = dst.data;</p>
<p>      //this.cvtColor.apply(this, [src, dst, 'gray']);</p>
<p>      for(var y=1;y<h-1;++y) {<br />
        for(var x=1;x<w-1;++x) {<br />
          var idx = 0;<br />
          var r = 0, g = 0, b = 0;<br />
          //var d = 0;<br />
          var i = (y*w + x) << 2;<br />
          for(var ky=-1;ky<=1;++ky) {<br />
            for(var kx=-1;kx<=1;++kx) {<br />
              var pos = (ky*w << 2) + (kx << 2);<br />
              r += srcData[i + pos]*this.matrix[idx];<br />
              g += srcData[i + pos + 1]*this.matrix[idx];<br />
              b += srcData[i + pos + 2]*this.matrix[idx];<br />
              //d += srcData[i + pos]*this.matrix[idx++];<br />
              idx++;<br />
            }<br />
          }<br />
          dstData[i] = r/this.divisor + this.bias;<br />
          dstData[i + 1] = g/this.divisor + this.bias;<br />
          dstData[i + 2] = b/this.divisor + this.bias;<br />
          dstData[i + 3] = 255;<br />
        }<br />
      }<br />
      // for Firefox<br />
      dstData.forEach(function(n, i, arr) { arr[i] = n<0 ? 0 : n>255 ? 255 : n; });<br />
    },<br />
    cvtColor : function(src, dst, mode) {<br />
      var w = src.width, h = src.height;<br />
      var srcData = src.data;<br />
      var dstData = dst.data;<br />
      switch(mode) {<br />
      case &#8220;gray&#8221;:<br />
        for(var y=0;y<h;y++) {<br />
          for(var x=0;x<w;x++) {<br />
            var i = (y*w + x) << 2;<br />
            dstData[i] = (77*srcData[i] + 150*srcData[i + 1] + 29*srcData[i + 2]) >> 8;<br />
            dstData[i + 1] = dstData[i];<br />
            dstData[i + 2] = dstData[i];<br />
            dstData[i + 3] = 255;<br />
          }<br />
        }<br />
        break;<br />
      case &#8220;hsv&#8221;:<br />
        // TODO<br />
        break;<br />
      case &#8220;lab&#8221;:<br />
        // TODO<br />
        break;<br />
      default:<br />
        break;<br />
      }<br />
    }<br />
  };<br />
[/javascript]</p>
<p>ポイントを絞って簡単に説明を。<br />
(以下 context は getContext(&#8216;2d&#8217;) で取得したオブジェクト)</p>
<p>* <strong>imagedata = context.createImageData(sw, sh)</strong><br />
幅sw, 高さshの<a href="http://www.w3.org/TR/html5/the-canvas-element.html#imagedata">ImageData</a>オブジェクトを生成します。<br />
ピクセルデータ(imageData.data)はすべて0(黒)になっています。</p>
<p>* <strong>imageData = context.getImageData(sx, sy, sw, sh)</strong><br />
(x, y)=(sx, sy) を基準に幅sw, 高さshの領域のピクセルデータを取得できます(imageData.data)。<br />
これはAS3における BitmapData.getPixels() のようなもので、ARGB32bitのデータを扱い、<br />
インデックスは 0～幅×高さ×4-1 まで。</p>
<p>* <strong>context.putImageData(imagedata, dx, dy)</strong><br />
指定されたImageDataオブジェクトを (x, y)=(dx, dy) を基準に描画します。</p>
<p>・参考記事<br />
<a href="http://www.html5.jp/canvas/ref/method/getImageData.html" title="createImageData, getImageData, putImageData メソッド - Canvasリファレンス - HTML5.JP">createImageData, getImageData, putImageData メソッド &#8211; Canvasリファレンス &#8211; HTML5.JP</a><br />
・関連記事<br />
<a href="http://rest-term.com/archives/2555/" title="HTML5の勉強">HTML5の勉強</a></p>
]]></content:encoded>
			<wfw:commentRss>http://rest-term.com/archives/2566/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>FITC Tokyo 2009 参加レポート</title>
		<link>http://rest-term.com/archives/2568/</link>
		<comments>http://rest-term.com/archives/2568/#comments</comments>
		<pubDate>Sun, 29 Nov 2009 11:04:37 +0000</pubDate>
		<dc:creator>wellflat</dc:creator>
				<category><![CDATA[diary]]></category>
		<category><![CDATA[tech/study]]></category>
		<category><![CDATA[flash]]></category>

		<guid isPermaLink="false">http://rest-term.com/?p=2568</guid>
		<description><![CDATA[FITC Tokyo 2009 に参加してきました。

どのセッションも聞き応えがあり良い刺激になりました。
個人的にはNVIDIAさんの話を興味深く聞かせていただきました。
ランチをゆっくり食べ過ぎたせいで途中からしか聞けませんでしたが、内容としては

Tegra用に最適化されたFlash Playerでは、H.264ビデオの再生などを行うときにTegraのアクセラレーション機能を利用でき、しかも省電力！
OpenGL ES関連 (企業ブースではARのシューティングゲームを展示してた)

OpenCL(とCUDA)関連のことで聞きたいこともあったのですが、ブースはすごい人だかりだったので断念。。
ノベルティとしてもらった携帯液晶クリーナーの厚紙に載っているTegraモジュールの写真も必見です。
ただ、セッションの時間がたった30分しかなくて残念でした。
それにあのデモはもっと大きなどよめきが起こってもいいレベルだと思ったんですが；；
他に興味を持ったのは、Lee BrimelowさんのAIR2.0に関することについて。
ネイティブプロセスの制御や、ネットワーク関連API(DNS周り等)の強化には可能性を感じました。
僕はAIRをほとんど触ったことがないのですが、これを機に時間を作って勉強しようと思います。
セッション終了後のパーティーは、場所を汐留シティセンタービル42Fに移して行われ、
大変景色の良い場所で楽しく過ごすことができました。
他の方々と交流を取らないとご飯が食べられない仕様になっていたので、
Web業界はきびしいなーと友人と一緒に半泣き半笑いで途方にくれているところを
いろんな方々が声をかけてくださったおかげでたくさん食べることができました。
しかもその後のクイズにも正解して分厚いステーキもいただきました。Happy!
もちろん豪華なスピーカーの方々もパーティーに参加されていました。
そこでは(セッションでASの最適化話をされていた)Grant Skinnerさんに
プログラミングを楽しむコツを聞いてみたんですが、
「Workとしてじゃなく、Artとしてプログラミングするといいよ !」
と言われ気付かされました。
技術は芸術。精進します。
パーティーでの反省点としては、名刺とデジカメを持っていかなかったこと。
名刺はもらいっぱなしでほんと申し訳なかったです。学生？とか聞かれたし。。
42Fからの夜景やみなさんの楽しむ姿を写真にも収めたかった。
でも多くの方と交流を持てて大きな活力になりました。
またこのようなイベントがあったときは是非参加したいと思っています。
]]></description>
			<content:encoded><![CDATA[<p>FITC Tokyo 2009 に参加してきました。<br />
<a href="http://rest-term.com/wp-content/uploads/2009/11/DSC00871.jpg"><img src="http://rest-term.com/wp-content/uploads/2009/11/DSC00871-300x225.jpg" alt="DSC00871" title="DSC00871" width="300" height="225" class="alignnone size-medium wp-image-2569" /></a></p>
<p>どのセッションも聞き応えがあり良い刺激になりました。</p>
<p>個人的にはNVIDIAさんの話を興味深く聞かせていただきました。<br />
ランチをゆっくり食べ過ぎたせいで途中からしか聞けませんでしたが、内容としては</p>
<ul style="list-style-type: disc; border:1px solid #ccc; width:550px;">
<li>Tegra用に最適化されたFlash Playerでは、H.264ビデオの再生などを行うときにTegraのアクセラレーション機能を利用でき、しかも省電力！</li>
<li>OpenGL ES関連 (企業ブースではARのシューティングゲームを展示してた)</li>
</ul>
<p>OpenCL(とCUDA)関連のことで聞きたいこともあったのですが、ブースはすごい人だかりだったので断念。。<br />
ノベルティとしてもらった携帯液晶クリーナーの厚紙に載っているTegraモジュールの写真も必見です。<br />
ただ、セッションの時間がたった30分しかなくて残念でした。<br />
それにあのデモはもっと大きなどよめきが起こってもいいレベルだと思ったんですが；；</p>
<p>他に興味を持ったのは、Lee BrimelowさんのAIR2.0に関することについて。<br />
ネイティブプロセスの制御や、ネットワーク関連API(DNS周り等)の強化には可能性を感じました。<br />
僕はAIRをほとんど触ったことがないのですが、これを機に時間を作って勉強しようと思います。</p>
<p>セッション終了後のパーティーは、場所を汐留シティセンタービル42Fに移して行われ、<br />
大変景色の良い場所で楽しく過ごすことができました。</p>
<p>他の方々と交流を取らないとご飯が食べられない仕様になっていたので、<br />
Web業界はきびしいなーと友人と一緒に半泣き半笑いで途方にくれているところを<br />
いろんな方々が声をかけてくださったおかげでたくさん食べることができました。<br />
しかもその後のクイズにも正解して分厚いステーキもいただきました。Happy!</p>
<p>もちろん豪華なスピーカーの方々もパーティーに参加されていました。<br />
そこでは(セッションでASの最適化話をされていた)Grant Skinnerさんに<br />
プログラミングを楽しむコツを聞いてみたんですが、<br />
「Workとしてじゃなく、Artとしてプログラミングするといいよ !」<br />
と言われ気付かされました。<br />
技術は芸術。精進します。</p>
<p>パーティーでの反省点としては、名刺とデジカメを持っていかなかったこと。<br />
名刺はもらいっぱなしでほんと申し訳なかったです。学生？とか聞かれたし。。<br />
42Fからの夜景やみなさんの楽しむ姿を写真にも収めたかった。<br />
でも多くの方と交流を持てて大きな活力になりました。<br />
またこのようなイベントがあったときは是非参加したいと思っています。</p>
]]></content:encoded>
			<wfw:commentRss>http://rest-term.com/archives/2568/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>HTML5の勉強</title>
		<link>http://rest-term.com/archives/2555/</link>
		<comments>http://rest-term.com/archives/2555/#comments</comments>
		<pubDate>Sun, 15 Nov 2009 12:53:14 +0000</pubDate>
		<dc:creator>wellflat</dc:creator>
				<category><![CDATA[tech/study]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://rest-term.com/?p=2555</guid>
		<description><![CDATA[
HTML5::canvas test (Firefox3.5, Safari4でのみ動作確認しています)
先日の社内コンペでHTML5を使ったすごいデモを出してきたチームがあったので、
僕もそれに刺激を受けていろいろ調べています。
以前Flashで作ったものをHTML5のcanvas要素を使って作り直したりしながら勉強。
簡単な画像処理なんかもできそうなので引き続き調べていきたいと思います。
]]></description>
			<content:encoded><![CDATA[<p><a href="http://rest-term.com/contents/other/html5/canvas.html"><img src="http://rest-term.com/wp-content/uploads/2009/11/html5_canvas.png" alt="html5_canvas" title="html5_canvas" width="370" height="239" class="alignnone size-full wp-image-2556" /><br />
HTML5::canvas test</a> (Firefox3.5, Safari4でのみ動作確認しています)</p>
<p>先日の社内コンペでHTML5を使ったすごいデモを出してきたチームがあったので、<br />
僕もそれに刺激を受けていろいろ調べています。<br />
以前Flashで作ったものをHTML5のcanvas要素を使って作り直したりしながら勉強。<br />
簡単な画像処理なんかもできそうなので引き続き調べていきたいと思います。</p>
]]></content:encoded>
			<wfw:commentRss>http://rest-term.com/archives/2555/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>10月おわり</title>
		<link>http://rest-term.com/archives/2536/</link>
		<comments>http://rest-term.com/archives/2536/#comments</comments>
		<pubDate>Sat, 31 Oct 2009 08:21:01 +0000</pubDate>
		<dc:creator>wellflat</dc:creator>
				<category><![CDATA[design/art]]></category>
		<category><![CDATA[diary]]></category>

		<guid isPermaLink="false">http://rest-term.com/?p=2536</guid>
		<description><![CDATA[最近は天気のいい日が多いので、お昼休憩は外に出ています。
同期や先輩達と食べるのはいいんですが、週1,2くらいはひとりまったりと過ごす時間を作ろうかと。

会社近くの檜町公園やミッドタウンガーデンっていう所でサンドイッチとか食べてますｖ


今はミッドタウンでDESIGN TOUCHっていうイベントの期間中で、今日は熱気球が上がってました。
けっこう近くで見たんですが、ゴーっていう炎の音がすごいんですね。

あと、ガレリアB1Fではデザイン展が開かれていて、初期のApple Mouseとか展示してあって面白かったです。
11月からは忙しくなるので、今の内に元気を溜めておこう。
]]></description>
			<content:encoded><![CDATA[<p>最近は天気のいい日が多いので、お昼休憩は外に出ています。<br />
同期や先輩達と食べるのはいいんですが、週1,2くらいはひとりまったりと過ごす時間を作ろうかと。</p>
<p><span id="more-2536"></span><br />
会社近くの檜町公園やミッドタウンガーデンっていう所でサンドイッチとか食べてますｖ</p>
<p><img src="http://rest-term.com/wp-content/uploads/2009/10/DSC00847.JPG" alt="DSC00847" title="DSC00847" width="320" height="240" class="alignnone size-full wp-image-2537" /><img src="http://rest-term.com/wp-content/uploads/2009/10/DSC00845.JPG" alt="DSC00845" title="DSC00845" width="320" height="240" class="alignnone size-full wp-image-2547" /><br />
<img src="http://rest-term.com/wp-content/uploads/2009/10/DSC00844.JPG" alt="DSC00844" title="DSC00844" width="320" height="240" class="alignnone size-full wp-image-2541" /><img src="http://rest-term.com/wp-content/uploads/2009/10/DSC00868.JPG" alt="DSC00868" title="DSC00868" width="320" height="240" class="alignnone size-full wp-image-2542" /></p>
<p>今はミッドタウンで<a href="http://www.tokyo-midtown.com/jp/designtouch/2009/index.html" title="東京ミッドタウン／DESIGN TOUCH 2009">DESIGN TOUCH</a>っていうイベントの期間中で、今日は熱気球が上がってました。<br />
けっこう近くで見たんですが、ゴーっていう炎の音がすごいんですね。</p>
<p><img src="http://rest-term.com/wp-content/uploads/2009/10/DSC00848.JPG" alt="DSC00848" title="DSC00848" width="320" height="240" class="alignnone size-full wp-image-2544" /><img src="http://rest-term.com/wp-content/uploads/2009/10/DSC00849.JPG" alt="DSC00849" title="DSC00849" width="320" height="240" class="alignnone size-full wp-image-2545" /></p>
<p>あと、ガレリアB1Fではデザイン展が開かれていて、初期のApple Mouseとか展示してあって面白かったです。</p>
<p>11月からは忙しくなるので、今の内に元気を溜めておこう。</p>
]]></content:encoded>
			<wfw:commentRss>http://rest-term.com/archives/2536/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>OpenCV 2.0 &#8211; cv::Mat 行列演算</title>
		<link>http://rest-term.com/archives/2484/</link>
		<comments>http://rest-term.com/archives/2484/#comments</comments>
		<pubDate>Sun, 25 Oct 2009 07:21:37 +0000</pubDate>
		<dc:creator>wellflat</dc:creator>
				<category><![CDATA[tech/study]]></category>
		<category><![CDATA[c/c++]]></category>
		<category><![CDATA[cv/im]]></category>

		<guid isPermaLink="false">http://rest-term.com/?p=2484</guid>
		<description><![CDATA[前回に引き続き、cv::Matクラスについて。
今回は行列演算に関する機能を使います。

上記のシンプルな連立一次方程式を cv::Mat クラスの機能を使って解いてみます。
[csharp]
// 係数行列 A
float dataA[][3] = { {1.0, -2.0, 3.0}, {3.0, 1.0, -5.0}, {-2.0, 6.0, -9.0} };
// 行列 B
float dataB[] = {1.0, -4.0, -2.0};
Mat matA(3, 3, CV_32FC1, dataA);
Mat matB(3, 1, CV_32FC1, dataB);
Mat matX(3, 1, CV_32FC1);
// AX = B を解く. 両辺にAの逆行列を前掛けする
matX = matA.inv()*matB;
MatConstIterator_ iter = matX.begin();
while(iter != matX.end()) printf(&#8220;%.1f\n&#8221;, *iter++);
[/csharp]
• 出力結果

1.0　// x
3.0　// y
2.0　// z

CvMatでは cvmInvert [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://rest-term.com/archives/2445/">前回</a>に引き続き、<strong>cv::Mat</strong>クラスについて。<br />
今回は行列演算に関する機能を使います。</p>
<p><img src="http://rest-term.com/wp-content/uploads/2009/10/houteisiki.png" alt="houteisiki" title="houteisiki" width="170" height="82" class="alignnone size-full wp-image-2512" /></p>
<p>上記のシンプルな連立一次方程式を cv::Mat クラスの機能を使って解いてみます。</p>
<p>[csharp]<br />
// 係数行列 A<br />
float dataA[][3] = { {1.0, -2.0, 3.0}, {3.0, 1.0, -5.0}, {-2.0, 6.0, -9.0} };<br />
// 行列 B<br />
float dataB[] = {1.0, -4.0, -2.0};<br />
Mat matA(3, 3, CV_32FC1, dataA);<br />
Mat matB(3, 1, CV_32FC1, dataB);<br />
Mat matX(3, 1, CV_32FC1);</p>
<p>// AX = B を解く. 両辺にAの逆行列を前掛けする<br />
matX = matA.inv()*matB;</p>
<p>MatConstIterator_<float> iter = matX.begin<float>();<br />
while(iter != matX.end<float>()) printf(&#8220;%.1f\n&#8221;, *iter++);<br />
[/csharp]<br />
• 出力結果</p>
<pre>
1.0　// x
3.0　// y
2.0　// z
</pre>
<p>CvMatでは cvmInvert -> cvmMul と関数を順番に呼び出さないといけないところを、<br />
cv::Matなら matX = matA.inv()*matB のように直感的に行列演算を行うことができます。<br />
また、今回のような線形な問題であれば solve(matA, matB, matX) で解くこともできます。</p>
<h3>基本的な行列演算</h3>
<table>
<tr>
<th> </th>
<th>CvMat</th>
<th>cv::Mat</th>
</tr>
<tr>
<td>X = A + B</td>
<td>cvmAdd(A, B, X)</td>
<td>X = A + B</td>
</tr>
<tr>
<td>X = A &#8211; B</td>
<td>cvmSub(A, B, X)</td>
<td>X = A &#8211; B</td>
</tr>
<tr>
<td>X = AB</td>
<td>cvmMul(A, B, X)</td>
<td>X = A * B</td>
</tr>
<tr>
<td>X = A<span style="vertical-align:super; font-size:80%;">-1</span> (逆行列)</td>
<td>cvmInvert(A, X)</td>
<td>X = A.inv()</td>
</tr>
<tr>
<td>X = A<span style="vertical-align:super; font-size:80%;">T</span> (転置行列)</td>
<td>cvmTranspose(A, X)</td>
<td>X = A.t()</td>
</tr>
<tr>
<td>X = A・B (内積)</td>
<td>cvmDotProduct(A, B)</td>
<td>X = A.dot(B)</td>
</tr>
<tr>
<td>X = A × B (外積)</td>
<td>cvmCrossProduct(A, B, X)</td>
<td>X = A.cross(B)</td>
</tr>
<tr>
<td>&#x7c;A&#x7c; (行列式)</td>
<td>cvmDet(A)</td>
<td>determinant(A)</td>
</tr>
</table>
<p>以下のような細かい操作もできます。<br />
[csharp]<br />
matA*5.0;　// 行列の各要素に5を掛ける (スケーリング)</p>
<p>matA.row(0) = matA.row(2)*2.0;　// 3行目をスケーリングして1行目に (添字に注意)<br />
[/csharp]</p>
<p>また、Matlabスタイルの行列初期化関数も用意されています。<br />
[csharp]<br />
Mat zero = Mat::zeros(3, 3, CV_32FC1);　// 零行列を生成<br />
Mat eye = Mat::eye(3, 3, CV_32FC1);　// 単位行列を生成<br />
Mat one = Mat::ones(3, 3, CV_32FC1);　// 全要素が 1 の行列を生成<br />
[/csharp]</p>
<p>これ以外にもまだまだたくさんの機能があります。<br />
今まで面倒だった行列演算がかなり楽になるのでうれしいですね。</p>
<p>関連記事：<br />
<a href="http://rest-term.com/archives/2445/" title="OpenCV 2.0 – cv::Mat">OpenCV 2.0 – cv::Mat</a><br />
<a href="http://rest-term.com/archives/2418/" title="OpenCV 2.0 – cv::Ptr">OpenCV 2.0 – cv::Ptr</a><br />
<a href="http://rest-term.com/archives/2402/" title="OpenCV 2.0を試してみた">OpenCV 2.0を試してみた</a></p>
]]></content:encoded>
			<wfw:commentRss>http://rest-term.com/archives/2484/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>OpenCV 2.0 – cv::Mat</title>
		<link>http://rest-term.com/archives/2445/</link>
		<comments>http://rest-term.com/archives/2445/#comments</comments>
		<pubDate>Sun, 18 Oct 2009 05:46:03 +0000</pubDate>
		<dc:creator>wellflat</dc:creator>
				<category><![CDATA[tech/study]]></category>
		<category><![CDATA[c/c++]]></category>
		<category><![CDATA[cv/im]]></category>

		<guid isPermaLink="false">http://rest-term.com/?p=2445</guid>
		<description><![CDATA[OpenCV C++ matrix class
前回、OpenCV 2.0 – cv::Ptr ではスマートポインタである cv::Ptr について調べました。
今回はOpenCV 2.0のC++インタフェースの中でも重要な役割を持つ cv::Mat クラスについて。
このクラスは従来の IplImage 及び CvMat に取って代わるものになっていますが、
かなり大きいクラスなので何回かに分けて調べていきたいと思います。
cv::Mat はマルチチャンネルとROI(Region Of Interest)をサポートしている二次元行列です。
オブジェクトの生成方法は複数ありますが、ここでは基本的な方法から紹介します。
[csharp]
using namespace cv;
using namespace std;
// create() メソッド　(5行5列，各要素が8ビット符号なし整数型 3チャンネル)
// タイプ指定：CV_{U&#124;S&#124;F}C
Mat matA;
matA.create(5, 5, CV_8UC3);
// コンストラクタ　(3行3列，各要素が32ビット浮動小数点型 1チャンネル)
Mat matB(3, 3, CV_32FC1);
// コンストラクタの引数に cv::Size を指定
Mat matC(Size(640, 480), CV_8UC3);
// 二次元配列を使って初期化
double data[][3] = { {1,2,3}, {4,5,6}, {7,8,9} };
Mat matD(Size(3, 3), CV_64FC1, data);
// std::vector [...]]]></description>
			<content:encoded><![CDATA[<blockquote><p>OpenCV C++ matrix class</p></blockquote>
<p>前回、<a href="http://rest-term.com/archives/2418/" title="OpenCV 2.0 – cv::Ptr">OpenCV 2.0 – cv::Ptr</a> ではスマートポインタである cv::Ptr について調べました。<br />
今回はOpenCV 2.0のC++インタフェースの中でも重要な役割を持つ <strong>cv::Mat</strong> クラスについて。<br />
このクラスは従来の <strong>IplImage</strong> 及び <strong>CvMat</strong> に取って代わるものになっていますが、<br />
かなり大きいクラスなので何回かに分けて調べていきたいと思います。</p>
<p>cv::Mat はマルチチャンネルとROI(Region Of Interest)をサポートしている二次元行列です。<br />
オブジェクトの生成方法は複数ありますが、ここでは基本的な方法から紹介します。</p>
<p>[csharp]<br />
using namespace cv;<br />
using namespace std;</p>
<p>// create() メソッド　(5行5列，各要素が8ビット符号なし整数型 3チャンネル)<br />
// タイプ指定：CV_<bit-depth>{U|S|F}C<number_of_channels><br />
Mat matA;<br />
matA.create(5, 5, CV_8UC3);</p>
<p>// コンストラクタ　(3行3列，各要素が32ビット浮動小数点型 1チャンネル)<br />
Mat matB(3, 3, CV_32FC1);</p>
<p>// コンストラクタの引数に cv::Size を指定<br />
Mat matC(Size(640, 480), CV_8UC3);</p>
<p>// 二次元配列を使って初期化<br />
double data[][3] = { {1,2,3}, {4,5,6}, {7,8,9} };<br />
Mat matD(Size(3, 3), CV_64FC1, data);</p>
<p>// std::vector を使って初期化<br />
// デフォルトでは浅いコピー、第二引数にtrueを指定すると深いコピーになる<br />
// この場合、10行1列の行列が生成され、要素は全て0で初期化される<br />
vector<double> v(10);<br />
Mat matE(v);　// or Mat matE(v, true);</p>
<p>// cv::Scalar を使って初期化<br />
Mat matF(5, 5, CV_32FC2, Scalar(1.0, 3.0));</p>
<p>// コピーコンストラクタ (浅いコピー, refcount++)<br />
Mat copy(matA);</p>
<p>// clone() メソッド　(深いコピー)<br />
Mat clone = matA.clone();</p>
<p>// ROIを設定 (cv::Rect で位置と大きさを指定)<br />
Mat roi(matC, Rect(10, 10, 100, 100));</p>
<p>// IplImage から cv::Mat に変換<br />
IplImage* src_img = cvLoadImage(&#8220;lena.jpg&#8221;, CV_LOAD_IMAGE_COLOR);<br />
Mat img(src_img);</p>
<p>// CvMat から cv::Mat に変換<br />
CvMat* cv_mat = cvCreateMat(3, 3, CV_32FC1);<br />
Mat mat(cv_mat);</p>
<p>[/csharp]</p>
<p>次はMatクラスの構造について。<br />
gdbで上のコードのmatAを見てみると、</p>
<pre>
(gdb) p matA
$1 = {
  flags = 1124024336,
  rows = 5,
  cols = 5,
  step = 15,
  data = 0xb07ff0 "",
  refcount = 0xb0803c,
  datastart = 0xb07ff0 "",
  dataend = 0xb0803b ""
}
</pre>
<table>
<tr>
<td>flags</td>
<td>//</td>
</tr>
<tr>
<td>rows</td>
<td>行数</td>
</tr>
<tr>
<td>cols</td>
<td>列数</td>
</tr>
<tr>
<td>step</td>
<td>一行のバイト数</td>
</tr>
<tr>
<td>data</td>
<td>データへのポインタ</td>
</tr>
<tr>
<td>refcount</td>
<td>参照カウントへのポインタ</td>
</tr>
<tr>
<td>datastart</td>
<td>データの始まりへのポインタ</td>
</tr>
<tr>
<td>dataend</td>
<td>データの終わりへのポインタ</td>
</tr>
</table>
<p>メンバは基本的にCvMatと同様のものを備えています。<br />
flagsはMatクラスの各メソッドで内部的に利用されているものなので特に気にしなくて構いません。<br />
また、サイズはIplImageと比べるとかなり小さく、sizeofしてみるとIplImageは112、Matは32となっています。</p>
<p>各要素のアドレスは以下のように計算します。<br />
[csharp]<br />
// M(i, j) の要素のアドレス</p>
<p>// elemSize() は1要素のバイト数を返す<br />
M.data + M.step*i + j*M.elemSize()</p>
<p>// 要素の型が既知の場合は at(int y, int x) が利用可能<br />
// 内部では、指定された型のポインタでキャストされた (data + step*y)[x] がreturnされている<br />
&#038;M.at<double>(i, j)</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
// 各行の先頭アドレスは ptr(int y) で取得可能　(内部では、return data + step*y)<br />
// 型指定しない場合は uchar* が返される<br />
M.ptr<double>(y)<br />
M.ptr(y)<br />
[/csharp]</p>
<p>とりあえず今回はcv::Matクラスの構造を主に紹介しました。<br />
次からは実際にこのクラスを利用していろいろな処理を行いたいと思います。</p>
<p>:: 追記<br />
＊ IplImage, CvMat と cv::Mat の互換性について<br />
とりあえず、ドキュメントに載っていたコードを使って確認を行いました。</p>
<p>[csharp]<br />
/* IplImage -> cv::Mat -> CvMat の順で変換 */</p>
<p>IplImage* img = cvLoadImage(&#8220;lena.jpg&#8221;, CV_LOAD_IMAGE_COLOR);<br />
Mat mtx(img);<br />
CvMat oldmat = mtx;</p>
<p>// OpenCV Error: Assertion failed~ は発生しないことを確認<br />
CV_Assert(oldmat.cols == img->width &#038;&#038; oldmat.rows == img->height<br />
  &#038;&#038; oldmat.data.ptr == (uchar*)img->imageData &#038;&#038; oldmat.step == img->widthStep);<br />
[/csharp]</p>
<p>関連記事：<br />
<a href="http://rest-term.com/archives/2418/" title="OpenCV 2.0 – cv::Ptr">OpenCV 2.0 – cv::Ptr</a><br />
<a href="http://rest-term.com/archives/2402/" title="OpenCV 2.0を試してみた">OpenCV 2.0を試してみた</a></p>
]]></content:encoded>
			<wfw:commentRss>http://rest-term.com/archives/2445/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>OpenCV 2.0 &#8211; cv::Ptr</title>
		<link>http://rest-term.com/archives/2418/</link>
		<comments>http://rest-term.com/archives/2418/#comments</comments>
		<pubDate>Tue, 13 Oct 2009 15:39:16 +0000</pubDate>
		<dc:creator>wellflat</dc:creator>
				<category><![CDATA[tech/study]]></category>
		<category><![CDATA[c/c++]]></category>
		<category><![CDATA[cv/im]]></category>

		<guid isPermaLink="false">http://rest-term.com/?p=2418</guid>
		<description><![CDATA[A template class for smart reference-counting pointers
OpenCV 2.0では cv::Ptr という参照カウント方式のスマートポインタが用意されています。
これは Boost C++ Library の shared_ptr と同様のもので大変便利です。
参考：参照カウント &#8211; Wikipedia
一時的にcv::Ptrクラスのrefcountというメンバをprotectedからpublicに変更して挙動を見てみます。
(cxcore.hppの660行目付近にあります)
[csharp]
class Test {
public:
  Test() { std::cout]]></description>
			<content:encoded><![CDATA[<blockquote><p>A template class for smart reference-counting pointers</p></blockquote>
<p>OpenCV 2.0では <strong>cv::Ptr</strong> という参照カウント方式のスマートポインタが用意されています。<br />
これは Boost C++ Library の shared_ptr と同様のもので大変便利です。<br />
参考：<a href="http://ja.wikipedia.org/wiki/%E5%8F%82%E7%85%A7%E3%82%AB%E3%82%A6%E3%83%B3%E3%83%88" title="参照カウント - Wikipedia">参照カウント &#8211; Wikipedia</a></p>
<p>一時的にcv::Ptrクラスのrefcountというメンバをprotectedからpublicに変更して挙動を見てみます。<br />
(cxcore.hppの660行目付近にあります)</p>
<p>[csharp]<br />
class Test {<br />
public:<br />
  Test() { std::cout<<"construct"<<std::endl; }<br />
  ~Test() { std::cout<<"destruct"<<std::endl; }<br />
};</p>
<p>int main(void) {<br />
  using namespace std;<br />
  cv::Ptr<Test> p1(new Test());  // 参照カウント 1<br />
  cout<<"refcount: "<<*(p1.refcount)<<endl;<br />
  {<br />
    cv::Ptr<Test> p2;<br />
    p2 = p1;  // 参照カウントが+1されて2になる<br />
    cout<<"refcount: "<<*(p1.refcount)<<endl;<br />
  }  // 参照カウントが-1されて1になる、まだオブジェクトは解放されない<br />
  cout<<"refcount: "<<*(p1.refcount)<<endl;<br />
  cout<<"main exit"<<endl;<br />
  return 0;<br />
}  // Testオブジェクトが解放される</p>
<p>--------------<br />
/** 結果<br />
 construct<br />
 refcount: 1<br />
 refcount: 2<br />
 refcount: 1<br />
 main exit<br />
 destruct<br />
**/<br />
[/csharp]</p>
<p>すばらしい。<br />
また、IplImage に適用した場合はきちんとテンプレートの特殊化が施されているので安心です。</p>
<p>[csharp]<br />
int main(void) {<br />
  cv::Ptr<IplImage> img = cvLoadImage(&#8220;test.jpg&#8221;);</p>
<p>  if(img.empty()) {<br />
    std::cerr<<"can't load image."<<std::endl;<br />
    return -1;<br />
  }</p>
<p>  namedWindow("image", CV_WINDOW_AUTOSIZE);<br />
  imshow("image", Mat(img));<br />
  waitKey();</p>
<p>  return 0;<br />
}</p>
<p>--------------------------------------------------------------------<br />
/* 参照カウント(refcount)が0になると Ptr::delete_obj() が呼ばれる<br />
 CvMatやIplImageは以下のように特殊化されている */<br />
template<> inline void Ptr<CvMat>::delete_obj()<br />
{ cvReleaseMat(&#038;obj); }   </p>
<p>template<> inline void Ptr<IplImage>::delete_obj()<br />
{ cvReleaseImage(&#038;obj); }<br />
[/csharp]</p>
<p>OpenCV 1.0ではメモリのアロケートに cvAlloc() という malloc() のラッパーが使われていましたが、<br />
OpenCV 2.0ではその代わりに fastMalloc() という関数が用意され、cv::Ptr内でもコールされています。<br />
少し中を覗いてみると、どうやらシステムコールの mmap() でアロケートしているようです。<br />
(Windowsでは普通のmalloc()が呼ばれる模様)<br />
詳しくはまだ読めていませんが、fastというくらいだからきっと速くなっているんでしょう。</p>
<p>メモリ管理を cv::Ptr に任せておくと開発が楽になるのは間違いなさそうです。</p>
<p>関連記事：<br />
<a href="http://rest-term.com/archives/2402/" title="OpenCV 2.0を試してみた">OpenCV 2.0を試してみた</a></p>
]]></content:encoded>
			<wfw:commentRss>http://rest-term.com/archives/2418/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>OpenCV 2.0を試してみた</title>
		<link>http://rest-term.com/archives/2402/</link>
		<comments>http://rest-term.com/archives/2402/#comments</comments>
		<pubDate>Mon, 12 Oct 2009 12:20:21 +0000</pubDate>
		<dc:creator>wellflat</dc:creator>
				<category><![CDATA[tech/study]]></category>
		<category><![CDATA[c/c++]]></category>
		<category><![CDATA[cv/im]]></category>

		<guid isPermaLink="false">http://rest-term.com/?p=2402</guid>
		<description><![CDATA[この連休中にちょっとOpenCV 2.0で遊んでいました。
ライブラリの規模がかなり大きくなったのでソースを読むのも大変です；
IplImage や CvMat は 新しいC++インタフェースでは cv::Mat に取って代わります。
(1.1preで追加されたWImageクラスの立場は?  関連：cv::WImage – OpenCV 1.1)
また、メモリ管理が賢くなっているので、後始末は各クラスのデストラクタに任せておきましょう。
boostのshared_ptrと同様のスマートポインタ(cv::Ptr)も用意されていて、いろいろ便利になっているようです。
C++インタフェースを中心にこれから少しずつ調べていこうと思います。

[csharp]
// カメラから画像をキャプチャ
#include 
#include 
int main(int argc, char **argv) {
  using namespace cv;
  VideoCapture cap(0);  // VideoCapture(int device)
  if(!cap.isOpened()) return -1;
  Mat edges;
  char code;
  namedWindow(&#8220;OpenCV 2.0 Capture Test&#8221;, CV_WINDOW_AUTOSIZE);
  for(;;) {
    Mat [...]]]></description>
			<content:encoded><![CDATA[<p>この連休中にちょっとOpenCV 2.0で遊んでいました。<br />
ライブラリの規模がかなり大きくなったのでソースを読むのも大変です；</p>
<p>IplImage や CvMat は 新しいC++インタフェースでは cv::Mat に取って代わります。<br />
(1.1preで追加されたWImageクラスの立場は?  関連：<a href="http://rest-term.com/archives/1156/" title="cv::WImage – OpenCV 1.1">cv::WImage – OpenCV 1.1</a>)<br />
また、メモリ管理が賢くなっているので、後始末は各クラスのデストラクタに任せておきましょう。<br />
boostのshared_ptrと同様のスマートポインタ(cv::Ptr)も用意されていて、いろいろ便利になっているようです。</p>
<p>C++インタフェースを中心にこれから少しずつ調べていこうと思います。</p>
<p><a href="http://rest-term.com/wp-content/uploads/2009/10/opencv2.0_test.png"><img src="http://rest-term.com/wp-content/uploads/2009/10/opencv2.0_test-300x187.png" alt="opencv2.0_test" title="opencv2.0_test" width="300" height="187" class="alignnone size-medium wp-image-2407" /></a></p>
<p>[csharp]<br />
// カメラから画像をキャプチャ</p>
<p>#include <cv.h><br />
#include <highgui.h></p>
<p>int main(int argc, char **argv) {<br />
  using namespace cv;<br />
  VideoCapture cap(0);  // VideoCapture(int device)<br />
  if(!cap.isOpened()) return -1;<br />
  Mat edges;<br />
  char code;<br />
  namedWindow(&#8220;OpenCV 2.0 Capture Test&#8221;, CV_WINDOW_AUTOSIZE);<br />
  for(;;) {<br />
    Mat frame;<br />
    cap >> frame;  // virtual VideoCapture&#038;  operator >> (Mat&#038; image)<br />
    cvtColor(frame ,edges, CV_BGR2GRAY);<br />
    GaussianBlur(edges, edges, Size(7, 7), 1.5, 1.5);<br />
    Canny(edges, edges, 0, 30, 3);<br />
    imshow(&#8220;OpenCV 2.0 Capture Test&#8221;, edges);<br />
    code = waitKey(30);<br />
    if(code == &#8216;q&#8217;) break;<br />
    if(code == &#8217;s&#8217;) imwrite(&#8220;test.jpg&#8221;, edges);<br />
  }<br />
  return 0;<br />
}<br />
[/csharp]</p>
]]></content:encoded>
			<wfw:commentRss>http://rest-term.com/archives/2402/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Thriftでバイナリデータを扱う</title>
		<link>http://rest-term.com/archives/2393/</link>
		<comments>http://rest-term.com/archives/2393/#comments</comments>
		<pubDate>Sun, 04 Oct 2009 14:49:32 +0000</pubDate>
		<dc:creator>wellflat</dc:creator>
				<category><![CDATA[tech/study]]></category>
		<category><![CDATA[c/c++]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://rest-term.com/?p=2393</guid>
		<description><![CDATA[Thriftでバイナリデータをやりとりする方法。
以前、FlexでXML-RPCを利用していた時は、確かbase64にエンコードして返していたと思うので、
Thriftでも同様にバイナリデータはbase64にエンコードして返すようにします。
Thriftのソースを漁っていると TBase64Utils とかいうのを見つけたのですが、
どうせboost必須なフレームワークなのでboostを使ってエンコードしてみます。
インタフェースとして、
・サービス名を Test
・プロシージャ名を returnImage
・引数は画像ファイル名、戻り値はbase64エンコード文字列
を定義します。

#!/usr/bin/thrift

service Test {
  string returnImage(1: string name)
}

画像ファイルを読み込んで、base64にエンコードするだけの処理です。
boostでbase64にエンコードする方法は以下のサイトを参考にさせていただきました。
B Lifeで行こう: boostでbase64のエンコード
ここではハンドラの部分のみ、自動生成部分は省略します。
[csharp]
class TestHandler : virtual public TestIf {
 public:
  TestHandler() {
  }
  void returnImage(std::string&#038; _return, const std::string&#038; name) {
    std::ifstream ifs;
    std::ostringstream oss;
    std::string str;
    ifs.open(name.c_str(), std::ios::in &#124; [...]]]></description>
			<content:encoded><![CDATA[<p>Thriftでバイナリデータをやりとりする方法。</p>
<p>以前、FlexでXML-RPCを利用していた時は、確かbase64にエンコードして返していたと思うので、<br />
Thriftでも同様にバイナリデータはbase64にエンコードして返すようにします。<br />
Thriftのソースを漁っていると TBase64Utils とかいうのを見つけたのですが、<br />
どうせboost必須なフレームワークなのでboostを使ってエンコードしてみます。</p>
<p>インタフェースとして、<br />
・サービス名を Test<br />
・プロシージャ名を returnImage<br />
・引数は画像ファイル名、戻り値はbase64エンコード文字列<br />
を定義します。</p>
<pre>
#!/usr/bin/thrift

service Test {
  string returnImage(1: string name)
}
</pre>
<p>画像ファイルを読み込んで、base64にエンコードするだけの処理です。<br />
boostでbase64にエンコードする方法は以下のサイトを参考にさせていただきました。<br />
<a href="http://babei.sblo.jp/article/25063647.html" title="B Lifeで行こう: boostでbase64のエンコード">B Lifeで行こう: boostでbase64のエンコード</a></p>
<p>ここではハンドラの部分のみ、自動生成部分は省略します。</p>
<p>[csharp]<br />
class TestHandler : virtual public TestIf {</p>
<p> public:<br />
  TestHandler() {<br />
  }</p>
<p>  void returnImage(std::string&#038; _return, const std::string&#038; name) {<br />
    std::ifstream ifs;<br />
    std::ostringstream oss;<br />
    std::string str;</p>
<p>    ifs.open(name.c_str(), std::ios::in | std::ios::binary);<br />
    if(!ifs.is_open()) {<br />
      _return = &#8220;&#8221;;<br />
    }else {<br />
      oss<<ifs.rdbuf();<br />
      str = oss.str();<br />
      _return = encode_base64(str);<br />
    }<br />
  }</p>
<p>  std::string encode_base64(const std::string&#038; src_data) {<br />
    using namespace boost::archive::iterators;<br />
    const int Base64_Column_Width = 76;<br />
    typedef insert_linebreaks<base64_from_binary<br />
<transform_width<<br />
      const char *, 6, 8> >, Base64_Column_Width> base64_encoder;</p>
<p>    // エンコードしたデータを格納<br />
    std::stringstream ost_base64;<br />
    // エンコード処理<br />
    std::copy(<br />
      base64_encoder(src_data.c_str()),<br />
      base64_encoder(src_data.c_str() + src_data.length()),<br />
      std::ostream_iterator<char>(ost_base64)<br />
    );<br />
    std::string base64 = ost_base64.str();<br />
    // 末尾の長さ調整<br />
    while(((base64.length() % (Base64_Column_Width + 1)) % 4) > 0) {<br />
      base64 += &#8220;=&#8221;;<br />
    }<br />
    return base64;<br />
  }<br />
};<br />
[/csharp]</p>
<p>次にクライアントを今回はPHPで書きます。<br />
RPCで受け取ったbase64エンコード文字列をimgタグに埋め込んで画面に表示します。</p>
<p>[php]<br />
<?php<br />
$GLOBALS['THRIFT_ROOT'] = 'src';<br />
$GEN_DIR = 'gen-php';</p>
<p>/** Include the Thrift base */<br />
require_once $GLOBALS['THRIFT_ROOT'].'/Thrift.php';</p>
<p>/** Include the binary protocol */<br />
require_once $GLOBALS['THRIFT_ROOT'].'/protocol/TBinaryProtocol.php';</p>
<p>/** Include the socket layer */<br />
require_once $GLOBALS['THRIFT_ROOT'].'/transport/TSocketPool.php';</p>
<p>/** Include the socket layer */<br />
require_once $GLOBALS['THRIFT_ROOT'].'/transport/TBufferedTransport.php';</p>
<p>/** Include the generated code */<br />
require_once $GEN_DIR.'/test/Test.php';<br />
require_once $GEN_DIR.'/test/test_types.php';</p>
<p>$transport = new TSocket('localhost', 9090);<br />
$client = new TestClient(new TBinaryProtocol($transport));</p>
<p>try {<br />
  $transport->open();<br />
  $img = $client->returnImage(&#8220;lenna.jpg&#8221;);  /* $img に base64エンコード文字列が入る */<br />
  $transport->close();<br />
}catch(Exception $e) {<br />
  echo $e->getMessage();<br />
}<br />
?></p>
<p><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><br />
<html xmlns="www.w3.org/1999/xhtml" lang="ja" xml:lang="ja"><br />
<head><br />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><br />
<meta http-equiv="Content-Style-Type" content="text/css" /></p>
<p></head><br />
<body><br />
<img src="data:image/jpg;base64,<?php echo $img ?>&#8221; /><br />
</body><br />
</html><br />
[/php]</p>
<p>こんな感じで一応上手く表示まで行うことができました。</p>
<p>サーバ側で画像処理を行った後、出力画像をクライアントに返す時などに使えます。<br />
楽な方法なんですが、大きな画像データをやりとりするのには向いてないですね；；<br />
もうちょっと良い方法を探してみます。</p>
<p>・関連記事<br />
<a href="http://rest-term.com/archives/2350/" title="Thrift + OpenCV">Thrift + OpenCV</a><br />
<a href="http://rest-term.com/archives/2310/" title="Thrift::例外処理">Thrift::例外処理</a><br />
<a href="http://rest-term.com/archives/2297/" title="Thriftインストール">Thriftインストール</a></p>
]]></content:encoded>
			<wfw:commentRss>http://rest-term.com/archives/2393/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>memcached: Slab Allocator</title>
		<link>http://rest-term.com/archives/2364/</link>
		<comments>http://rest-term.com/archives/2364/#comments</comments>
		<pubDate>Fri, 02 Oct 2009 02:37:30 +0000</pubDate>
		<dc:creator>wellflat</dc:creator>
				<category><![CDATA[tech/study]]></category>
		<category><![CDATA[c/c++]]></category>

		<guid isPermaLink="false">http://rest-term.com/?p=2364</guid>
		<description><![CDATA[僕の務める会社でも memcached はほとんどのサービスで利用されています。
今は業務も少ないので、ひまつぶしにmemcachedのコードを読んでいました。
Slab Allocatorの部分に興味を持ったので、それについてわかったことのメモ。
以下のサイトで事前知識を付けてからコードを読みました。
memcachedを知り尽くす：第2回　memcachedのメモリストレージを理解する
Slab Allocator : メモリの確保・管理を行うメカニズム
　・メモリアロケーションでオーバーヘッドの大きいmalloc()を極力呼ばない
　・一度アロケートしたメモリ領域を再利用してメモリフラグメンテーションを抑える
これらを実現するために以下のルールでメモリアロケーションを行っています。
　・memcachedの初期化時にmalloc()で大きな領域(slabと呼ばれる, デフォルトで1MB)を確保
　・あるslab classに属するslabは全て同一サイズのchunkで構成される
　・chunkサイズはslab classにより異なる
　・各slabはどのchunkが使われていないかを指すポインタを持っている
　・chunkは不要になったらfree()されるのではなく、再利用するためにchunkリストに戻される
　・もし利用可能なchunkがなくなった場合は、malloc()して新しいslabを作成する
Slab Allocatorの実装は slabs.h, slabs.c
　・ slabclass_t 構造体
chunkサイズやslabのリストを持っています。
これを見ると、chunkのことをコード上ではitemと呼んでいる模様。
[csharp]
typedef struct {
    unsigned int size;      /* sizes of items */
    unsigned int perslab;   /* how many items per slab */
    void **slots;   [...]]]></description>
			<content:encoded><![CDATA[<p>僕の務める会社でも memcached はほとんどのサービスで利用されています。<br />
今は業務も少ないので、ひまつぶしにmemcachedのコードを読んでいました。</p>
<p><strong>Slab Allocator</strong>の部分に興味を持ったので、それについてわかったことのメモ。<br />
以下のサイトで事前知識を付けてからコードを読みました。<br />
<a href="http://gihyo.jp/dev/feature/01/memcached/0002" title="memcachedを知り尽くす：第2回　memcachedのメモリストレージを理解する｜gihyo.jp … 技術評論社">memcachedを知り尽くす：第2回　memcachedのメモリストレージを理解する</a></p>
<h3>Slab Allocator : メモリの確保・管理を行うメカニズム</h3>
<p>　・メモリアロケーションでオーバーヘッドの大きいmalloc()を極力呼ばない<br />
　・一度アロケートしたメモリ領域を再利用してメモリフラグメンテーションを抑える</p>
<p>これらを実現するために以下のルールでメモリアロケーションを行っています。<br />
　・memcachedの初期化時にmalloc()で大きな領域(slabと呼ばれる, デフォルトで1MB)を確保<br />
　・あるslab classに属するslabは全て同一サイズのchunkで構成される<br />
　・chunkサイズはslab classにより異なる<br />
　・各slabはどのchunkが使われていないかを指すポインタを持っている<br />
　・chunkは不要になったらfree()されるのではなく、再利用するためにchunkリストに戻される<br />
　・もし利用可能なchunkがなくなった場合は、malloc()して新しいslabを作成する</p>
<p>Slab Allocatorの実装は slabs.h, slabs.c<br />
　・ slabclass_t 構造体<br />
chunkサイズやslabのリストを持っています。<br />
これを見ると、chunkのことをコード上ではitemと呼んでいる模様。</p>
<p>[csharp]<br />
typedef struct {<br />
    unsigned int size;      /* sizes of items */<br />
    unsigned int perslab;   /* how many items per slab */</p>
<p>    void **slots;           /* list of item ptrs */<br />
    unsigned int sl_total;  /* size of previous array */<br />
    unsigned int sl_curr;   /* first free slot */</p>
<p>    void *end_page_ptr;         /* pointer to next free item at end of page, or 0 */<br />
    unsigned int end_page_free; /* number of items remaining at end of last alloced page */</p>
<p>    unsigned int slabs;     /* how many slabs were allocated for this class */</p>
<p>    void **slab_list;       /* array of slab pointers */<br />
    unsigned int list_size; /* size of prev array */</p>
<p>    unsigned int killing;  /* index+1 of dying slab, or zero if none */<br />
    size_t requested; /* The number of requested bytes */<br />
} slabclass_t;</p>
<p>static slabclass_t slabclass[MAX_NUMBER_OF_SLAB_CLASSES];</p>
<p>[/csharp]</p>
<p>　・Slab Allocatorは固定数のslabclass_t配列を持ち、chunkサイズでソートされている<br />
　・slabclass_t配列のインデックス番号はclsidと呼ばれ、これはslab classを識別するためのidになっている</p>
<h3>Slab Allocatorのメインインタフェース</h3>
<p>[csharp]<br />
unsigned int slabs_clsid(const size_t size);<br />
void *slabs_alloc(size_t size, unsigned int id);<br />
void slabs_free(void *ptr, size_t size, unsigned int id);<br />
[/csharp]<br />
malloc()が実際にメモリ割り当てを行っているのに対して、<br />
slab_alloc()はあらかじめ確保した領域から、最適なサイズのchunkを返しているだけです。<br />
同様に、free()が実際にメモリ解放を行っているのに対して、<br />
slab_free()はchunkをリスト(slabclass_tのslots)に戻しているだけです。</p>
<p>[csharp]<br />
unsigned int clsid;<br />
item *it;<br />
clsid = slabs_clsid(item_size);  // item_sizeに応じてclsidを決める<br />
it = slabs_alloc(item_size, clsid); // item_sizeとclsidをもとにchunkの割り当てを行う<br />
slabs_free(it, item_size, clsid); // chunkをリストに戻す<br />
[/csharp]</p>
<p>このSlab Allocatorの仕組みは、Linuxカーネルでも使われているとのことです。<br />
時間があれば続きを読んでいきたいと思います。</p>
<p>・参考<br />
<a href="http://code.google.com/p/memcached/wiki/MemcachedSlabAllocator" title="MemcachedSlabAllocator - memcached - Project Hosting on Google Code">MemcachedSlabAllocator &#8211; memcached -</a></p>
]]></content:encoded>
			<wfw:commentRss>http://rest-term.com/archives/2364/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Thrift + OpenCV</title>
		<link>http://rest-term.com/archives/2350/</link>
		<comments>http://rest-term.com/archives/2350/#comments</comments>
		<pubDate>Tue, 22 Sep 2009 13:33:11 +0000</pubDate>
		<dc:creator>wellflat</dc:creator>
				<category><![CDATA[tech/study]]></category>
		<category><![CDATA[c/c++]]></category>
		<category><![CDATA[cv/im]]></category>
		<category><![CDATA[perl]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://rest-term.com/?p=2350</guid>
		<description><![CDATA[Thriftを利用してOpenCVの関数をスクリプトから呼んでみます。
といってもRPCで繋げるだけで特別なことをする必要はありません。
ここでは、画像の各チャンネルの平均値と標準偏差を求めてみます。
サーバ側でOpenCVの cvAvgSvd() を利用すればOK。
まず、最初にRPCのインタフェースをThrift IDLに書きます。
ここでは、平均と標準偏差を求める関数を2つ作ることにしました。
各チャンネルの値が欲しいので戻り値は list&#60;double&#62; に、
引数は画像ファイル名を指定したいので string にしておきます。
• cv.thrift (サービス名は CV)

service CV {
  list&#60;double&#62; calcAvg(1: string img)
  list&#60;double&#62; calcSdv(1: string img)
}

• thriftコマンドでコード生成

$ thrift --gen cpp --gen perl --gen php --gen rb cv.thrift

サーバ側の実装ではC++で普通にOpenCVを使って書けばOKです。
(今回の場合は gen-cpp/CV_server.skeleton.cpp というファイルを編集する)
メソッドの引数にだけ注意しておきます。
ここではコードを一部省略しますが、実際はドメインロジック以外自動生成されます。
ソケットを作って接続を待ったり、データ構造をシリアライズしたりといった面倒な部分は、
全てThriftが引き受けてくれるので安心です。
• サーバ側 CV_server.skeleton.cpp (C++)
[csharp]
#include &#8220;CV.h&#8221;
#include

#include 
#include

#include

#include 
#include 
#include 
/*  中略  */
class CVHandler : virtual public CVIf {
  [...]]]></description>
			<content:encoded><![CDATA[<p>Thriftを利用してOpenCVの関数をスクリプトから呼んでみます。<br />
といってもRPCで繋げるだけで特別なことをする必要はありません。</p>
<p>ここでは、画像の各チャンネルの平均値と標準偏差を求めてみます。<br />
サーバ側でOpenCVの cvAvgSvd() を利用すればOK。</p>
<p>まず、最初にRPCのインタフェースをThrift IDLに書きます。<br />
ここでは、平均と標準偏差を求める関数を2つ作ることにしました。<br />
各チャンネルの値が欲しいので戻り値は list&lt;double&gt; に、<br />
引数は画像ファイル名を指定したいので string にしておきます。</p>
<p><strong>• cv.thrift (サービス名は CV)</strong></p>
<pre>
service CV {
  list&lt;double&gt; calcAvg(1: string img)
  list&lt;double&gt; calcSdv(1: string img)
}
</pre>
<p><strong>• thriftコマンドでコード生成</strong></p>
<pre>
$ thrift --gen cpp --gen perl --gen php --gen rb cv.thrift
</pre>
<p>サーバ側の実装ではC++で普通にOpenCVを使って書けばOKです。<br />
(今回の場合は gen-cpp/CV_server.skeleton.cpp というファイルを編集する)<br />
メソッドの引数にだけ注意しておきます。<br />
ここではコードを一部省略しますが、実際はドメインロジック以外自動生成されます。<br />
ソケットを作って接続を待ったり、データ構造をシリアライズしたりといった面倒な部分は、<br />
全てThriftが引き受けてくれるので安心です。</p>
<p><strong>• サーバ側 CV_server.skeleton.cpp (C++)</strong><br />
[csharp]<br />
#include &#8220;CV.h&#8221;<br />
#include
<protocol/TBinaryProtocol.h>
#include <server/TSimpleServer.h><br />
#include<br />
<transport/TServerSocket.h>
#include<br />
<transport/TBufferTransports.h>
<p>#include <cv.h><br />
#include <highgui.h><br />
#include <iostream></p>
<p>/*  中略  */</p>
<p>class CVHandler : virtual public CVIf {<br />
  IplImage *srcImg;<br />
  CvScalar mean;<br />
  CvScalar std_dev;<br />
 public:<br />
  CVHandler() {<br />
    srcImg = 0;<br />
    mean = cvScalarAll(0);<br />
    std_dev = cvScalarAll(0);<br />
  }</p>
<p>  void calcAvg(std::vector<double> &#038; _return, const std::string&#038; img) {<br />
    if((srcImg = cvLoadImage(img.c_str(), CV_LOAD_IMAGE_ANYDEPTH |  CV_LOAD_IMAGE_ANYCOLOR)) == 0) {<br />
      std::cout<<"load error."<<std::endl;<br />
      exit(0);<br />
    }<br />
    cvAvgSdv(srcImg , &#038;mean, NULL);<br />
    for(int i=0;i<3;++i) _return.push_back(mean.val[i]);<br />
    cvReleaseImage(&#038;srcImg);<br />
  }</p>
<p>  void calcSdv(std::vector<double> &#038; _return, const std::string&#038; img) {<br />
    /* 以下略 (calcAvgと同様に書けばよい)*/<br />
　<br />
[/csharp]</p>
<p>• コンパイル</p>
<pre>
$ g++ -g CV.cpp CV_server.skeleton.cpp -o CV_server `pkg-config --cflags --libs opencv thrift`
</pre>
<p>次はクライアント側を実装します。<br />
<strong>• クライアント側 cv.pl (Perl)</strong><br />
[php]<br />
#!/usr/bin/perl</p>
<p>use strict;<br />
use warnings;<br />
use lib &#8216;./gen-perl&#8217;;</p>
<p>use Thrift;<br />
use Thrift::BinaryProtocol;<br />
use Thrift::Socket;</p>
<p>use CV;</p>
<p>my $transport = Thrift::Socket->new(&#8216;localhost&#8217;, 9090);<br />
my $client = CVClient->new(Thrift::BinaryProtocol->new($transport));</p>
<p>eval {<br />
  $transport->open();<br />
  print &#8220;Calculate the Mean\n( Blue Green Red ) = ( &#8220;;<br />
  printf &#8220;%f &#8220;, $_ for @{$client->calcAvg(&#8220;lena.jpg&#8221;)};　# 戻り値はリストリファレンス<br />
  print &#8220;)\n\n&#8221;;<br />
  print &#8220;Calculate the Standard-Deviation\n( Blue Green Red ) = ( &#8220;;<br />
  printf &#8220;%f &#8220;, $_ for @{$client->calcSdv(&#8220;baboon.jpg&#8221;)};<br />
  print &#8220;)&#8221;;<br />
  $transport->close();<br />
};</p>
<p>if($@) {<br />
  warn $@->{message};<br />
}<br />
[/php]<br />
<strong><br />
• サーバの起動およびクライアントの実行</strong></p>
<pre>
$ mv ./gen-cpp/CV_server .
$ ./CV_server
</pre>
<pre>
$ chmod +x cv.pl
$ ./cv.pl
Calculate the Mean
( Blue Green Red ) = ( 105.398991 99.562698 179.730305 )

Calculate the Standard-Deviation
( Blue Green Red ) = ( 60.611124 47.493925 55.499225 )
</pre>
<p>上手くいきました。<br />
次はPHPから。抽象化レイヤのおかげでPHPでも簡単に使えます。<br />
<strong>• クライアント側  cv.php (PHP)</strong></p>
<p>[php]<br />
<?php<br />
$GLOBALS['THRIFT_ROOT'] = 'src';<br />
$GEN_DIR = 'gen-php';</p>
<p>/** Include the Thrift base */<br />
require_once $GLOBALS['THRIFT_ROOT'].'/Thrift.php';</p>
<p>/** Include the binary protocol */<br />
require_once $GLOBALS['THRIFT_ROOT'].'/protocol/TBinaryProtocol.php';</p>
<p>/** Include the socket layer */<br />
require_once $GLOBALS['THRIFT_ROOT'].'/transport/TSocketPool.php';</p>
<p>/** Include the socket layer */<br />
require_once $GLOBALS['THRIFT_ROOT'].'/transport/TBufferedTransport.php';</p>
<p>/** Include the generated code */<br />
require_once $GEN_DIR.'/CV.php';<br />
require_once $GEN_DIR.'/cv_types.php';</p>
<p>$transport = new TSocket('localhost', 9090);<br />
$client = new CVClient(new TBinaryProtocol($transport));</p>
<p>try {<br />
  $transport->open();<br />
  print_r($client->calcAvg(&#8220;lena.jpg&#8221;));　/* Perl版と同じように呼べる */<br />
  print_r($client->calcSdv(&#8220;baboon.jpg&#8221;));<br />
  $transport->close();<br />
}catch(Exception $e) {<br />
  echo $e->getMessage();<br />
}</p>
<p>?><br />
[/php]</p>
<p><strong>• 出力結果</strong></p>
<pre>
Array
(
    [0] => 105.3989906311
    [1] => 99.562698364258
    [2] => 179.73030471802
)
Array
(
    [0] => 60.611123950567
    [1] => 47.493925313866
    [2] => 55.499224912776
)
</pre>
<p>詳細は省きますが、Rubyでもシンタックスを変えるだけで利用できます。<br />
[php]<br />
# Rubyでも簡単<br />
client.calcAvg(&#8220;lena.jpg&#8221;)<br />
client.calcSdv(&#8220;baboon.jpg&#8221;)<br />
[/php]</p>
<p>今回はThriftを使って各言語から簡単にOpenCVを利用できることを確認しました。</p>
<p>それはともかくOpenCV 2.0 のリリースが Sept. 31, 2009 って書いてありましたが、<br />
また便利な機能が追加されてるんですかね。楽しみです。</p>
]]></content:encoded>
			<wfw:commentRss>http://rest-term.com/archives/2350/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Thrift::例外処理</title>
		<link>http://rest-term.com/archives/2310/</link>
		<comments>http://rest-term.com/archives/2310/#comments</comments>
		<pubDate>Sun, 20 Sep 2009 09:50:59 +0000</pubDate>
		<dc:creator>wellflat</dc:creator>
				<category><![CDATA[tech/study]]></category>
		<category><![CDATA[perl]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://rest-term.com/?p=2310</guid>
		<description><![CDATA[Thriftでの例外処理について。
macbookへのインストールについてはThriftインストールを参照。
hello, world 的な話はたくさん情報が公開されているのでそちらを参考するといいかと。
ここでは例外処理についてメモしておきます。
TException
ThriftはRPCフレームワークです。
このRPCにおいてなんらかの理由でサーバと通信ができなかった時などの異常系処理。
ThriftではTExceptionという例外オブジェクトを送出します。
PerlとPHPの例を載せますが、以下のように普通にハンドリングすればOKです。
• Perlの場合
[php]
my $transport = Thrift::Socket->new(&#8216;localhost&#8217;, 9090);
my $client = HelloClient->new(Thrift::BinaryProtocol->new($transport));
eval {
  $transport->open();
  printf &#8220;%s¥n&#8221;, $client->hello(&#8220;aru&#8221;);
  $transport->close();
};
if($@) {
  print $@->{message};
}
[/php]
• PHPの場合
[php]
$transport = new TSocket(&#8216;localhost&#8217;, 9090);
$client = new HelloClient(new TBinaryProtocol($transport));
try {
  $transport->open();
  echo $client->hello(&#8220;aru&#8221;);
  $transport->close();
}catch(Exception $e) {
  echo $e->getMessage();
}
[/php]
普通ですね。
エラーメッセージは message というプロパティに入っています。
• エラーメッセージ例

TSocket: Could not connect to localhost:9090

RPCにおける異常系処理にも特に頭を悩ませることがないのはうれしいです。
]]></description>
			<content:encoded><![CDATA[<p>Thriftでの例外処理について。</p>
<p>macbookへのインストールについては<a href="http://rest-term.com/archives/2297/">Thriftインストール</a>を参照。<br />
hello, world 的な話はたくさん情報が公開されているのでそちらを参考するといいかと。<br />
ここでは例外処理についてメモしておきます。</p>
<p><strong>TException</strong><br />
ThriftはRPCフレームワークです。<br />
このRPCにおいてなんらかの理由でサーバと通信ができなかった時などの異常系処理。<br />
ThriftではTExceptionという例外オブジェクトを送出します。<br />
PerlとPHPの例を載せますが、以下のように普通にハンドリングすればOKです。</p>
<p><strong>• Perlの場合</strong><br />
[php]<br />
my $transport = Thrift::Socket->new(&#8216;localhost&#8217;, 9090);<br />
my $client = HelloClient->new(Thrift::BinaryProtocol->new($transport));</p>
<p>eval {<br />
  $transport->open();<br />
  printf &#8220;%s¥n&#8221;, $client->hello(&#8220;aru&#8221;);<br />
  $transport->close();<br />
};<br />
if($@) {<br />
  print $@->{message};<br />
}<br />
[/php]</p>
<p><strong>• PHPの場合</strong><br />
[php]<br />
$transport = new TSocket(&#8216;localhost&#8217;, 9090);<br />
$client = new HelloClient(new TBinaryProtocol($transport));</p>
<p>try {<br />
  $transport->open();<br />
  echo $client->hello(&#8220;aru&#8221;);<br />
  $transport->close();<br />
}catch(Exception $e) {<br />
  echo $e->getMessage();<br />
}<br />
[/php]<br />
普通ですね。<br />
エラーメッセージは message というプロパティに入っています。</p>
<p>• エラーメッセージ例</p>
<pre>
TSocket: Could not connect to localhost:9090
</pre>
<p>RPCにおける異常系処理にも特に頭を悩ませることがないのはうれしいです。</p>
]]></content:encoded>
			<wfw:commentRss>http://rest-term.com/archives/2310/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>休養中&#8230;</title>
		<link>http://rest-term.com/archives/2315/</link>
		<comments>http://rest-term.com/archives/2315/#comments</comments>
		<pubDate>Sun, 20 Sep 2009 06:32:59 +0000</pubDate>
		<dc:creator>wellflat</dc:creator>
				<category><![CDATA[diary]]></category>

		<guid isPermaLink="false">http://rest-term.com/?p=2315</guid>
		<description><![CDATA[って書くと、仕事辛くて休職中みたいにも読めるけど、別にそこまで辛くはないです；
今日は六本木ヒルズの森美術館とスカイアクアリウムに行ってきました。
美術館はフラッシュ無しなら撮影可だったんですが、なんとデジカメを忘れるという。。
まぁここに写真を貼るよりああいうのは実物をみないとあんまり意味ないですし。
一応ケータイで東京の街並みを撮りましたが、ひどい画質。。

あとは、マグカップとかエンピツを買ってきました。

職場から歩いて5,6分くらいなんですが、あまり行かないので今日はイイ気分転換になりました。
]]></description>
			<content:encoded><![CDATA[<p>って書くと、仕事辛くて休職中みたいにも読めるけど、別にそこまで辛くはないです；</p>
<p>今日は六本木ヒルズの森美術館とスカイアクアリウムに行ってきました。<br />
美術館はフラッシュ無しなら撮影可だったんですが、なんとデジカメを忘れるという。。<br />
まぁここに写真を貼るよりああいうのは実物をみないとあんまり意味ないですし。</p>
<p>一応ケータイで東京の街並みを撮りましたが、ひどい画質。。<br />
<img src="http://rest-term.com/wp-content/uploads/2009/09/200909201220000.jpg" alt="200909201220000" title="200909201220000" width="240" height="345" class="alignnone size-full wp-image-2319" /><img src="http://rest-term.com/wp-content/uploads/2009/09/200909201223000.jpg" alt="200909201223000" title="200909201223000" width="240" height="345" class="alignnone size-full wp-image-2320" /></p>
<p>あとは、マグカップとかエンピツを買ってきました。<br />
<a href="http://rest-term.com/wp-content/uploads/2009/09/DSC00821.JPG"><img src="http://rest-term.com/wp-content/uploads/2009/09/DSC00821-300x225.jpg" alt="DSC00821" title="DSC00821" width="300" height="225" class="alignnone size-medium wp-image-2316" /></a></p>
<p>職場から歩いて5,6分くらいなんですが、あまり行かないので今日はイイ気分転換になりました。</p>
]]></content:encoded>
			<wfw:commentRss>http://rest-term.com/archives/2315/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Thriftインストール</title>
		<link>http://rest-term.com/archives/2297/</link>
		<comments>http://rest-term.com/archives/2297/#comments</comments>
		<pubDate>Sat, 29 Aug 2009 17:53:00 +0000</pubDate>
		<dc:creator>wellflat</dc:creator>
				<category><![CDATA[tech/study]]></category>

		<guid isPermaLink="false">http://rest-term.com/?p=2297</guid>
		<description><![CDATA[Thriftを業務で今後利用するかもしれないので少し調べています。
ただ、インストールでつまづいてた。。
普通に公式サイトに書いてあるようにやれば上手くインストールできるのです。
FrontPage Thrift Wiki
ただ、FAQもよく読んでおくべきだった。。それだけ。
一応メモ。
今回はMacbookにインストールしました。
Thriftはboostが必須なので注意。公式サイトにはSo please download the bzip2 of boost and unpack〜〜とか書いてありますが、portでインストールしてしまいます。
$ sudo port install boost
インストールに失敗する場合は一度cleanしてみる。
$ sudo port clean --work boost
環境変数の設定も忘れずに(.bashrc, .zshrc &#8230;)。

export PATH=/opt/local/bin:/opt/local/sbin/:$PATH
export MANPATH=/opt/local/man:$MANPATH
export LIBRARY_PATH=/opt/local/lib:$LIBRARY_PATH
export LD_LIBRARY_PATH=/opt/local/lib:$LD_LIBRARY_PATH
export C_INCLUDE_PATH=/opt/local/include:$C_INCLUDE_PATH
export CPLUS_INCLUDE_PATH=/opt/local/include:$CPLUS_INCLUDE_PATH
export DYLD_FALLBACK_LIBRARY_PATH=/opt/local/lib
export BOOST_ROOT=/opt/local/include/boost:$BOOST_ROOT

あとはThrift本体をインストールするだけです。

$ wget -O thrift.tgz "http://gitweb.thrift-rpc.org/?p=thrift.git;a=snapshot;h=HEAD;sf=tgz"
$ tar -xzf thrift.tgz
$ cd thrift
$ ./bootstrap.sh
$ ./configure
$ make
$ sudo make install

ただ、僕の場合 ./configure で以下のようなエラーがでました。

./configure: line 21183: syntax error near unexpected token `MONO,'
./configure: [...]]]></description>
			<content:encoded><![CDATA[<p>Thriftを業務で今後利用するかもしれないので少し調べています。<br />
ただ、インストールでつまづいてた。。<br />
普通に公式サイトに書いてあるようにやれば上手くインストールできるのです。<br />
<a href="http://wiki.apache.org/thrift/">FrontPage Thrift Wiki</a><br />
ただ、FAQもよく読んでおくべきだった。。それだけ。</p>
<p>一応メモ。<br />
今回はMacbookにインストールしました。<br />
Thriftはboostが必須なので注意。公式サイトにはSo please download the bzip2 of boost and unpack〜〜とか書いてありますが、portでインストールしてしまいます。</p>
<pre><code>$ sudo port install boost</code></pre>
<p>インストールに失敗する場合は一度cleanしてみる。</p>
<pre><code>$ sudo port clean --work boost</code></pre>
<p>環境変数の設定も忘れずに(.bashrc, .zshrc &#8230;)。</p>
<pre><code>
export PATH=/opt/local/bin:/opt/local/sbin/:$PATH
export MANPATH=/opt/local/man:$MANPATH
export LIBRARY_PATH=/opt/local/lib:$LIBRARY_PATH
export LD_LIBRARY_PATH=/opt/local/lib:$LD_LIBRARY_PATH
export C_INCLUDE_PATH=/opt/local/include:$C_INCLUDE_PATH
export CPLUS_INCLUDE_PATH=/opt/local/include:$CPLUS_INCLUDE_PATH
export DYLD_FALLBACK_LIBRARY_PATH=/opt/local/lib
export BOOST_ROOT=/opt/local/include/boost:$BOOST_ROOT
</code></pre>
<p>あとはThrift本体をインストールするだけです。</p>
<pre><code>
$ wget -O thrift.tgz "http://gitweb.thrift-rpc.org/?p=thrift.git;a=snapshot;h=HEAD;sf=tgz"
$ tar -xzf thrift.tgz
$ cd thrift
$ ./bootstrap.sh
$ ./configure
$ make
$ sudo make install
</code></pre>
<p>ただ、僕の場合 ./configure で以下のようなエラーがでました。</p>
<pre>
./configure: line 21183: syntax error near unexpected token `MONO,'
./configure: line 21183: `  PKG_CHECK_MODULES(MONO, mono >= 1.2.6, have_mono=yes, have_mono=no)'
</pre>
<p>意味がわからなくて途方に暮れていたんですが、公式のFAQに解決策が書いてありました。。<br />
<a href="http://wiki.apache.org/thrift/FAQ">FAQ &#8211; Thrift Wiki</a><br />
If you&#8217;re on OS X: find pkg.m4, copy it to thrift/aclocal, and rerun bootstrap.sh.<br />
とあるので、とりあえず /opt/local/share/aclocal  に pkg.m4 があるか確認してからcopy。<br />
(pkgconfigパッケージがインストールされている必要がある)</p>
<pre>
$ cp /opt/local/share/aclocal/pkg.m4 ./aclocal
$ ./bootstrap.sh
.... 略
</pre>
<p>make install まで上手くいきました。<br />
公式にドキュメントがある場合はFAQも含めてよく読もう。</p>
<p>＜追記＞<br />
各言語のライブラリのインストールも忘れないように。<br />
ここでは、perl, ruby, pythonの各ライブラリをインストールしておきます。</p>
<pre>
$ cd lib/perl
$ perl Makefile.PL
$ sudo make install
$ cd ../rb
$ sudo ruby setup.rb
$ cd ../py
$ sudo python setup.py install
</pre>
]]></content:encoded>
			<wfw:commentRss>http://rest-term.com/archives/2297/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic page generated in 2.435 seconds. -->
<!-- Cached page generated by WP-Super-Cache on 2010-03-13 05:50:51 -->
