hirax.net::inside out

最新記事(inside out)へ  |   年と月を指定して記事を読む(クリック!)

2017年2月 を読む << 2017年3月 を読む >> 2017年4月 を読む

2017-03-19[n年前へ]

天下一品がもしも太麺だったら…(汁の粘度的に)女性人気が低いラーメン店になっていたに違いない!?  share on Tumblr 

 天下一品の麺は、ドロドロの粘度高いスープにストレートな細麺が使っている。今日は、もしも天下一品が太麺だったらづなるか!?を考えてみた。

 天下一品の高粘度なスープは、一般的な醤油ラーメンに対して2桁程度は粘度が高く、おそらく10の3乗センチポワズくらいだと思う。ということは、箸で持ち上げられた麺に絡んだ天下一品のスープは、さらさら低粘度な醤油ラーメンと比べて2桁程度も強く重力に逆らう抵抗力を受ける…ということになる。

 麺に絡んだスープが、重力に対抗するより強い力を受けるということは、つまり、重力に逆らいつつ高い場所まで持ち上げられてしまうということである。そして、もしも、麺からスープが落ちることがあれば、高い場所から落ちたスープ滴が大きな運動エネルギーをスープ液面に叩きつけるということであり、悲惨な飛散を生じさせること間違いない。この「高いところから汁が滴ることによる飛散」は、粘度が高い麺類が持つ宿命である。高粘度スープを誇る天下一品は、そんな運命を持つ。

 ところで、麺類から落ちる汁というものは、たいてい麺の先端から滴ると相場が決まっている。その理由は単純で、「表面積を最小にしたがる」スープの表面張力により、曲率が大きな箇所からしかスープは滴り落ちないからだ。そして「表面積を最小にしたがる」ということから、(体積と表面積で連立方程式を組めばわかるように)円筒形状に沿って吐出される液体は、円筒形状の半径をRとすると半径3/2 Rの球状になって滴り落ちることになる。つまり、麺に沿って(麺の端部から)滴り落ちるスープは、麺の太さに比例する大きさで下に落下していく…ということになる。つまり、粘度が高く・麺の径が太い食物は、「高い場所から・大きな液滴を落とすので、悲劇的な飛散を引き起こす」ということである。

 天下一品の場合は、スープの粘度は高いがその麺は細い。それはつまり(麺形状の効果はとりあえず無視すれば)天下一品ラーメンは、高いところからスープ液滴が落ちやすいけれど(麺の太さにしたがって)液滴径が小さいがゆえに、まだスープ飛散はマシなはず…ということになる。

 というわけで、天下一品がもしも太麺だったら、汁の粘度的にスープ液滴が飛散することよる汚れを気にしがちな女性には、人気が低いラーメン店になっていたに違いない。とはいえ、天下一品ラーメンの麺が細いからといって、女性人気が低くないかどうかは…よくわからないのだけれど…。

天下一品がもしも太麺だったら…(汁の粘度的に)女子人気が低かったに違いない!?天下一品がもしも太麺だったら…(汁の粘度的に)女子人気が低かったに違いない!?






2017-03-06[n年前へ]

父が書いた「はるか」な物語  share on Tumblr 

 『超巨大ブラックホールに迫る―「はるか」が創った3万㎞の瞳』が届いた。本のタイトルそのままでは内容が伝わりにくいような気がする電波天文観測衛星「はるか(MUSES-B)」に関する20年以上の物語…ひとことで言ってしまえば、父が書いた「はるか」な物語。

 客観的な目で読んだ人が、どんな感想を持つかは全くわからないけれど、手にとって何度もたくさん読まれたなら、少し嬉しい気がする。

 それにしても、父の名が付けられた小惑星が十年近く前から空に浮かんでいた…なんて知らなかった。

久(ひさし、10224 Hisashi)は小惑星帯に位置する小惑星。埼玉県のアマチュア天文家、佐藤直人が1997年に秩父市で発見した。JAXA宇宙教育センター長や電波天文衛星はるかのプロジェクトマネージャーなどを勤めた平林久にちなんで、2009年4月に命名された。

2017-03-05[n年前へ]

現実のリアルタイム風景と、そこから眺めた好きな時間・瞬間を合成してVR的に眺めてみよう!?  share on Tumblr 

 先日、周囲全方向を撮影することができるRicoh Theta Sを使い、24時間にわたり11段階の多段露出撮影画像からリトル・プラネット(とても小さな星を上空から撮影したような)風動画を作ってみました(Ricoh Theta S で24時間のHDR(多段露出)撮影をして遊んでみる!?)。けれど、そんな風に景色を離れたところから第三者的・客観的に眺めるのではなくて、その場に立って一人称的に景色を眺めたくなりました。そこで、合成した高画質4K動画をYoutubeに(360度映像だというタグを付けて)アップロードしてみました。

 こうすることで、スマホからYoutubeアプリケーションでアクセスし、VR用レンズセットを取り付けて眺めれば、あたかもこの場所に立ち・数百倍近く速く時間が流れる中で、夜空や太陽の影を眺めることができます。

 そして一番面白いのは、24時間の撮影を行った場所に立って、目の前にあるリアルタイムな実際の景色を眺めつつ、「東の空に昇る太陽や夜星や夕焼けや」…24時間の中にある美しい瞬間や一番好きな時間を、スマホに覗いて自由自在にVR合成しながら眺めてみると…とても不思議で面白い気持ちになってきます。

 今日は、24時間にわたる、周囲全ての4πステラジアンの全天周風景を、11段階多段露出のハイダイナミックレンジ撮影をして、その映像を4K映像に変換して眺めてみました。

現実のリアルタイム風景と、そこから眺めた好きな時間・瞬間を合成してVR的に眺めてみよう!?現実のリアルタイム風景と、そこから眺めた好きな時間・瞬間を合成してVR的に眺めてみよう!?






2017-02-26[n年前へ]

Ricoh Theta S で24時間のHDR(多段露出)撮影をして遊んでみる!?  share on Tumblr 

 Ricoh Theta Sを制御するPython 3.xコードを書いた (「Ricoh Theta S で2017年旧暦1月満月の夜を撮ってみる」)ので、Theta Sを載せた三脚を高く立て、24時間を少し超えるくらいの時間にわたり、11段階の露出時間での撮影を交互に続けてみました。ちなみに、撮影に使ったPython コードは下記になります。

