この記事の情報は古いです.
TeXclipで作成した数式の再編集については
を参照してください.
2009年6月21日日曜日
2009年5月30日土曜日
mov(H.264)形式の動画をPowerPointに挿入する方法
PowerPointでスライドに挿入できる(ことになっている)動画は,大雑把には
簡単なことかと思いきや,意外と苦労しているのでメモを残しておきます.プレゼンでは自分のじゃないマシンで発表しないといけなくなったりすることも多いので,特殊なコーデックの追加とかは試していません.
ちなみに環境はWindows Vista / Powerpoint 2007. 動画はCasio EX-F1でSTD画質(640x480,30fps)で撮影したH.264 mov形式のファイルです.
実質的にはmpegの一択ということになります.デフォルトではビットレートが低く(200kbps)画質が実用に耐えないので
$ ffmpeg –i test.mov –b 8192k test.mpeg
という感じでしょうか.
他にいい方法があればご教授いただければ幸いです.
- AVI
- WMV
- MPEG1/2
簡単なことかと思いきや,意外と苦労しているのでメモを残しておきます.プレゼンでは自分のじゃないマシンで発表しないといけなくなったりすることも多いので,特殊なコーデックの追加とかは試していません.
ちなみに環境はWindows Vista / Powerpoint 2007. 動画はCasio EX-F1でSTD画質(640x480,30fps)で撮影したH.264 mov形式のファイルです.
QuickTime Pro 単体ではうまくいかなかった
一番素直な解はQuickTime Pro を購入して.movファイルを.aviに変換することだと思われるので,とりあえずやってみました.PowerPointに挿入するところまではうまくいったのですが,クリックすると動画が黒くなって再生されません.無圧縮のAVIでは再生まで可能ですが,ファイルサイズが大き過ぎる上に,再生時のディスクアクセスによるコマ落ちが激しく,実用には耐えません.Windows Media エンコーダを併用すると一応OK
QuickTime Pro を使って一旦無圧縮のAVIを作成した後で,Windows Media エンコーダを併用すると,PowerPointに挿入可能な高画質なwmvファイルを作成できます.画質にこだわらなければ,aviからの変換にWindowsムービーメーカーを使うこともできます.この方法は作業が二段階になる上に有償のQuickTime Proが必要です.研究室の学生全員に使ってもらうにはちょっと面倒すぎる気がします.Mp4cam2aviではH.264動画を無圧縮aviにすることはできない
mov形式のファイルを無圧縮aviにできそうなフリーソフトとしてMp4cam2aviがあげられますが,今のところH.264の動画のデコードには対応していないようです.FFmpegでの結果
FFmpegを使うと動画の多彩な変換が可能ですが,PowerPointへの挿入はなかなかうまくいきません.結果を以下の表にまとめます.ちなみに,いずれの形式に変換したときもWindows Media Playerでの再生はできています.コマンドライン | 結果 |
$ ffmpeg -i test.mov \ -vcodec wmv1 test.avi | プレビューは正常 再生で暗転 |
$ ffmpeg -i test.mov \ -vcodec wmv2 test.avi | プレビューは正常 再生で暗転 |
$ ffmpeg -i test.mov \ -vcodec msmpeg4 test.wmv | 挿入時から黒いまま |
$ ffmpeg -i test.mov \ -vcodec msmpeg4v2 test.wmv | 挿入時から黒いまま |
$ ffmpeg -i test.mov \ -vcodec wmv1 test.wmv | 挿入時から黒いまま |
$ ffmpeg -i test.mov \ -vcodec wmv2 test.wmv | 挿入時から黒いまま |
$ ffmpeg -i test.mov test.mpeg | 正常 |
$ ffmpeg -i test.mov test.m2v | 正常(音声無し) |
$ ffmpeg –i test.mov –b 8192k test.mpeg
という感じでしょうか.
まとめ
色々やってみましたが,- ベストを尽くすなら
1. QuickTime Pro で無圧縮AVIに変換
(試してないですが,ffmpegでも同等の変換ができるはず?)
2. Windows Media エンコーダでwmvに変換
の2段階 - そこそこでいいなら
$ ffmpeg –i test.mov –b 8192k test.mpeg
他にいい方法があればご教授いただければ幸いです.
2009年5月26日火曜日
Arduinoで簡易オシロスコープ
2013/4/22 ライセンスを修正BSDライセンスとしました
Arduinoで簡単に使える簡易オシロスコープもどきを作ってみました.ちょっとした実験にはなかなか便利なので公開しておきます.
全体図

