面白いもの!!

中谷です。初投稿です。

今回は面白いものの紹介をします。

先生がCHI2011勉強会というものに出席して見つけた研究です。

CHI2011とはとても有名なhuman-computer interactionの国際会議です。つまり、人間と機械とを相互作用させる研究に関しての発表を、世界中から集まって行うというものです。

そして、その会議で発表された面白い作品がこちらっ↓

iRiS: Multi-User Interaction on Media Facades through Live Video on Mobile Devices

<img class="alignnone size-full wp-image-938" Zumal die schnell zu casino online erklarenden casino Regeln einfach und verstandlich casino online sind und die Spannung in spelautomater pa natet gratis Online Casinos sich sehr gut darstellen lasst. kasino src=”http://unitedfield.net/wordpress/wp-content/uploads/2011/07/スクリーンショット(2011-07-10-16.04.28).png” alt=”” width=”642″ height=”358″ />

ドイツのmunich大学の研究です。目の前にある建物の正面にある光を自分の手元にあるケータイのタッチパネルで操作できるというもの。色を塗ったり、パズルをしたりといった操作が出来ます。2人以上での操作も可能です。

 

↑先ほどの動画の最初の方に一瞬、オペラハウスが出て来ました。以前研究会でも私が個人的に紹介しましたが、5月から6月にかけてシドニーで行われていたVivid Sydneyからの画像です。

オペラハウスの複雑な形を上手く利用した作品です。見てるだけでワクワクしちゃいます!

 

 

日本ロマンチスト協会

竹内です。

少し前のことになるのですが、夜景星座とmailTravellerを展示中に日本ロマンチスト協会の方からスカウトをいただきました。ちょっとあやしい感じもしますが、素晴らしいクリエイターの方々がたくさんいらっしゃいます。
私、竹内は中西研ではロマンチストの一員としてロマンスの宣教活動して行く所存でおります。

われこそはロマンチストという方はぜひ中西研を履修してください。
ちなみに新規履修希望の方は研究会シラバスをご覧の上、SAの竹内までご連絡ください。
お待ちしております。
s08475yt[at]sfc.keio.ac.jp

ProcessingでVideoChat(DatagramSocket)

中西研のB4関口です。

今回もProcessingネタになってしまうのですが、今回はProcessingを使ったビデオチャットを実装したいと思います。
方針としては、画像をバイト配列に変換して、データグラム通信で別のPCへ送ってあげる感じにします。今回はわかりやすさのために、スレッドとか使いません。

さくっとまずはソースを乗せてしまいます。

[java]
import processing.video.*;
import java.awt.image.*;
import java.awt.*;
import javax.imageio.*;
import java.net.DatagramPacket;

InetSocketAddress remoteAddress;
DatagramPacket sendPacket;
DatagramPacket receivePacket;
DatagramSocket receiveSocket;

Capture capture;

//送信するバイト配列
byte[] sendBytes;
//受信するバイト配列を格納する箱
byte[] receivedBytes = new byte[300000];

void setup() {
size(600,480);

capture = new Capture(this,640,480);

try {
//受信ポート
receiveSocket = new DatagramSocket(5101);
}
catch(SocketException e) {
}
//受信用パケット
receivePacket = new DatagramPacket(receivedBytes,receivedBytes.length);
//送り先
remoteAddress = new InetSocketAddress(“localhost”,5100);
try{
receiveSocket.setSoTimeout(1000);
}catch(SocketException e){
}
}

