2011年12月21日水曜日

【php】XMLを読み込んで複数のコマンドを実行する

前回のプログラムを少し拡張してみた。XMLをロードして複数コマンドを実行する。

001<?php
002doMultiProcesses($argc , $argv);
003//コマンド
004function doMultiProcesses($num,$param){
005    if($num  < 2){
006        echo "コマンドが入力されていません。\n";
007        return;
008    }
009    execProcess($param);
010 }
011 
012//コマンドの実行
013function execProcess($arg)
014{
015    switch($arg[1]){
016    case "xml":
017        if(count($arg) < 3){ echo "引数が足りていません\n";return;}
018        $process = new XMLLoader($arg[2]);
019        break;
020    default:
021        echo "設定されていないコマンドです。\n";
022        return;
023    }
024    $process->execute();
025 $processes = new Launcher();
026 $processes->setProcesses($process->processes);
027 //$processes->isQueue = false;
028 $processes->execute();
029  
030}
031 
032 
033/***********************
034 *
035 * 抽象クラス
036 *
037 **********************/
038abstract class AbstractProcess{  
039    abstract public function execute();
040    abstract public static function toString();
041}
042 
043class Process
044{
045 public $params;
046 public $name;
047  
048 public function Process($name,$params){
049  $this->name = $name;
050  $this->params  = $params;
051 }
052  
053 public static function create($name,$params)
054 {
055  $className  = $name;
056  $classParams = $params;
057        if(class_exists($className)){
058            $process = new $className($classParams);
059        }else{
060            echo $className . "という処理がみつかりません。\n";
061        }
062  return $process;
063 }
064}
065 
066/***********************
067 *
068 * 複数コマンドの実行用
069 *
070 ***********************/
071 
072final class Launcher extends AbstractProcess{
073  
074 public $processes;
075 public $isQueue;
076  
077 public function Launcher(){
078  $this->isQueue = true;
079 }
080  
081 public function setProcesses($value){
082  $this->processes = $value;
083 }
084  
085 public function execute(){
086  while(count($this->processes) > 0){
087   if($this->isQueue){
088    $process = array_shift($this->processes);
089   }else{
090    $process = array_pop($this->processes);
091   }
092   $process->execute();
093  }
094 }
095  
096 public static function toString(){
097  return "Launcher";
098 }
099}
100 
101 
102/***********************
103 *
104 * コマンドローダー
105 *
106 ***********************/
107 
108class XMLLoader extends AbstractProcess{
109     
110 
111     
112    private $path = "";
113    public $processes;
114         
115    public function XMLLoader($path){
116        $this->path = $path;
117        $this->processes = array();
118    }
119 
120    public function execute(){
121         
122        if(!file_exists($this->path)) {
123            echo "ファイルが存在しません\n";
124            return;
125        }
126        try{
127            $xml = simplexml_load_file($this->path);
128        }catch(Exception $e ){
129            echo "XMLの書式が間違っています\n";
130            return;
131        }
132 
133        foreach( $xml->process as $process){
134            $name = (string)($process->name);
135            $param = (string)($process->param);
136   $prc = Process::create($name,$param);
137 
138            if($prc instanceof AbstractProcess)
139                array_push($this->processes,$prc);
140        }
141    }
142 
143    public static function toString()
144    {
145        return "XMLLoader";
146    }
147}
148 
149/***********************
150 *
151 * サンプルコマンド
152 *
153 ***********************/
154class Test extends AbstractProcess
155{
156    private  $param;
157    public function Test($param){
158        $this->param = $param;
159    }
160 
161    public function execute(){
162         
163        echo $this->param . "\n";
164    }
165 
166    public static function toString()
167    {
168        return "Test";
169    }
170 
171}


これを使って以下のXMLを読み込んで実行する。
01<data>
02  <process>
03    <name>Test</name>
04    <param >param1</param>
05  </command>
06  <process>
07    <name>Test</name>
08    <param >param2</param>
09  </process>
10</data>


実行

1mr-elephant:php shuzo$ php process.php xml ./process.xml
2param1
3param2


とりあえず必要なものだけを実装してみました。
もうちょいなんか工夫できそうな気がします。

というかGithubにあげてみたいと思ったのですが、うまくいってません。orz

※インデントが気持ち悪いところだけ修正しました。
※commandという名前はあまりよくないというご指摘を受けたので、修正しました。
どうせなので、微妙にリファクタリングを追加。