Arduinoで簡単に使える簡易オシロスコープもどきを作ってみました.ちょっとした実験にはなかなか便利なので公開しておきます.
スクリーンショット
全体図
マウスで周波数などの読み取りも可能
操作法
- [↑][↓] 時間軸の変更
- [space] データ取得の停止/再開
- [s] データをcsv形式で保存
- [マウス操作] 値の読み取り・ドラッグで周波数読み取り
インストール
- 下記のソースの末尾・Arduino用のプログラムの部分をArduinoに書き込んでおく.
- 下記のソースをProcessingにコピーし,シリアルポートの設定とフォントの生成/設定を行う.
- 実行してみる
ソース
// ArduinoScope v1.0.0 // // Note: // 1. please confirm serial port setting // 2. prepare font // 3. Arduino code is attached at the end of this code // Copyright (c) 2009-2013 I. Maruta <ichiro.maruta@gmail.com> // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // 2. Neither the name of the author nor the names of its contributors // may be used to endorse or promote products derived from this software // without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE // ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS // OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF // SUCH DAMAGE. import processing.serial.*; Serial ArduinoPort; // Create object from Serial class int NumOfScopes,NumOfInput=2; int data_span=10000; Strage dfs = new Strage(); Scope[] sp; int fontsize=16; PFont myFont; void setup() { // Serial Port println(Serial.list()); String portName = Serial.list()[0]; // TODO: automatic detection? ArduinoPort = new Serial(this, portName, 38400); ArduinoPort.bufferUntil(10); // Screen size(800, 600); NumOfScopes=2; sp = new Scope[NumOfScopes]; sp[0]= new Scope(0,50,10,width-100,height/2-35,512,-512,1000); sp[1]= new Scope(1,50,height/2+15,width-100,height/2-35,1024,0,1000); myFont = loadFont("Dotum-16.vlw"); textFont(myFont,fontsize); } class Scope{ int input_id; // corresponding input int posx,posy; // screen position of the scope int sizex,sizey; // pixel size of the scope float yu,yl; // range of y is [yl,yu] int tspan; // int ngx,ngy; // number of grids float maxposx,maxposy,minposx,minposy,maxx,minx,maxy,miny; Scope(int did,int px,int py,int sx,int sy,float syu,float syl,int ts){ input_id=did; posx=px; posy=py; sizex=sx; sizey=sy; yu=syu; yl=syl; tspan=ts; ngx=10; ngy=4; } void grid(){ pushStyle(); fill(255,196); stroke(0,0,150); for(float gx=sizex; gx>=0; gx-= (float)sizex/ngx){ line(posx+gx,posy,posx+gx,posy+sizey); textAlign(CENTER,TOP); text((int)map(gx,sizex,0,0,-tspan),posx+gx,posy+sizey+2); } for(float gy=sizey; gy>=0; gy-= (float)sizey/ngy){ line(posx,posy+gy,posx+sizex,posy+gy); textAlign(RIGHT,CENTER); text((int)map(gy,0,sizey,yu,yl),posx,posy+gy); } popStyle(); } int curx,cury; // draw cursor void cur() { // return if mouse cursor is not in this scope if(constrain(mouseX,posx,posx+sizex)!=mouseX || constrain(mouseY,posy,posy+sizey)!=mouseY) return; pushStyle(); // draw cross cursor stroke(255,0,0,196); fill(255,0,0,196); line(mouseX,posy,mouseX,posy+sizey); line(posx,mouseY,posx+sizex,mouseY); // draw measure if mouse is dragged if(mousePressed){ line(curx,posy,curx,posy+sizey); line(posx,cury,posx+sizex,cury); textAlign(RIGHT,BOTTOM); text((int)map(curx,posx,posx+sizex,-tspan,0)+"ms, "+(int)map(cury,posy,posy+sizey,yu,yl),curx,cury); textAlign(LEFT,TOP); text("("+nfp((int)map(mouseX-curx,0,sizex,0,tspan),1)+"ms, "+nfp((int)map(mouseY-cury,0,sizey,0,-(yu-yl)),1)+")\n"+nf(1000/map(mouseX-curx,0,sizex,0,tspan),1,2)+"Hz\n"+nf(TWO_PI*1000/map(mouseX-curx,0,sizex,0,tspan),1,2)+"rad/sec",mouseX,mouseY+2); } else{ curx=mouseX; cury=mouseY; textAlign(RIGHT,BOTTOM); text((int)map(curx,posx,posx+sizex,-tspan,0)+"ms, "+(int)map(cury,posy,posy+sizey,yu,yl),curx,cury); } popStyle(); } // draw min&max tick void minmax(){ pushStyle(); fill(255,128); stroke(0,0,100); textAlign(RIGHT,CENTER); line(posx,maxposy,posx+sizex,maxposy); text((int)maxy,posx,maxposy); line(posx,minposy,posx+sizex,minposy); text((int)miny,posx,minposy); textAlign(LEFT,CENTER); textAlign(CENTER,TOP); text("max",maxposx,maxposy); textAlign(CENTER,BOTTOM); text("min",minposx,minposy+20); popStyle(); } // draw scope void Plot(){ float sx,sy,ex,ey; int nof=0; DataFrame df_last = dfs.get(0); maxy=-1e10; // -inf miny=1e10; // +inf // draw background (for transparency) pushStyle(); noStroke(); fill(0,0,64,64); rect(posx,posy,sizex,sizey); popStyle(); // draw data plot pushStyle(); stroke(0,255,0); smooth(); strokeWeight(1); for(int idx=0;(dfs.get(idx).t>max(df_last.t-tspan,0)) && -idx<data_span;idx--){ DataFrame df_new=dfs.get(idx); DataFrame df_old=dfs.get(idx-1); sx=(float) map(df_new.t, df_last.t, df_last.t - tspan, posx+sizex,posx); ex=(float) map(df_old.t, df_last.t, df_last.t - tspan, posx+sizex,posx); sy=(float) map((float)df_new.v[input_id],(float) yu,(float) yl,(float) posy,(float) posy+sizey ); ey=(float) map((float)df_old.v[input_id],(float) yu,(float) yl,(float) posy,(float) posy+sizey ); if(ex<posx){ ey+=(sy-ey)*(posx-ex)/(sx-ex); ex=posx; } line(sx,sy,ex,ey); maxy=max(maxy,df_new.v[input_id]); if(maxy==df_new.v[input_id]){ maxposx=sx; maxposy=sy; } miny=min(miny,df_new.v[input_id]); if(miny==df_new.v[input_id]){ minposx=sx; minposy=sy; } nof++; } popStyle(); // minmax(); // draw current value of input pushStyle(); textAlign(LEFT,CENTER); stroke(0,0,64); fill(0,255,0,196); text(df_last.v[input_id],posx+sizex,map(df_last.v[input_id], yu, yl, posy, posy+sizey )); popStyle(); grid(); cur(); } } void draw() { background(0); for(int i=0;i<NumOfScopes;i++){ sp[i].Plot(); } } // input data buffer class // (now using ring buffer) class Strage{ int cur; DataFrame[] DataFrames; Strage(){ cur=0; DataFrames=new DataFrame[data_span]; for(int idx=0;idx<data_span;idx++){ int ret_v[] = new int[NumOfInput]; DataFrames[idx] = new DataFrame(0,ret_v); } } void push(DataFrame d){ cur = ((cur+1) %data_span); DataFrames[cur]=d; } DataFrame get(int idx) { int num=(cur+idx); for(; num<0; num+= data_span); return((DataFrame) DataFrames[num]); } void save() { String savePath = selectOutput(); // Opens file chooser if (savePath == null) { // If a file was not selected println("No output file was selected..."); }else{ PrintWriter output; output = createWriter(savePath); DataFrame df_last = this.get(0); for(int idx=0;-idx<data_span;idx--){ if(this.get(idx).t==0) break; output.print(this.get(idx).t-df_last.t); for(int k=0;k<NumOfInput;k++){ output.print(","+this.get(idx).v[k]); } output.println(""); } output.flush(); output.close(); } } } class DataFrame{ int t; int[] v; DataFrame(int st, int[] sv){ t=st; v=sv.clone(); } } boolean isactive=true; // buffering data from serial port void serialEvent(Serial myPort) { int[] vals=new int[NumOfInput]; int timestamp; int[] splitdata; if( myPort.available() > 0) { String datline=myPort.readString(); splitdata=parseInt(datline.split(",")); if((splitdata.length==NumOfInput+2)){ timestamp=splitdata[0]; for(int idx=0;idx<NumOfInput;idx++){ vals[idx]=splitdata[idx+1]; } if(isactive){ if((timestamp-dfs.get(0).t)<0){ dfs.cur--; } if((timestamp-dfs.get(0).t) > ((float)sp[0].tspan / sp[0].sizex/2.0) ){ dfs.push( new DataFrame(timestamp,vals)); } } } } } // keyboard user interface void keyPressed(){ switch(key){ // activate/deactivate scope update case ' ': isactive=!isactive; break; // save record case 's': dfs.save(); break; case CODED: switch(keyCode){ // Increse time span case UP: for(int i=0;i<NumOfScopes;i++){ sp[i].tspan*=2; } break; // Decrease time span case DOWN: for(int i=0;i<NumOfScopes;i++){ sp[i].tspan/=2; } break; } break; } } /* Arduino code void setup() { Serial.begin(38400); } void loop() { Serial.print(millis()); Serial.print(","); Serial.print(analogRead(0)); Serial.print(","); Serial.print(analogRead(1)); Serial.println(","); } */
2009年5月22日金曜日
SyntaxHighlighter2でMATLABソースを表示 in Blogger
以前SyntaxHighlighterをMATLAB対応にしました.その後,ファイルを置いてあるサーバーの更新があったり,SyntaxHighlighterがバージョン2になったりで使えない状態で放置していたので,改めて作りなおしてみました.
のように追加するといいようです.config.bloggerModeの設定がないと改行の位置にBRタグの出来そこないが出現します.
上の設定例はこのホストを使う設定にしてます.
BloggerでSyntaxHighlighter2を使う
まず最初にBloggerでSyntaxHighlighter2をつかうときの設定ですが,テンプレートに<!--ここから --> <script src='http://alexgorbatchev.com/pub/sh/2.0.278/scripts/shCore.js' type='text/javascript'/> <script src='http://alexgorbatchev.com/pub/sh/2.0.278/scripts/shBrushPlain.js' type='text/javascript' /> <script src='http://alexgorbatchev.com/pub/sh/2.0.278/scripts/shBrushXml.js' type='text/javascript' /> <script src='http://alexgorbatchev.com/pub/sh/2.0.278/scripts/shBrushCss.js' type='text/javascript' /> <script src='http://alexgorbatchev.com/pub/sh/2.0.278/scripts/shBrushJScript.js' type='text/javascript' /> <script src='http://maru.bonyari.jp/storage/shBrushMatlab.js' type='text/javascript'/> <!--ここまで --> </head> ... <!-- end outer-wrapper --> <!--ここから --> <script type='text/javascript'> //<![CDATA[ SyntaxHighlighter.config.bloggerMode = true; SyntaxHighlighter.all(); //]]> </script> <!--ここまで -->
のように追加するといいようです.config.bloggerModeの設定がないと改行の位置にBRタグの出来そこないが出現します.
MATLABのソースをSyntaxHighlighterで成形する
【使い方】
上記のファイルを通常の”shBrush*.js”と同じように読み込んで,class=”brush:matlab”で使えます.上のサーバーに置いてあるのを読み込んでも構いませんが,無保証自己責任でお願いします.ちなみにSyntaxHighlighter本体も本家でホスティングされているようですね.(リンク)上の設定例はこのホストを使う設定にしてます.
2009年5月18日月曜日
MATLABで並列計算(PSO)
素のMATLABは並列計算に弱いようで,最近のデュアルコアのPCだと,プロセッサ使用量が50%で頭打ちします.
ただ,最近学校の MATLAB ライセンスに Parallel Computing Toolbox が加わって一部関数が置き換えられたためか,単にバージョンアップの恩恵なのかは知りませんが,一部の計算ルーチンがマルチコア用にコンパイルされているらしく,計算によっては50%を超えるプロセッサ使用率を見ることもできるようになりました.
でも依然として,大半の処理は片方のコアのみで処理されるようです.
本来は並列計算できる部分は処理系が自動的に判別して最適に処理してくれるのが理想なんですが,なかなか実現されないですね.また,最近はコア1つ当たりの性能向上は収束気味で,今後はコアの数が増える方向にPCは進化するようなので,今後MATLABでPCの進化の恩恵を享受するためには,並列計算のスキルを身につけておく必要がありそうです.
MATLAB で Parallel Computing Toolbox が使える場合,単一マシンで並列処理をするのはとても簡単で
とやれば並列に処理されます.matlabpool の後の数字は生成されるスレッド数です.
結構並列化のオーバーヘッドがあるようで,単位処理の計算量があまりに小さい場合,かえって遅くなることもあるようです.結果が芳しくないときはプロファイラでチェックしてみるべきですね.
Particle Swarm Optimization (PSO) なんかは並列計算の恩恵を最大限に受けられるアルゴリズムなので,目的関数の評価に時間がかかる問題であれば,処理速度がほぼコア数倍になります.(といってもまだデュアルコアでしか試してませんが・・・)
もうちょっと手間をかけると複数のマシンをつないでクラスタリングとかもできるようなので,人がいない夜中とかに実験室のマシンを束ねて試してみようかな〜
ただ,最近学校の MATLAB ライセンスに Parallel Computing Toolbox が加わって一部関数が置き換えられたためか,単にバージョンアップの恩恵なのかは知りませんが,一部の計算ルーチンがマルチコア用にコンパイルされているらしく,計算によっては50%を超えるプロセッサ使用率を見ることもできるようになりました.
でも依然として,大半の処理は片方のコアのみで処理されるようです.
本来は並列計算できる部分は処理系が自動的に判別して最適に処理してくれるのが理想なんですが,なかなか実現されないですね.また,最近はコア1つ当たりの性能向上は収束気味で,今後はコアの数が増える方向にPCは進化するようなので,今後MATLABでPCの進化の恩恵を享受するためには,並列計算のスキルを身につけておく必要がありそうです.
MATLAB で Parallel Computing Toolbox が使える場合,単一マシンで並列処理をするのはとても簡単で
matlabpool 2 %デュアルコアの場合 parfor idx=1:100 % 並列化する処理 end matlabpool close
とやれば並列に処理されます.matlabpool の後の数字は生成されるスレッド数です.
結構並列化のオーバーヘッドがあるようで,単位処理の計算量があまりに小さい場合,かえって遅くなることもあるようです.結果が芳しくないときはプロファイラでチェックしてみるべきですね.
Particle Swarm Optimization (PSO) なんかは並列計算の恩恵を最大限に受けられるアルゴリズムなので,目的関数の評価に時間がかかる問題であれば,処理速度がほぼコア数倍になります.(といってもまだデュアルコアでしか試してませんが・・・)
もうちょっと手間をかけると複数のマシンをつないでクラスタリングとかもできるようなので,人がいない夜中とかに実験室のマシンを束ねて試してみようかな〜
・・・・と思ったらクラスタリングには MATLAB Distributed Computing Server っていう別製品が必要なようですね.
また,Parallel Computing Toolbox ではスレッドの数も4つまでに制限されてるようです.
つまり現状ではクアッドコアのXeon W3570以上のCPUを使っても性能向上は期待できないということかな?
値段を考えると2.66GHzのXeon W3520か,近々更新される見込みなCore i7あたりが計算用マシンのCPUとしてはベストになるのだろうか・・・
2009年4月15日水曜日
通販できる海外のホビーロボット用部品店
ネットを使うと海外からも簡単に部品が買えて良いですね.
最近目を付けてる海外サイトをメモしておきます.
最近目を付けてる海外サイトをメモしておきます.
- Gravitech
Arduino nanoを売ってます.僕が注文したときは12日で届きました.ちなみに送料は$5.85.スイッチサイエンスさんから買った方が速いし,値段もトータルでは同じくらいのはず. - Dimension Engineering
モータードライバー,センサーなど.僕が購入したときはUSPS First Classで送料$2.5,一週間くらいで着きました.急ぐのならメカロボショップさんでも購入できます. - RobotShop
ロボット材料,モジュールなどなど.ルンバをbluetooth接続するキットとかを売っているのが気になる.日本からも通販できるようだけど,重量物は送料が怖い・・・ - Pololu Robotics and Electronics
モータードライバ,センサー等々.試したことはないけど,日本からも購入可能なはずです.配送はUSPS First Classのようなので,一週間そこそこで着くはず.送料は基板程度なら$2.5だと思います.急ぐのならメカロボショップさんでも購入できます. - Endurance
R/Cラジコンの部品.PCTx (パソコンをラジコンの送信機にするデバイス)が売ってるのでメモ. - The Robot Marketplace
なんか凶悪そうなモーターが売ってるのでメモ.パワー系ロボコン用ですね - SuperDroid Robots
ロボット関連いろいろ.オムニホイールを扱っているのでメモ. - SparkFun
Arduino関連が超有名.大抵のものはスイッチサイエンスさんで扱っているので,そちらから購入した方が良いでしょう.最近は日本橋でもSparkFun製品を結構見かけますね.
登録:
投稿 (Atom)