import osc
import theta
import time
thetas = RicohThetaS()
thetas.setCaptureMode( 'image' )
thetas.setOption("exposureProgram", 1 )
thetas.setOption("ISO", "100")
thetas.setOption("whiteBalance", "daylight")
shutterSpeeds1 = [0.00015625, 0.0005,
    0.002,0.008,0.03333333,0.125,0.5,
    2,8,30,60]
for i in range(400):
    for shutterSpeed in shutterSpeeds1:
      thetas.setOption("shutterSpeed", shutterSpeed)  
      time.sleep(1)
      response = thetas.takePicture()
      thetas.waitForProcessing(response['id'])
      time.sleep(1)
      thetas.getLatestImage()
      time.sleep(1)
thetas.closeSession()

 こうして、 1/6400秒~60秒までの11段階にわたる露出時間で撮影した画像群を、下記のPythonコードでHDR(ハイダイナミックレンジ)合成します。

import cv2
import numpy as np
iniID = 11006 # fileName
for i in range(400):
    files=["hoge"+"R00"+str(iniID+j+i*11)+".JPG" for j in range(11)]
    imgs = [cv2.imread(file) for file in files]
    mertens = cv2.createMergeMertens()
    resImg = mertens.process(imgs)
    resImg = np.clip( resImg*255, 0, 255 ).astype('uint8') 
    cv2.imwrite("hoge"+
                "out_"+str(1000+i)+".jpg", resImg)
 そして、11段階の多段露出画像を合成した連番画像ファイルを動画ファイルとして結合することで、たとえば、下に貼り付けたようなLittle Planet風のタイムラプス(微速度)動画として眺めることができます。撮影を行ったのは、都会に近い薄曇りの空の下ですが…それでも恒星が浮かぶ宇宙空間を回転する地球が進んでいるさまが見えるような気がしてきます。

2017-02-12[n年前へ]

Ricoh Theta S で2017年旧暦1月満月の夜を撮ってみる  share on Tumblr 

 思い返せば2015年は忙しかった。長身の国オランダに入り浸ったり、大学病院に入院したり、タイのスコータイやチェンマイあるいはバンコクで Ricoh Theta S と自作治具を抱えて全天周HDR距離マップ付き動画に挑戦したり、人生で2回目のスカートを送風機でめくる実験をしたり…と七転八倒の毎日だった。

 そんな人生七転八倒のお友達 Ricoh Theta S ともっと戯れたい!というわけで、OpenSphericalCameraのTheta S 制御用 Python コードを3.x用に書き換えて、長時間露光の微速度撮影で満月の夜を撮影をしてみた。

 旧暦1月の満月の夜を、露光60秒で20分ほどの時間、微速度動画を撮ってみる。太陽のように明るい満月と、都会に近いけれどそれでも見えるいくつもの星 は、北極星を中心に廻っている。もしも、渋谷のスクランブル交差点や、上野公園の桜の下、あるいは、山手線のホームで眺めてみたら、一体どんな景色が見えてくるだろう。

Ricoh Theta S で2017年旧暦1月満月の夜を撮ってみる






2017-01-29[n年前へ]

「手持ちスマホ撮影動画からの超巨大開口レンズ撮影」に挑戦してみよう!?  share on Tumblr 

 かつて、スマホに搭載されているカメラのレンズはとても小さく、綺麗なボケとは無縁の存在でした。しかし、今や最新のスマホには特殊処理によるボケ生成機能などが備えられています。カメラレンズの光学開口径が小さくとも、たとえば2眼カメラなどを備えて距離情報を取得して、距離情報などからボケを人工的に合成するといった仕組みです。

 そんな最新スマホを持たずとも、大レンズのボケ味を手に入れるために、「手持ちスマホ撮影動画からの超巨大開口レンズ撮影」に挑戦してみました。スマホ動画から巨大開口レンズ撮影の手順はとても簡単、まずは目の前の風景にスマホを向けて・なるべくスマホが平面上を動くように意識しながら(スマホを動かしつつ)動画撮影します。そして、動画の各コマから画像ファイル群を生成し、それぞれの画像が撮影された位置や方向にもとづいて撮影された光情報を加算合成する、というものになります。

 細かい手順は、スマホ撮影動画(の展開画像をもとに) Bundler: Structure from Motion (SfM) から出力された刻々のカメラ位置・方向や特徴点情報ファイル(bundler.out)を読み込み、それらのカメラ情報にもとづいて、刻々の撮影画像をレンズ開口面に沿った(同じ方向を向く平行カメラが存在していた場合の)光線画像を位置・角度ズレを踏まえて重ねることで、任意のピント位置に焦点を合わせた超巨大開口レンズ撮影画像を生成する…というものです。

 試しに、iPhoneを約1.5m×1.0mの範囲で動かしつつ動画撮影し、つまり、レンズ直径約1.5mに相当する範囲で動かしつつ動画撮影し、その画像群から開口合成により超巨大カメラの撮影画像を作り出してみた結果が右上の画像です。

 右上画像を眺めてみても、良好なボケ味どころか、全くピントが合っていない画像にしか見えません。直径が1mを超える開口を持つカメラレンズとなると焦点深度もとても浅くなるのでピントがなかなか合わない…というわけでなく、手持ち撮影動画からのカメラ位置・方向精度が低いせいか、単一カメラに平行合成した後のズレが大きいようです。

 ちなみに、試しに各画像を(撮影方向による傾きを補正しつつ)位置毎に並べてみると、下の画像のようになります。動画撮影からのカメラ位置推定精度が果たして不十分なのかどうか、次は撮影カメラ位置を精度良く知る事ができる撮影治具でも作り、また再挑戦してみたいと思います。

 上記処理のコード手順、Python/OpenCVで書いたコード処理手順は、bundler.outからカメラ位置・方向・焦点距離や歪みパラメータを読み込み、cv2.initUndistortRectifyMapにカメラ情報を渡して、各撮影画像の向き補正用のホモグラフィーマップを作成してremapで変換した後に、各撮影画像を加算合成するという手順です。

 Bundlerの出力ファイルを読み込んでライトフィールド合成を行うOpenCV/Pythonコード、まだまだ間違い含まれているような気もしますが、とりあえずここに貼り付けておくことにします。

import cv2
import numpy as np
from matplotlib import pyplot as plt
from PIL import Image
import math
%matplotlib inline