2011年12月19日月曜日

【php】クラスの継承メモ

phpでコード生成のプログラムを書くことがちょくちょく増えてきたので、インターフェイスとかを統一しておきたい。まずはクラスの書き方から勉強。

01<?php
02cmd($argc , $argv);
03//コマンド
04function cmd($num,$param){
05    if($num  < 2){
06        echo "コマンドが入力されていません。\n";
07        return;
08    }
09    commandExec($param);
10 }
11 
12//コマンドの実行
13function commandExec($arg)
14{
15    switch($arg[1]){
16    case "test":
17        if(count($arg) < 3){ echo "引数が足りていません\n";return;}
18        $cmd = new TestCommand($arg[2]);
19        break;
20    default:
21        echo "設定されていないコマンドです。\n";
22        return;
23    }
24    $cmd->execute();
25}
26 
27/***********************
28 *
29 * スーパークラス
30 *
31 **********************/
32abstract class AbstractCommand{  
33    protected  $states;
34    abstract public function execute();
35    abstract public function toString();
36}
37 
38/***********************
39 *
40 * 子クラス
41 *
42 ***********************/
43class TestCommand extends AbstractCommand
44{
45    private  $param;
46    public function TestCommand($param){
47        $this->param = $param;
48    }
49 
50    public function execute(){
51         
52        echo $this->param . "\n";
53    }
54 
55    public function toString()
56    {
57        return "TestCommand";
58    }
59 
60}


これを実行すると。

1mr-elephant:php shuzo$ php cmd.php test hoge
2hoge


出力されました。上の内容でちょっとつまずいたところは、


01class TestCommand extends AbstractCommand
02{
03    private $hoge;
04    public function TestCommand($param){
05         
06        $hoge = $param;
07    }
08 
09    public function execute(){
10        echo $hoge . "\n";
11    }
12 
13    public function toString()
14    {
15        return "TestCommand";
16    }
17 
18}


上のやり方だと出力されず、メンバ変数へのアクセスには必ず$this->hogeを使うとのこと。省略しちゃだめってことですね。

2011年10月11日火曜日

Hello world

Dartでちょっと修正Hello World

1int main() {
2   
3 var hello = echo;
4 
5  hello('Hello world!!');
6}
7 
8echo(var str) => print(str);


結果
1Hello world!!

http://try-dart-lang.appspot.com/s/Z0ET
うむ。

ついでに(チョイ修正)、
01int main() {
02   
03 var hello = echo;
04 
05 hello('Hello world!!');
06}
07/*
08echo(String str){
09  print(str);
10}*/
11 
12echo(int str){
13  print(str);
14}


結果
1Hello world!!


http://try-dart-lang.appspot.com/s/iGUT
うーむ。

2011年9月8日木曜日

【AppleScript】ダイアログボックスを出す。

AppleScriptでダイアログボックスを出す。
あると便利だったりするのでメモ。
1on run ARGV
2  tell application "Finder"
3    activate
4    set msg to item 1 of argv
5    display dialog msg
6  end tell
7end run

コマンドラインで実行権限を与えてあげる
1chmod +x alert.applescript

実行
1osascript alert.applescript "Hello world"


結果

2011年6月22日水曜日

【JavaScript】jQueryを読んでみたい part.1

JavaScriptをしっかり勉強しようと思って、オライリーのJavaScriptパターン――優れたアプリケーションのための作法という本を読みながら実装をしたりしたんだけど、最初に見た先輩のAS3のコードがとても勉強になってすごいやる気が出た記憶もあり、やっぱり優れたプロダクトコードを見るのが一番勉強になると思うので、プログラミング言語人気TOP10の簡易解説という記事でも紹介されていたように、jQueryを読んでみようと思った。

思ったまではいいんだけど、まぁ、へたれなのでファイルを開いてとりあえず絶望したし、コードリーディングというものをどこからしていいのかわからない(現に使っているライブラリの挙動を見ようというイメージで触っていない)。
という訳でとりあえず”jQuery”という文字を利用している箇所を探すことにした。
1bash-3.2$ grep -n jQuery jquery-1.6.1.js  >> output.txt

でるわでるわ、ですぎるわ。
という訳で改めて。
1bash-3.2$ grep -n ^jQuery jquery-1.6.1.js  >> output2.txt