void draw() {
capture.read();
/* ここから受信 */

println(receiveSocket.isBound());
try {
receiveSocket.receive(receivePacket);
}
catch(IOException e) {
}

Image awtImage = Toolkit.getDefaultToolkit().createImage(receivedBytes);
PImage receiveImage = loadImageMT(awtImage);
/* 受信終了 */

/* ここから送信 */
//バッファーイメージに変換
BufferedImage bfImage = (BufferedImage)(capture.getImage());
//ストリームの準備
ByteArrayOutputStream bos = new ByteArrayOutputStream();
BufferedOutputStream os = new BufferedOutputStream(bos);

try {
bfImage.flush();
ImageIO.write(bfImage,”jpg”,os);
os.flush();
os.close();
}
catch(IOException e) {
}
sendBytes = bos.toByteArray();
try {
sendPacket = new DatagramPacket(sendBytes, sendBytes.length, remoteAddress);
try{
new DatagramSocket().send(sendPacket);
} catch(IOException e){
}
println(“bufferImageSended:”+sendBytes.length+” bytes #2″);
}
catch(SocketException e) {
}
/* 送信終了 */

//描画
image(receiveImage,0,0);
image(capture,width-width/4,height-height/4,capture.width/4,capture.height/4);
}

[/java]

横着して、catchではなにもしません。

setup()

具体的にsetup()内について見ていきます。
[java]
receiveSocket = new DatagramSocket(5101);
receivePacket = new DatagramPacket(buf,buf.length);
[/java]
ここで、受信ソケットのポートの設定をします(適当に5101番)。今回は、localhost内では2つアプリを起動することになるのですが、受信と送信ポートを互い違いにしないと動かないので注意です。(別のIPが振られてるところに飛ばすなら、全く同じアプリを起動させれば通信するはず)
その下で受信したデータをどこに格納するかを指定します。予め用意しておいたbyte[]を渡すと、受信するたびにそこに値が入っていきます。

[java]
remoteAddress = new InetSocketAddress(“localhost”,5100);
[/java]
ここで、送信先とポートを設定します。今回はlocalhostですが、普通にIPでも大丈夫です。

[java]
receiveSocket.setSoTimeout(1000);
[/java]
最後に受信のタイムアウトを設定します。今回は1000ミリ秒=1秒をタイムアウト時間に設定しました。これを指定してあげないと、受信データが来ない場合に永遠に待ち続けてしまうので、適当な値を指定してあげましょう。

draw()

次に描画部分です。まずは受信部。
[java]
try {
receiveSocket.receive(receivePacket);
}
catch(IOException e) {
}
Image awtImage = Toolkit.getDefaultToolkit().createImage(receivedBytes);
PImage receiveImage = loadImageMT(awtImage);
[/java]
凄く簡単ですね。receiveメソッドを呼んであげれば、予め設定しておいたbyte[]にバイト配列が格納されます。ので、それをまずImageにしてあげて、さらにそれをPImageに変換してます。

次は送信部です。
[java]
//バッファーイメージに変換
BufferedImage bfImage = (BufferedImage)(capture.getImage());
//ストリームの準備
ByteArrayOutputStream bos = new ByteArrayOutputStream();
BufferedOutputStream os = new BufferedOutputStream(bos);
[/java]
まず、キャプチャ画像をBufferedImageにしてあげて、ストリームの準備をします。
[java]
try {
bfImage.flush();
ImageIO.write(bfImage,”jpg”,os);
os.flush();
os.close();
}
catch(IOException e) {
}
sendBytes = bos.toByteArray();
try {
sendPacket = new DatagramPacket(sendBytes, sendBytes.length, remoteAddress);
try{
new DatagramSocket().send(sendPacket);
} catch(IOException e){
}
println(“bufferImageSended:”+sendBytes.length+” bytes #2″);
}
catch(SocketException e) {
}
[/java]

次にImageIOを使ってjpgに変換します。そしてストリームに流し込んで、byteArrayにしてあげます。
DatagramPacketにbyte配列と宛先情報を渡して、それをDatagramSocket.send()すると送られます。
わぁ、簡単。

という感じで、Processingで簡単なビデオチャットが出来ます。


“Visual Note Taking”

こんにちは石井です。

「シンキングプロセスデザイン」で勧められていた、紙に思考の過程を書きつつ考える【ビジュアルシンキング】に関連して面白いものを見つけたので紹介します。

“Visual Note Taking / Sketchnotes ” presentation by Eva-Lotta Lamm (from slideshare)

上のリンク先はいろいろな人のプレゼンテーション用スライドが公開されている「slideshare」というサイトにたまたまあった、WebデザイナーのEva-Lotta Lammさんのスライドです。彼女はここで”Visual Note Taking”の面白さについて沢山の例を交えつつ紹介しています。

sketch by Da vincisketch

(Visual Note Takingの例:左=レオナルド・ダ・ダヴィンチによるスケッチ、右=Eva-Lottaさんによるスケッチ)

残念ながらスライドにはメモやスピーチは含まれていないので何となくの雰囲気を感じとるしかできないのですが、まず”Visual Note Taking”とは何かということから始まり、かの有名なダヴィンチのスケッチから最近のスケッチまで様々なノートを紹介しています。どのノートも一癖ある面白いものばかりでそのクオリティには驚かされるばかりです。

Visual Note Takingとはその名のとおり視覚的で直感的に捉えられるノートのとり方なのですが、このプレゼンテーションでは次に具体的なやり方について掲載されています。情報に階層をつけたり同じ要素をブロックでまとめたりするほか、タイムラインの流れに従って書いて情報を整理する方法などを紹介しています。さらに「楽しいのが一番!」と記す彼女は楽しいノートを作るために色をつけたりフレームや矢印の形を変え、文字のフォントまで変えているそうです。

中で紹介されるノートがあまりにも完成度が高いので、思考の過程としてのスケッチではなく思考の結果としてのスケッチになっている気もしますが、彼女のように楽しく工夫して思考や情報を視覚的にアウトプットできれば、それを後から見返すのも楽しくなりそうですね。

このような”Visual Note Taking”のやり方を高校時代にしていたら、毎回寝ていた古典や化学も楽しく勉強できたのかもしれません。
※スケッチの写真をもっと見てみたい方は、Flickrで「Sketchnote」などと検索してみるといろいろ出てくると思います。

夜景星座 その2

こんにちは。秋学期から新研究会に新規参加させていただいております井上と申します。
片倉さん不調のため、一週間の間が空いてしまいましたがご了承を。

前の記事で紹介された「夜景星座」アプリですが今回、私がスプラッシュ画面等々のデザインをさせて頂きました。
こちらです。

アプリの画面を描くのが初めて&パースを取るのが苦手(!)
なので拙い部分がありますが、スタイリッシュな感じは出たかなと思います。
イラストが趣味だったので、こういう所で多少なりお手伝いが出来たのは光栄でした。
次回は大森さんか、同じく新規の石井さんのどちらかが担当です。宜しくお願いいたします。

夜景星座

こんにちは、竹内です。

いま中西研のシンボル的存在の西牟田先生(現・藤田研)のアイデアである夜景星座というアプリケーションの実装を行っています。

先人達が光の点に関係性を見いだし、人や動物に例え、ストーリーを作っていったように街の光の点で思い思いの形を描く。それが夜景星座です。「夜景星座」という名前がそもそも素敵ですね。さすがです。

画像が夜景でないだけに、凄まじくアプリケーションの雰囲気が伝わらないと思うのですが、実装が完了したら画像を更新します。

技術的にはそう真新しいことも難しいこともやっていなく、純粋に見せ方が重要になるアプリケーションなので、作っている過程で非常に勉強になります。

リリースもする予定なので乞うご期待!

次は中西研のエース長野くんがブログを書いてくれるのでそれもお楽しみに!

コマだれ?を作りました

中西研の北原です。

先日SFCの秋学期が始まるタイミングで コマだれ? というサービスを作りました。これは、SFCの各コマの授業に今誰が興味を持っているかということを twitter を使って共有する仕組みになっており、UI を iphone に最適化したものです。
“コマだれ?を作りました” の続きを読む

Laser Tag 2.0 でのSnowLeopardの問題を解決しました

中西研の北原です。

Graffiti Research Lab » L.A.S.E.R. Tag で紹介されているLaser Tagというレーザポインタでプロジェクターが投影している先に落書きが出来るアプリケーションがあります。しかし、このLaserTagが作られてからSnowLeopardにバージョンアップしたり、LaserTagが依存しているOpenFrameworksが大幅に変わるなどでSnowLeopardでカメラを使った最にクラッシュしてしまう問題がありました。

Theodore Watson – Laser Tag 2.0 – How To – Download and Source Code のコメントに紹介されていたSnowLeopardの修正版の挙動も本家と少し違うように感じられたので修正したものを

http://web.sfc.keio.ac.jp/~soh335/download/LaserTag2002SnowLeopard.zip

にアップロードしました。

変更点としては、OpenFrameworksのバージョン、0.61を利用しつつ同胞されてるOpenCVやXMLを扱うアドオンがもとのLaserTagの時と大分変わってしまっているので、0.61で動くように昔のアドオンを変更して利用するというふうにしました。

第一回XD対抗フットサル大会

中西研の関口です。

6月20日に、XDの研究室(+熊坂研)が集まり、フットサル大会を企画、開催しました。
今回は、中西研の他に、脇田研・山中研・坂井研・熊坂研の4チームが参加して下さり、非常に楽しい時間を過ごすことができました。本当にありがとうございます。

さてさて、そのフットサルですが、我が中西研は、日頃の運動不足を露呈してしまいました。
先生

フットサル

総当たりで試合をした結果、優勝は坂井研でした。商品はありませんが、おめでとうございます。

XD問わず、SFCの研究室の垣根を超えたこういった活動を今後もやっていきたいですね。

次は、フットサルやバスケットボールなどもしていきたいと思います。
集合

(今回の写真は、脇田研の方々に頂きました。ありがとう!)

Processingで射影変換(ホモグラフィ)

中西研の関口です。4年生になりました。気づいたら22歳。最近、疲れが抜けません。

さて、L.A.S.E.R. Tagをいじる機会があり、現在、P5用に移植してる真っ最中です。その中で重要な機能であるキャリブレーションの実装について今回はメモ程度に残しておきます。

L.A.S.E.R. Tagでは、読み込んだカメラ画像に対しキャリブレーションを施して正確にポインタと投影面が重なるように設定が可能となっています。これによって、斜めからカメラで落書き面を捉えても、正確に落書きすることが可能となっているんですね。

今回は、これとおんなじようなことを、Processingでやろうというわけです。

多分、L.A.S.E.R. TagではOpenCVを使ってキャリブレーションしてる気がするのですが、ProcessingにはOpenCVのライブラリがあるのですが、キャリブレーションする機能は使えないようだったので、結局頑張って計算することにしました。

そもそも、こういった平面の変換は射影変換と呼ばれていて、任意の4点が定まれば、一意にパラメータが定めることができます。(詳しくは、http://www.teu.ac.jp/clab/kondo/research/cadcgtext/Chap5/Chap503.html

ということで、キャプチャした画像から任意の4点を選択し、そこからパラメータを計算して表示すればなんとなくOKっぽいです。パラメータの計算は連立方程式をとけば出てきます。
homographyMatrix
ただ、あんまりProcessingにないライブラリやらを使いたくなかったので、今回はMatrixを使わずに計算することにしました。この際、AS3で同じことをしている人を発見したので、大いにパクリました。というかむしろ、AS3をP5に移植したといって過言ではないです。(参考:Homography | HIDIHO!

ということで、ソースコードです。

[java]
import JMyron.*;
JMyron jmyron;

PImage capture;
PImage convert;
boolean dragged = false;
int selector = 0;
final static int CAP_WIDTH = 320;
final static int CAP_HEIGHT = 240;
Point[] points = {
  new Point(),new Point(),new Point(),new Point()};

void setup(){
  size(CAP_WIDTH*3,CAP_HEIGHT);
  jmyron = new JMyron();
  jmyron.start(CAP_WIDTH,CAP_HEIGHT);  
  capture = new PImage(CAP_WIDTH,CAP_HEIGHT);
  convert = new PImage(CAP_WIDTH,CAP_HEIGHT);
  points[0].setPoint(0,0);
  points[1].setPoint(320,0);
  points[2].setPoint(320,240);
  points[3].setPoint(0,240);
}
void mousePressed(){
  if(dragged == false){
    for(int i=0; i < 4; i++){
      if(points[i].x -10 < mouseX && points[i].x + 10>mouseX){
        if(points[i].y -10 < mouseY && points[i].y + 10>mouseY){
          dragged = true;
          selector = i;
        }
      } 
    } 
  }
}
void mouseDragged(){
  if(dragged){
    if(mouseX > 0 && mouseX < CAP_WIDTH){
      points[selector].setPoint(mouseX,points[selector].y);
    }
    if(mouseY > 0 && mouseY < CAP_HEIGHT){
      points[selector].setPoint(points[selector].x,mouseY);

    }
  }
}
void mouseReleased(){
  dragged = false; 
}
void draw(){

  jmyron.update();
  int[] jImage = jmyron.image();
  capture.loadPixels();
  for(int i=0;i < capture.width*capture.height; i++){
    capture.pixels[i] = jImage[i]; 
  }
  capture.updatePixels();
  image(capture,0,0);
  ellipseMode(CENTER);
  noFill();
  strokeWeight(1);
  for(int i=0; i < 4; i++){
    stroke(255*(i%2),64*(i%4),0);

    ellipse(points[i].x,points[i].y,10,10);
    line(points[i%4].x,points[i%4].y,points[(i+1)%4].x,points[(i+1)%4].y);
  }
  convert = setTransform(capture,CAP_WIDTH,CAP_HEIGHT,points[0],points[1],points[2],points[3]);
  image(convert,CAP_WIDTH,0);

}
PImage setTransform(PImage pimg,
int destWidth, int destHeight,
Point p0, Point p1,
Point p2, Point p3){
  if ( p0 == null || p1 == null || p2 == null || p3 == null ) return null;
  float[] system = new float[8];
  system = getSystem(p0,p1,p2,p3);
  PImage target = new PImage(destWidth,destHeight);

  int i,j,x,y,u,v;
  Point p;

  for(i = 0; i

processingのcaptureを使えばいいんですが、ちょっと都合上JMyronを使わせて頂きました。と言っても、Captureでも特に問題はありません。その場合は、captureをPImageからCaptureに変えればすんなり動く気がします。

実行結果はこんな感じです。

homography

このように、ポスターが長方形ぴったりに収まるように表示されるようになりました。

これで、カメラの位置に関係なく色々することができますね!

それでわ。