class camera:
    def __init__(self):
        self.f = 1.0
        self.k1 = 0.0
        self.k2 = 0.0
        self.R = [[0.0,0.0,0.0],[0.0,0.0,0.0],[0.0,0.0,0.0]]
        self.T = [0.0,0.0,0.0]

def readBundlerOut( filePath ):
    f = open(filePath, 'r')
    list = f.readlines()
    f.close()

    numberOfCameras = int((list[1].split())[0]) 
    cameras = []
    for i in range(numberOfCameras):
        aCamera = camera()
        fk1k2 = [float(j) for j in list[5*i+2].split()]
        aCamera.f  = fk1k2[0]
        aCamera.k1 = fk1k2[1]
        aCamera.k2 = fk1k2[2]
        rot = []
        for j in range(1,4):
            rot.append( [float(k) for k in list[ 5*i+2+j ].split()] )
        aCamera.R = rot
        aCamera.T = [float(k) for k in list[ 5*i+2+4 ].split()]
        cameras.append(aCamera)
    return cameras

def readImageList( listPath, imageDirPath ):
    f = open(listPath, 'r')
    list = f.readlines()
    list = [ i.rstrip() for i in list ]
    f.close()
    list = [imageDirPath+fileName for fileName in list]
    return list

class lightField:
    
    def __init__(self):
        self.w = 2000
        self.h = 2000
    
    def loadImageListAndMakeLightField( self, 
                    imagePathList, cameraList, workList, scaleA ):
        self.cimg  = np.zeros((self.h, self.w,3), dtype=np.uint8)
        sum = 1.0
        for i in workList:
            img = cv2.imread( imagePathList[i], cv2.IMREAD_COLOR )
            h, w = img.shape[:2]
            imageHeight = img.shape[0]
            imageWidth =  img.shape[1]
            focalLength = cameraList[i].f
            principalPointX = 0.500000
            principalPointY = 0.500000
            distCoef = np.array([ 0.0, 0.0, 0.0, 0.0, 0.0 ])
            cameraMatrix = np.array([ 
                [focalLength,   
                 0.0,          
                 imageWidth  * principalPointX], 
                [0.0,           
                 focalLength,  
                 imageHeight * principalPointY], 
                [0.0,           0.0,          1.0] 
                           ])
            newCameraMatrix, roi = cv2.getOptimalNewCameraMatrix(
                cameraMatrix,
                distCoef,
                (img.shape[1], img.shape[0]),1,
                (img.shape[1], img.shape[0]) )
            rotMatrix = np.array( cameraList[i].R )
            map = cv2.initUndistortRectifyMap( 
                newCameraMatrix,
                distCoef,
                rotMatrix,
                newCameraMatrix, 
                (img.shape[1], img.shape[0]),
                cv2.CV_32FC1)
            
            undistortedAndRotatedImg = cv2.remap( img, 
                        map[0], map[1],
                        cv2.INTER_LINEAR )
            
            scale = 1.0
            pt3 = np.array(cameraList[i].T) - np.array(cameraList[0].T)
            x =  ( self.w/2.0 - pt3[0] * scale * scaleA ) 
            y =  ( self.h/2.0 - pt3[1] * scale * scaleA ) 
            pts1 = np.float32( [[0,      0],
                                [w, 0],
                                [w, h],
                                [0, h]])
            pts2 = np.float32(  [[x,           y],
                                 [x + w*scale, y],
                                 [x + w*scale, y + h*scale],
                                 [x,           y + h*scale]] )
            M = cv2.getPerspectiveTransform( pts1, pts2 )
            img2 = cv2.warpPerspective( 
                undistortedAndRotatedImg, M, (self.w, self.h) )
            sum = sum + 1.0
            self.cimg = cv2.addWeighted(
                 self.cimg, (sum-1) / sum, 
                 img2,      (1.0) / sum, 0)
    
    def showImage(self):
        plt.figure( figsize=(14,14) )
        plt.imshow( np.array(self.cimg2) ) 
        plt.autoscale( False )

「手持ちスマホ撮影動画からの超巨大開口レンズ撮影」に挑戦してみよう!?「手持ちスマホ撮影動画からの超巨大開口レンズ撮影」に挑戦してみよう!? 






2017-01-21[n年前へ]

「入金」を意味する「チャージ」の歴史 第1話  share on Tumblr 

 現代の日本では、「入金する」ことを「チャージ」と表すことが多い。たとえば、何かを買ったり・使ったりすることができる権利や口座など、あるいは、そういう用途のカードに再入金を行うことを「チャージ」と表現することが多いように思う。

 ところが、それを英語で表現しようとすると、それは「チャージ」ではない、というワナがある。「再入金する」ということを表すために、top-upとかadd valueとは言うけれど、chargeと言ってしまうと「課金する」「支払いを(さらに)求める」といった意味になってしまう。つまり、意味が逆になってしまう。

 この「意味の逆転」が生じるに至った歴史・主要因として、まず一番疑いたくなるのがJR東日本が2001年から提供している乗車カード・電子マネーサービスであるSuica(スイカ)だ。それまでに、再入金できないプリペードカードはすでに広まっていたが、Suica(スイカ)は、再入金可能かつ広まったプリペードカードの先駆けだった。

 その「Suica(スイカ)サービス開始」のプレスリリース、2001年9月4日にJR東日本が出したプレスリリースでは、カードに再入金をすることを「チャージ(ご入金)」と表現している。もっとも、この時代の日本では、入金=チャージという共通認識は確立されていなかったようで、「チャージ」には「チャージ:Suicaのイオカード部分に入金すること」という、注釈も付いている。今や「チャージ」という日本語に注釈が付くことは少ないが、この時代には注釈がまだ付いていた。ちなみに、イオカードというのは、SUICAカード以前に使われていた磁気式プリペイド乗車カード(に相当する機能)のことである。

 もうじき20年近く前になる21世紀の初頭の日本、JR東日本が「なぜ、再入金することを表すために、チャージという言葉を選んだ経緯・理由」をJR東日本に(もしその経緯などを示す資料などあれば?と)問い合わせてみた。そして、JR東日本から頂いた回答は次のようになる。

 明確な資料等はございませんが、Suicaにつきましては、従来の磁気式のイオカード等、使い切りの形ではなく、充電式の電池等のようにカードに再度入金をしていただくことで、1枚のカードを繰り返しご利用いただけることをお客さまにわかりやすくお伝えする趣旨で充電等を意味する「チャージ」の用語を用いております。なお、一部、わかりづらいというご意見がありましたので、宣伝物等のご案内については「入金(チャージ)」という表現を使用しております。