としたら割とまとまりのある感じに出力された。
とりあえず
1var jQuery = (function(){

で始まっている最初の部分から少しずつ読んでみようかなー。というところで今日はおしまい。

正直、意味あるのかはわからないけれど、とりあえずgrepの使い方は、なれといて損はなさそうだとは思った。
part2は、どうしよう。

2011年5月17日火曜日

【OpenCV】cvSobel / cvLaplace

画像のエッジ抽出をするのにcvSobelとcvLaplaceがでてきたのでメモ。
そもそもエッジ抽出をするとはどういう事なのか?と言うところから。
画像内にみることのできる輪郭線を抽出する、つまり色や形の変化がはっきり見えるところを特徴として抽出すると言う事、正確に言うと濃度の変化が大きいところをエッジと言うらしい。
つまり濃度の変化の値(つまり変化の傾き)が大きいところ、言い換えると変化を表す曲線の接戦がより垂直に近いところがエッジとなる。結果的に言うと2次微分をしたときに、その傾きの値が0になる点をエッジとなると見なせばよい、と言う事だそうだ。

そこで使うのがcvSobelと、cvLaplaceと言う事らしい。
Sobelを調べたけど元のいみはわからず。でてきたのは↓こちら。※一次微分と言う意味かと思ったらそれはGradientと言うらしい。
ソーベルフィルター《画像処理での edge detection filter の一つ; 水平方向と垂直方向のものがあり, 組み合わせて用いることもある; Prewitt filter に比べ, そのピクセルのある行・列の重みが高くなっている》.

「Weblio 辞書 / 英和辞典・和英辞典」より

ちなみにLaplaceはLaplacian(2次微分)で元はピエール=シモン・ラプラスという数学者からなんだそうな。
2 階線型の偏微分方程式である。
「wikipedia / ラプラス方程式」より


と書いてあったけど、正直のところぼんやりとしかわからない。とりあえず読み込んだ画像をグレースケールに直して、cvSobelとcvLaplaceをそれぞれ適応させてみると、以下のような結果を得ることができた。




ちなみにSobelは一次微分なので、X、Y方向を指定してあげて抽出する。みた通り、X、Y軸方向それぞれのエッジを検出することができる。また、Laplacianに比べて細い部分は取得できていないものの、細かいノイズを気にしなくても良いそう。

と、ここまでやってなんとなくどういうところに使えるかや、根本的な原理はなんとなくわかったものの、処理そのものがあまり理解できていないので、もう少し詳しくみた方が良さそう。

メモ:こちらのPDFが参考になそう。
http://www.osakac.ac.jp/labs/hild/IPslide7.pdf

2011年4月26日火曜日

【OpenCV】画像の二値化。CV_THRESHOLD_○×△

Thresholdってよく聞くけど何なのさ、と前も書いたようなデジャブに襲われましたが、【閾値】だそうですね。なかなかおぼえられん。OpenCVで画像の二値化を行ったときにちょっと気になったことがあったのでメモ。
画像の二値化は以下の方法にて。

1doble cvThreshold( const CvArr* src, CvArr* dist, double threshold,
2                                    double max_value, int hreshold_type);

というメソッドを使う場面がありまして、このときthreshold typeの部分にいくつかデフォルトで定数が用意されているようなので、その内容が気になったので結果を表示してみました。invって何だって思ってたんですけど昨日書いたINVERTつまり逆って事なんですねー。

CV_THRESH_BINARY



CV_THRESH_BINARY_INV



CV_THRESH_TRUNC



CV_THRESH_TOZERO



CV_THRESH_TOZRO_INV





2011年4月24日日曜日

【sudy】2011.4.24
















OpenCVによる透視変換の実行結果。
cvGetPerspectiveTransform()
cvWarpPerspective()
を使っている。

これとは関係ないのだけれど、今日一番ハッとした内容は逆行列を使って連立方程式を解く方法。
x + y + z = 2
7x + 3y + z = 4
4x + 2y + z = 6

をそれぞれ
「1 1 1  「x  「2
 7 3 1   y = 4
 4 2 1 」 z」  6」

とおいて両辺に逆行列をかけると
行列
「x
 y
 z」
が求まると言うもの。うむ、確かに。
これはいろんな場面で使えそう。
ActionScriptのmatrixクラスにも逆行列を求めるメソッドinvert();があるみたいなのでFlashでなんか作るときもこれは使えそう。

2011年4月9日土曜日

【C】RGBをHSVに変換した時の表示について。

01int main(int argc,char** argv)
02{
03    cvNamedWindow("source",CV_WINDOW_AUTOSIZE);
04    cvNamedWindow("HSV");
05 
06    IplImage* sourceImage = cvLoadImage(argv[1],
07            CV_LOAD_ANYDEPHT | CV_IMAGE_ANYCOLOR );
08    IplImage* hsvImage  = cvCreateImage(cvGetSize(sourceImage),
09             IPL_DEPTH_8U,
10             3);
11   cvCvtColor(sourceImage,hsvImage,CV_BGR2HSV);
12 
13   cvShowImage("source", sourceImage);
14   cvShowImage("HSV", hsvImage);
15 
16   /*------略-------*/
17}


RGBの画像のデータをHSVに変換して、そのデータがどんな感じになっているのかを上記のように表示しようとしたところ、画像が変な色で表示されてしまった。

こんな感じ。














で、少し調べてみたら、HSVに変換した情報自体が色空間情報をもっている訳ではないとの事。要するに画像を操作するようにデータを変換してあげていて、表示するための変換ではないと言う事らしい。というわけでcvShowImageで表示しようとしたときに、変な色で表示されてしまうと言う事らしい。たしかに、IplImage構造体のメンバ変数にもHSVとRGBを判別している値はない(とおもわれる?)し、cvShowImageの関数に引数を渡している訳でもないので、当然と言えば当然なのかもしれない。

2011年1月27日木曜日

【C++】初めてのOpenCV(コンパイル編)

_
あれこれしてたんですがなかなかコンパイルが通らなかったので、ウマく言った記念にメモ。多分もっといいやり方があるし、ほかのOpenCVをコンパイルしている方法よりも面倒だけど、ともかくC++のライブラリへリンクをしてコンパイルする方法を覚えた。

01#include "highgui.h"
02 
03int main(int argc , char** argv){
04  IplImage* img = cvLoadImage(argv[1]);
05  cvNamedWindow("Example1", CV_WINDOW_AUTOSIZE );
06  cvShowImage( "Exapmle1" , img );
07  cvWaitKey(0);
08  cvReleaseImage(&img);
09  cvDestroyWindow( "Example1" );
10}


で、下のようにすれば、コンパイルできました。
1g++-4.0 main.cpp -o main -I/usr/local/include/opencv
2                 -L/usr/local/lib -lopencv_core -lopencv_highgui


ちなみにOpenCVの入れ方は
Mac OSX Snow LeopardにOpenCVを入れてXCodeから使えるようにする手順 (konisimple log)
を参考にさせていただきました。
リンクファイルのパスは
1pkg-config --cflags opencv


1pkg-config --libs opencv


で、調べています。

2011年1月5日水曜日

【C++】vectorで要素の参照が無効になる。

   今書いているプログラムで、可変長配列のvectorをつかっていろいろいじくろうとしていたんだけれど、new演算子を使ってインスタンス化したクラスのポインタをそのままpush_back()したら、何回か格納した後"EXC_BAD_ACCESS"といわれて止まう現象が起こる。まだ解決方法はわかっていないのだけれど、どうやら以下の二つが原因っぽいので忘れないようにメモ。(そろそろ寝る時間なので)

もとはこんな感じです。

1Hoge *hoge = new Hoge();
2hoge ->foo();
3vec.push_back(*hoge);


たぶん原因は下記二点

要素数が自動的に変更されると書きましたが、vector はある程度の個数分の領域を事前に一括で確保しておき、 それが足りなくなったとき(新たに要素を追加しようとして、足りなかったとき)に、領域を拡張するのです。
http://www.geocities.jp/ky_webid/cpp/library/002.html


vector は、配列の長さを増加させた場合、要素の参照や、要素を指すポインタは、無効になる、と覚えておきましょう。
http://homepage2.nifty.com/well/STL.html


そもそもC++が全然わかっていない。


【追記】解決しました。

サンプルコードの正誤表を見たらあっさり訂正が書いてありました。まぁ、勉強になったからよかったとは思いますが。よく考えたら可変長でメモリを再確保するのならば、参照がずれるのは当然なのかもしれませんね。
1vector <CSample*> hoge;

と、vector の要素を自体をポインタにしてあげればよいとのこと。そうするとこうやって配列に入れることができるみたいです。

1Hoge *hoge = new Hoge();
2hoge ->foo();
3vec.push_back(hoge);