JR東日本

 CHARGEの語源は、ラテン語の「荷車(carrus)」から、「荷を積む(carricare)」という意味が、古フランス語を経て、英語で使われるようになったものだ。荷を積むことは、負荷を掛けることであって、それは支払いを求める(責任や仕事の分担を求める)ことにも繋がるし、充電された状態にするための「負荷」を掛けることも意味する。この車に積む「荷」をプラスの(足す)作用を持つ存在と捉えるかマイナスの(引く)ものと考えるかが、2017年の日本語のチャージと英語のChargeの違いに繋がっているように思われる。

 JR東日本が「チャージ」という言葉を選ぶに至った歴史の前ページ、そして、それ以外のエトセトラ…については、次にまたメモ書きしてみたいと思う。

2017-01-15[n年前へ]

データで眺める誕生日、生まれる人が少ないのは「土日祝日と○月×日」  share on Tumblr 

 データで眺める誕生日、生まれる人が少ないのは「土日祝日と○月×日」を書いた。人が生まれる誕生日時は、平均的に眺めてみれば、比較的精度良くコントロールされているものだ。

 データで眺めてみると、生まれる人が少ない「土日祝日と4月1日」と比べて、普通の平日は2割〜3割くらい生まれる人が多くなっています。誕生日はその年のカレンダーと連動しているので、誕生した人が多い日・少ない日は、年によって偏りが生まれます。ちなみに、休みとして月日がいつも決まっている祝日は、いつの年であっても「生まれた人は少ない」ということになるので、色々な年で平均してみてもやはり誕生日には偏りがあることになります。

2017-01-14[n年前へ]

ライトフィールドプリント最適化のためのBlenderシミュレーション その1  share on Tumblr 

 いくつもの視点から見た映像から視点変化に応じた見え方を再現するライトフィールド・プリント(インテグラル・フォトグラフィー)を作るために、Blender を使った透明シートへの印刷シミュレーションをしながら、効率的な印刷方法に挑戦してみた。

 どんな場合でも汎用的に使うことができる一般的な画像に対して、視点変化に応じた見え方を再現しようとすると、偏光素子を重ねるなど特殊な方法を使うのでなければ、視野を制限するマスク(アパーチャ)に相当する層を上にプリントした上で、視野変化に応じて見える光(色)をさらにその下にプリントすることになりそうだが、そうすると、次の問題が生じる。変角解像度を両立させるためにはマスク(アパーチャ)を小さくしたくなるが、そうすると画像が暗くなる。

 この問題に対して最適解を出そうとすると、マスクの口径(アパーチャー)が持つ周波数特性を、視点変化に対する見え方変化の周波数特性と一致させたくなる。つまり、もしも、視点が変化しても見え方の変化が小さい方向があれば、その方向に対してはマスクの口径(アパーチャー)を大きくし(周波数特性を鈍くし)、視点変化に対して見え方が敏感に変わる方向があれば、その方向に対しての口径を狭くしたくなる。つまり、高周波が鈍ることを防ぎたくなる。

 というわけで、ライトフィールドプリントの上面に配置したマスク(アパーチャ−)形状を、視点変化に対する見え方の変化(ライトフィールド勾配)に連動した方向性を持つ楕円形状にした画像生成をするPythonコードを書いてみた。そして、スタンフォードの The (New) Stanford Light Field Archiveをサンプル画像として使い、Blenderでライトフィールドプリントのシミュレーションをしてみたのが下の動画だ。

 眺めてみると、マスクサイズを固定とした範囲では、明度と変角解像度という相反する項目の両立が改善したような気もするが、空間方向変化(空間解像度)と連成した処理になっていないこともあり、まだまだ修正すべき項目が多い。…というわけで、次は、変角解像度と空間解像度の最適化を考えてみることにしよう。

2017-01-08[n年前へ]

ネット画像から有名人の個人情報(静脈パターン)を可視化してみよう!?  share on Tumblr 

 SNSなど投稿した「ピースマークなどの指写真」から指紋を推定する記事「指紋がネットで狙われている! 手の画像は悪用恐れ… 国立情報学研が新技術の実用化目指す」を読みました。写真の解像度が高ければ、指紋の抽出は確かにできそうです。もっとも、2017年時点の、よくある撮影解像度やアップロード画像解像度を考えると、指紋抽出はまだ困難な気がします。

 撮影の解像度だけを考えれば、皮膚内での波長毎の吸収・散乱特性の違いによる静脈可視化の方が楽かもしれません。掌を走る静脈は、その模様が人ごとに違うため、個人認証機器に多く使われたりします。そこで、各波長(RGB画像)の特性の違いを利用して、静脈推定をしてみることにしました。

 まずはネット上から掌が映った写真を探してみることにします。有名人の掌が映った写真はとても多く、観客に手を振る写真・演説中に両手の掌を開いて聴衆に見せている写真など、さまざまなパターンの画像が手に入ります。

 そして、静脈を可視化するために色の違いを利用するとなると、重要なことは「圧縮率が低い画像を探す」ということです。なぜかというと、人の視覚系は明度に対しては敏感ですが、色の違いに対しては解像力が低いため、多くの画像ファイルでは色情報が圧縮され低解像度になっているからです。

 圧縮率が低く・掌が映った有名人画像を探してみると、まず最初に見つかったのが綾瀬はるかさんの写真です(下左図)。この画像に「静脈部分を抽出する画像処理」を掛けてみると、皮膚下を走る静脈が浮かび上がってきます(下右図)。

 静脈模様を可視化する用途には、ネットにアップロードされている画像では圧縮率が問題になります。しかし、自分で撮影する画像なら、撮影さえすれば、圧縮が掛かっていない画像が手に入ります。…ということは、個人情報を狙われやすい有名人の人は、静脈模様を覆い隠す「静脈盗撮防止用のコンシーラー」などが必需品になるかもしれません。

2016-12-30[n年前へ]

「π r2(パイアール2乗)=面積」式は、ひいらぎ愛 さんの乳曲率に適用可能か?問題  share on Tumblr 

 「面積表示のタイトルがいいでしょ」というtweetに思わず目を引かれて、紹介文を眺めた途端に思わず笑ってしまいました。

「魅惑の巨大乳輪 ひいらぎ愛 π r2(パイアール2乗)=面積176cm2」巨大乳輪に特化した新シリーズです。第一弾は乳輪直径15cm、面積176cm2の…
そして、ふと考えたのです。
「乳というものは、多くの場合は立体的な存在である。少なくとも、ひいらぎ愛さんの場合は、超立体的なものに違いない。それなのに、面積計算を2次元平面上の公式を使って良いものだろうか?」
そこで、果たしてπ r2(パイアール2乗)=面積176cm2で良いのかどうか、軽く計算をしてみることにしました。

 ひいらぎ愛さんは、トップバストがバスト156cmでOカップということです。ということは、以前書いた おっぱい解析向けライブラリを使うと、彼女のトップバストに対してアンダーパストは45cm短い111cmであることがわかります。さらに、その乳を半球で近似した時の半径は30cmであると計算されます。

 乳を半球で近似すると、乳輪の面積は「半球を乳輪の大きさである立体角θで切り取った領域の表面積」となり、式で書くと、

 2π r^2 (1- Cos θ)
となります。立体角θは、「乳輪直径15cm」というのが、表面に沿って長さを計ったものだとすると、乳輪の立体角θは約29度です。すると、その乳輪の表面積は172平方cmとなります。π r2(パイアール2乗)から計算される177平方cmとは、約5平方cmほど違います。最初の2桁だけを比べれば、曲率を考慮してもしなくても全く同じ数値ですから、その差は十分小さいのかもしれません。

 「π r2(パイアール2乗)=面積」式は、ひいらぎ愛 さんの乳曲率に適用可能か?問題を解決するためには、その乳輪の直径だけでなく「円周の長さを計る」などの方法により乳表面の曲率を求める、という作戦が考えられます。それは、今後の課題としておこうかと思ます。

2016-12-23[n年前へ]

Python/OpenCVで画像多重解像度解析コードを書いてみる  share on Tumblr 

 多重解像度解析…といっても直交基底に分解するというような話ではなくて、単に各周波数帯の特性がどの程度含まれるかを眺めるといった用途なら(つまり、ガボール変換やSTFTを掛ける感じの程度の用途なら)、Python/OpenCVを使って十数行で書けるかも?と思い書いてみました。もちろん、実装は簡単第一最優先!というわけで、ガウシアンフィルタ差分で2次元のバンドパスを作成し、それを周波数軸で重ねて眺めてみるというくらいの話です。

 実際に書いてみたら、ポスト処理含めて約20行くらいになりました。超入門的な画像処理コードですが、1次元〜2次元の多重解像度解析や周波数解析を行うことは意外に多いような気もするので、適当に貼り付けておくことにします。*


*画像処理クラスタからのコメント:
 ・マルチスケールで眺めるなら、DCゲイン1同士のガウシアン差分をとり、そのL2ノルムを1に正規化しすべし。
 ・周波数軸は等比的にした上で、ボリューム的表示も等比的比率で重ねたい。

import numpy as np
import cv2
from matplotlib import pyplot as plt

def DOG(img, s, r):
    img2=img.astype('uint16')
    img2=img2*128+32767
    gs = cv2.GaussianBlur(img2,(0, 0), s)
    gl = cv2.GaussianBlur(img2,(0, 0), s*r)
    return cv2.absdiff(gs, gl)

img = cv2.imread("sample2.jpg",0 )
(h,w)=img.shape
pts1 = np.float32([[0,0],[w,0],[w,h],[0,h]])
pts2 = np.float32([[0,h*1/4],[w*3/4,h*1/4],
                   [w,h*3/4],[w*1/4,h*3/4]])
M = cv2.getPerspectiveTransform(pts1,pts2)
baseImg = cv2.warpPerspective(
    img.astype('uint16'),M,(w,h))

for i in range(100,5,-10):
    pts1 = np.float32([[0,0],[w,0],[w,h],[0,h]])
    pts2 = np.float32([[0+i,h*1/4-i],
    [w*3/4+i,h*1/4-i],[w+i,h*3/4-i],[w*1/4+i,h*3/4-i]])
    M = cv2.getPerspectiveTransform(pts1,pts2)
    img2 = cv2.warpPerspective(DOG(img, i, 1.05),M,(w,h))
    baseImg = cv2.addWeighted(baseImg, 0.9, img2, 0.3, 0)

plt.figure(figsize=(6,6))
plt.imshow(np.array(baseImg)) 
plt.autoscale(False)

Python/OpenCVで画像多重解像度解析コードを書いてみる






2016-12-14[n年前へ]

「(泡が下へ沈んでいく)ギネスカスケード」を高速度撮影してみよう!?  share on Tumblr 

 続々「(泡が下へ沈んでいく)ギネスカスケード」を近赤外線で撮影してみよう!?過去ビール記事で書いたように、上が広がったグラスにビールを注ぎ、ビールの上面に溜まった泡を眺めると、きめ細やかにできあがった泡が下へ下へと下降しているさまが見えます。泡と言えば「上に浮かび上がっていく」ばかりに思えますが、いくつかの条件が重なると、グラスの中で「下へひたすら沈んでいく」ビールの泡を見ることができます。

 そんな「下降を続けるビールの泡」のようすを細かく確認するために、今日は高速度撮影を行っててみました。…といっても、やったことは、iPhoneに顕微鏡アタッチメントを付けて、標準機能の高速撮影を行ってみただけのことです。

 高速度撮影した映像を眺めてみると、泡(Bubble)というより遙かに密度が高く、むしろ泡(Foam)という言葉の方が適切かもしれない状態の中で、大きな泡は緩やかに下降して・小さな泡は隙間へと素早く動きながら速い速度で下降していることがわかります。ちなみに、この高速度撮影を行った時には、ビールグラスの中では「泡部分」と「ビール液体(だけがある部分)」は分離している状態になっています。

 これまでコンピュータ流体シミュレーションから予想されている現象は、グラス中央で浮かび上がる泡がグラス内部にビールの対流を生み、グラフの最外側境界で下降していくビールの流れに沿って泡が下降していくように見える、というものでした。しかし、ビールと泡がすでに分離したグラスの中で、泡が下降していくように見えるさまを眺めていると、もう少し違う説明も必要であるようにも思えてきます。

2016-12-13[n年前へ]

街通りを歩きながら…列車中で…似合う「飲料類」を決める振動動特性のヒミツ  share on Tumblr 

 街の通りを歩きながら、あるいは列車の中で1人飲み物を飲みたくなることがある。時にビール、あるいはコーヒー、その時の気分に応じた何かを手に持つカップに注いで飲んでみたくなる。とはいえ、カップから飲み物がこぼれたりするのはイヤだ…という人は、この論文  "Damping of liquid sloshing by foams: from everyday observations to liquid transport" を読んでみると面白いと思う。

 場所や状況に応じた飲み物を、その時の気分だけではなくて、その場所の「振動や揺れ」に応じて選びたい!と考える人に役立つこの論文は、飲み物の上面に浮かぶ「泡(foam)」が、どのように飲み物自体の揺れ・振動を抑える効果があるかを示している。液上面に泡がわずか数ミリメートルあるだけで、液面の揺れが数分の1に治まるようにすることができる現象解析をした論文だ。

 石けんや洗濯洗剤で「泡のかたまり」を作り、息を吹きかけたり・指で突き動かしたりすると、ブルブル震えて大きく揺れる。けれど、それと同時に、揺れがだんだん治まっていくことにも気付かされる。それはもちろん、たくさんの泡が「動き」を妨げるよう・緩やかにするよう抵抗として働くからだ。

 揺れが激しいところでは、きめ細やかな泡が厚く重なるギネスビールが似合う…とか、もう少し揺れが治まればピルスナービールが似合う…とか、(泡を持たない)コーヒーでは揺れが少ない落ち着いた場所が似合うとか、そんなことがわかる論文は、読んでみると面白いと思います。

街通りを歩きながら…列車中で…似合う「飲料類」を決める振動動特性のヒミツ






2016-12-12[n年前へ]

「君の名は。」画風変換アプリをPython/OpenCVで書いてみよう! 〜意外に空変換は簡単? 編〜  share on Tumblr 

 先月下旬頃、映画「君の名は。」画風変換アプリEverfilterが流行っていた。軽く遊んでみた印象は、「空領域抽出処理に破綻が少なく(適切で)、その処理はおそらく普通の枯れた方法を使って、画面の4端辺から領域判定を独立にかけてる」ように感じられた。

 そこで、普通にやりそうなコードを書いてみたら、空領域抽出がどのくらいの品質が得られるか、確かめてみることにした。手っ取り早く試してみたいというわけで、Python/OpenCVコードを書いてみた。このコードは、入力画像と(入れ替え用の)空画像を読み込んで、グラフカットアルゴリズムが実装されたOpenCVのGrabCut関数を使い、(空がある程度の面積を占めていそうな)画面上半分の領域を対象として空領域を抽出し、その領域に空を合成するという処理を行うものだ。その処理例が、たとえば下に貼り付けた「バンコクの昼風景を夜空の下の街に入れ替えた画像」のようになる(上が入力画像、下が出力画像)。

 コードを書いて・試してみた印象は、OpenCVのGrabCut関数を使う程度でも、十分破綻の少ない空領域抽出を行うことができそうで、枯れた(枯れつつある)技術は便利だ!というものだ。実際のところ、「君の名は。」画風変換アプリ程度であれば、使用データ群(入れ替え用画像群)抽出処理も含めて、数日掛からず作ってしまいそうな気がする。

import cv2
import numpy as np

img = cv2.imread("bangkok1s.jpg")
mask = np.zeros(img.shape[:2],np.uint8)
skyimg = cv2.resize(cv2.imread("Starsinthesky.jpg"),
                         img.shape[1::-1]) 
bgdModel = np.zeros((1,65),np.float64)
fgdModel = np.zeros((1,65),np.float64)
rect = (0,0,img.shape[1],round(img.shape[0]*0.7))
cv2.grabCut(img,mask,rect,bgdModel,fgdModel,
                      50,cv2.GC_INIT_WITH_RECT)
mask2 = np.where((mask==2)|(mask==0),0,1).astype('uint8')
mask2 = cv2.blur(mask2,(5,5))
img2 = img*(1-mask2[:,:,np.newaxis])
skyimg = skyimg*mask2[:,:,np.newaxis]
img3 = cv2.addWeighted(skyimg, 1, img2, 1, 2.5)
cv2.imwrite("out.jpg",img3)
cv2.imshow("preview",img3)
cv2.waitKey()

「君の名は。」画風変換アプリをPython/OpenCVで書いてみよう! 〜意外に空変換は簡単? 編〜「君の名は。」画風変換アプリをPython/OpenCVで書いてみよう! 〜意外に空変換は簡単? 編〜






2016-12-11[n年前へ]

「平面的に見える満月」と「立体的な月蝕」の秘密  share on Tumblr 

 太陽と正反対の空に浮かぶ満月は、とても平面的に見える。まるで、真っ平らな円を切り抜いて、夜空に貼り付けたように見える。白いピンポン球を手に持って、光を当てながら眺めたときのような、「中央近くは明るくて、周辺部分が滑らかに暗く落ち込む陰影が付いた、立体感ある見え方」にはならない。

 球の周りが徐々に暗くなる陰影は、物体表面に当たった光が、表面から外に帰っていく際に、周囲に等しく方向性を持たず返される時に生じる。そんな条件では、球の中心から端部までコサイン関数状の陰影が生じる。それでは、遙か古代に信じられていた平面状の月でなく、現実には3次元球体であるはずの月が陰影無く、真っ平らに見えてしまうのだろうか。

 その秘密は、月表面の反射特性にある。月の表面は、その表面を照らす光を、その光が発された方向へ返す性質があるからだ(Diffuse Reflections from Rough Surfaces )。満月の時、月を基準にすると、月を照らす太陽は地球の後ろにある。そして、月を照らす太陽と同じ側に浮かぶ地球から月を眺めると、月の表面反射特性は「陰影がほとんどない、真っ平らな平面状の満月」を空に浮かび上がらせることになる。

 自分を照らす光を、その光が発された方向へと返す再帰性反射と呼ばれる性質は、急峻な凹凸の表面形状や(交通標識などで使われる)透明ビーズ(やキャッツアイ)など、多くの材質で現れる。再帰性の反射性質が現れる理由は、たとえば、前者の急峻な凹凸形状の場合であれば、斜めから当たる光も、表面が急峻な凹凸形状*であれば、斜面(の法線方向に対し)垂直近くに光が当たり、その光が元来た方向へと帰って行きやすくなるからで、後者の透明ビーズでは、ビーン内部の反射により光が元いた場所へと戻っていくからだ。

 通常の満月がとても平面的に見える一方、同じ満月の時期に稀に訪れる皆既月蝕中の月は、とても立体的に見える。それは、太陽からの光を地球が遮りつつ、けれど地球大気が屈折させた太陽光は、月表面を見事なまでな立体的でグラデーション豊かな、名カメラマン顔負けの素晴らしいライティングとなる。

 次に日本で見ることができる皆既月蝕は2018年1月31日らしい。その満月を見ることができたなら、立体感溢れる月を眺めてみたいと思う。


*そうした形状の表面反射を表したモデルが、Oren–Nayarの反射モデル

「平面的に見える満月」と「立体的な月蝕」の秘密「平面的に見える満月」と「立体的な月蝕」の秘密「平面的に見える満月」と「立体的な月蝕」の秘密






2016-12-03[n年前へ]

グラス片手に楽しく読めるシャンパンに関する計算や可視化解説  share on Tumblr 

 普段はシャンパンなんて飲まないにも関わらず、クリスマスが近づくと風物詩的に少しだけ飲んでみたくなる。そんな時期に眺めてみるととても面白そうな「シャンパンに関する計算や可視化解説」があった。このConvective Mass Transfer in a Champagne Glass (Fabien Beaumont, Gérard Liger-Belair and Guillaume Polidori)が楽しいのは、登場する計算式が比較的簡単でわかりやすいということもあるけれど、何よりシャンパンが注がれたグラス内から立ち上る気泡を可視化したさまがとても美しく、その写真に思わず目を惹かれ、魅入られてしまうからだ。

 アルゴンレーザーでシート状に光を照射して、シャンパンガラス周りでレーザー光が屈折してしまわないように、シャンパンを入れたグラスを水槽中に浮かべ、グラスを切断するように横から当てたレーザー光で浮かび上がらせた泡の動きは、ただ眺めているだけでも不思議に心地良くなる。

グラス片手に楽しく読めるシャンパンに関する計算や可視化解説 グラス片手に楽しく読めるシャンパンに関する計算や可視化解説 






2016-11-15[n年前へ]

空に浮かぶ雲の大きさから、雲の高さや地球の大きさを推定する方法  share on Tumblr 

 青空に浮かぶ白い雲を眺めながら、こんなことを訊かれたことがある。

「たとえば、南の空に浮かぶ、天頂からちょうど40度くらいの角度の雲までの距離や高さを、眺めた景色から計算することができる?」

 雲の高さやその雲までの距離、それらを一体どうやったら知ることができる?という質問だ。もちろん、気象に詳しい人なら、たとえば「あれはひつじ雲で、近くの山の高さと比較すると、多分高さは3千メートルくらいだろう」という具合で、雲の種類や見え方から、雲の高さを知ることができるかもしれない。そして、雲の高さがわかってしまえば、雲までの距離を計算するための式は幾何的に導出することができる。それは、雲の高さをr、天頂からの角度をαとし、地球の半径6371kmをRとしたこんな式だ。

 実際のところ、雲の高さや距離は、どちらか片方がわかってしまえば、もう片方は自動的に求まる性質のものだ。前述の「雲までの距離」を計算するための式は、雲の高さr、雲の天頂からの角度α、地球の半径Rという3つのパラメータを用いたものだから、天頂角度α、地球半径Rがわかっている限りは、雲の高さか雲間での距離のどちらか片方がわかってしまえば、残りひとつの未知数は単純に計算することができる。たとえば、雲の高さを地上から2000mに固定すると、雲が見える方向(天頂からの角度)に応じた雲までの距離は、次のようなグラフとして描くことができる。

 けれど残念なことに、その時のぼくには、雲や気象に関する知識がほとんど無かったので、「一体どうすれば雲の高さや距離を知ることができるのだろう?」と考えながら、ただ黙っていた。

 目の前の景色から雲の高さと距離を知る方法を尋ねられてから何年も経った今日、バンコクの空に浮かぶ雲を眺めながら、こんな「空に浮かぶ雲の高さと距離を推定する方法」をふと思いついた。それは、こんな考え方だ。

 雨季から乾季を迎えたバンコクの青空には多くの「わた雲」が浮かんでいる。このわた雲たちはどれも同じ物理現象の結果生じたもので、いずれもとても安定な状態で空に浮かんでいるのだ。だとしたら、きっと似たような大きさをしていると考えるのが自然だろう。そしてまた、大気気象的には、どの雲の底面も地上からの高さはほぼ同じになっているはずだ。

 そして、雲の「天頂からの角度」と「見た目の大きさ」は、眺めた景色から知ることができる。だとすれば、雲までの距離は雲の見た目の大きさに(比例係数をsとして)反比例しているという関係を使って、上述の式に、雲の「見た目の大きさと天頂からの角度」を既知(わかっている数値)として代入すれば、雲の高さrと比例係数sを2未知数とした方程式ができあがる。それはつまり、距離が異なる2個以上の雲の大きさを観察して、その雲の大きさや場所を代入した連立方程式を解けば、雲の高さや距離がわかる、ということになる。

 ためしに、バンコクで眺めた雲の位置と大きさの関係をデジカメ撮影画像から算出して、散布図にしたのが下左図だ。天頂から離れた「遠い」雲ほど小さいという単純な関係だ。この雲の位置と大きさを観察した関係から、雲の高さrと比例係数sを「手動で」フィッティングしてみると、たとえば、雲の(底面)高さが500mの場合で、下右図のような対応となる。この数日が真実と近いのか・遠いのかはわからないけれど、こんな風に、原理的には、大きさが同じ雲の位置や大きさがどのように見えるかを調べてやれば、雲の高さや雲までの距離は知ることができる…かもしれない。

 …「原理的には」「かもしれない」と書いたのは、前述の式は、雲の高さrを求めるには精度が低い式だからだ。式自体は「”地球の半径+雲の高さ”を半径とする円」と「雲を見上げた視線の直線」の交点から導かれる方程式で、雲の高さが地球半径に比べて遙かに小さいために、精度良く雲の高さや雲間での距離を求めることは、おそらく難しいからだ。

 地球の半径に比べて雲の高さが遙かに小さいから、この方程式を使っても雲の高さを求められない?…だとしたら、頭上から地平線近くまで散らばる雲の大きさとこの連立方程式を使って地球半径を計算してみるのはどうだろう?この方程式は、雲の高さr、雲の天頂からの角度α、地球の半径Rという3つのパラメータを結びつけるものだから、たとえば「雲の天頂からの角度αは見たままに、わた雲の高さrは気象の知識や周りの山などの比較から地上500mとする」というように考えれば、あとは雲の大きさから地球半径Rを求めることができるかもしれない。

 ためしに、上に使ったデータで最小二乗フィッティングを行ってみると、地球半径R=約6万2千kmという結果になった。教科書に載っている地球の半径約6千3百kmと比べると、10倍ほども大きい巨大な地球になってしまった。良い結果を得ることができたとは全く言えない。

 その理由は、地平線近くの遠い雲といっても、自分を中心にした数十km程度の距離しかないので、その見え方から直径にして1万2千kmもの地球の大きさを計算するにはとても無理があるからだ。

 けれど、青空に広がる雲を眺め、雲の位置や大きさがどんな風に見えるかを調べて、地球の大きさを求めてみることができるかもしれないと考えると、何だかとてもワクワクさせられる気がする。

空に浮かぶ雲の大きさから、雲の高さや地球の大きさを推定する方法空に浮かぶ雲の大きさから、雲の高さや地球の大きさを推定する方法空に浮かぶ雲の大きさから、雲の高さや地球の大きさを推定する方法






2016-10-29[n年前へ]

「眼球の型をしたピンホールカメラ」模型を作ってみよう!?  share on Tumblr 

 小学生高学年向けのこどもたちに「見えないものを観てみよう!」という実験授業をするために、「眼球の型をしたピンホールカメラ」模型を作ってみました。…どういうことかというと、授業内容は「自分の目で見ることができる可視光な世界を踏まえつつ、それとは異なる非可視な電磁波で世界を眺めてみよう!」というものなのですが、そのためには「私たちが(人それぞれ)どんな風に世界を眺めているのか」を説明する必要があるのかもしれないと思い「見ることができるもの」を話すための補助資料を作ってみようと考えたわけです。

 そこで、以前作った全球ディスプレイを作るためのパーツを利用して、「眼球の型をしたピンホールカメラ」模型を作ってみました。直径30cmほどの白球体に、瞳形状の絞りを貼り付けて、さらに瞳中心にはレンズを固定して…網膜に映る映像を(眼球の後ろ側から)の眺めることができる模型を作ってみました。

 後は、この眼球模型に錐体や錯体を(人それぞれの比率や分布で)貼り付けてみると面白そうですが…そういう仕組みを見せるなら、この球体を全球ディスプレイとしてPCから表示する方が適切なのかもしれません。

「瞳型したピンホールカメラ」模型を作ってみよう!?「瞳型したピンホールカメラ」模型を作ってみよう!?






2016-10-23[n年前へ]

弾丸2泊1日的、香港経由の深圳アプローチ最適解!?  share on Tumblr 

 香港・日本間の片道航空券が380円(香港エクスプレス航空)で売られたりもしている今日この頃、その類のチケット、日本深夜発(早朝香港着)で、深夜香港発(早朝日本着)便で中国深圳に行ってきたので、「お金と時間」を最適化する「2016年度版、弾丸2泊1日的、香港経由の深圳アプローチ最適解」をメモしておきます。

 早朝香港着で「その時間に動いている交通手段も限られて」、さらにその当日にはもう日本に戻る「時間が貴重なコース」となると、香港空港からエアポートエクスプレス経由で香港市街に入り、MTR経由で深圳に入りたくなります。そして、このエアポートエクスプレス+MTR経由コースは、日帰り往復コースなら、コストパフォーマンスがとても良くなります。

 なぜかと言うと、150香港ドルで買うことができるオクトパスカード(Octopus Card 八達通)を使うと、

  1. オクトパスカードでエアポート・エクスプレスに乗車すると、同日の帰りのエアポート・エクスプレス乗車が無料
  2. エアポート・エクスプレスに乗車した後に1時間以内に乗継いだMTR線の料金が無料
  3. 九龍駅と香港駅から街中へ走る何種類もの無料シャトルバスに乗ることができる
  4. 九龍駅と香港駅にある航空会社カウンターでオクトパスカード使ってインタウン・チェックインすると、手続き直前に(オクトパスカードで)乗車したMTR料金が無料
というサービスがあるからです。このオクトパスカード3大サービスを使うと、「エアポートエクスプレスで香港空港→(たとえば)九龍駅・MTRに乗り換えて九龍駅→羅湖駅/羅湖駅→九龍駅、九龍駅でインタウンチェックイン/(シャトルバスで移動して)自由時間/九龍駅→香港空港」という経路を辿ることで、香港空港から深圳(香港側としては羅湖駅か落馬洲駅)までの往復運賃が、(たとえば上記の香港駅でエアポートエクスプレスとMTRの乗り換え/インタウンチェックインを行った場合なら)全てコミコミなんと90香港ドル(約1200円)でできることになるからです。

 弾丸2泊1日的、香港経由の深圳アプローチをする場合には、早朝に香港国際空港に着いたら、空港内セブンイレブンでオクトパスカードを購入し、(たとえば)九竜駅経由で深圳往復をして、九龍駅などでインタウンチェックインをした上で、無料シャトルバスで香港市街を堪能し、その後エアポートエクスプレスで香港国際空港に戻り、オクトパスカードを払い戻す(60香港ドル返却される)…というのが、もしかしたら最適解、かもしれません。

2016-10-16[n年前へ]

「現実にはありえない」照明状態の「道路沿いのパラドクス」を現実にしてみよう!?  share on Tumblr 

 アニメーションの作画をする際に、絵の印象を良くするために「現実にはありえない」照明状態で描くという「道路沿いのパラドクス」テクニックの話を面白く読みました。この話を読みながら、ふと「そんな不可能立体を杉原厚吉先生風に現実に作り出してみるのも面白いかも」と考え、雑に適当に「現実にはありえない」照明状態の「道路沿いのパラドクス」を現実にしてみました。

 雑に3Dラクガキした程度なので出来はイマイチだったり、「そもそも現実にはありえない」感じが増幅しただけ…のような気もしますが、とりあえず「がんばりました」と日記には書いておくことにします。

「現実にはありえない」照明状態の「道路沿いのパラドクス」を現実にしてみよう!?「現実にはありえない」照明状態の「道路沿いのパラドクス」を現実にしてみよう!?