2017-04-30[n年前へ]
■スマホ(BLE)から動かせる街中スナップ用の(Ricoh Theta S用)2軸自動制御アームを作ってみる。
先週、Ricoh Theta用の極座標自動アームを作った。それを旅先で持ち歩き・街中で2軸アームを 動かしつつ気軽なスナップ写真を撮るために、今日は「ステージ制御をスマホ(iPhone)からできる」ようにしてみました。作戦は、iPhoneとアーム制御ボード間をBluetooth(BLE)で繋ぎ、iPhone上で動くPython環境(Pythonista)から制御アームとRicoh Theta Sを同期制御するという仕組みです。
先週組んだアームはMakeblockのパーツを使っているので、その制御に使ってる(Makeblock製の)ArduinoボードにBluetooth I/Fを繋ぎ、ドキュメントとiOSアプリのLightBlue Explorerで制御ボードにアクセスしてみると、servicesのFFE1中にあるcharacteristics FFE3 に書き込みを行えば、制御ボードに情報を渡すことができることがわかります。…というわけで、「iPad + Pythonista(iOSで動くPython) + BLEで、Genuino101のLチカをしてみた。」を参考に、Makeblock(Arduino UNO)ボードに(適当に俺ルールで決めた5byte一組の)コマンドをiPhone(Pythonista)から送りつけ、そのコマンドをもとに2軸アームを動かしてみることにしました。
というわけで、スマホから制御できる「Ricoh Theta S+制御アーム」を持ち歩き、山道で撮影した(円筒表面上の48枚の)画像から、試しに生成してみたた3次元風景が下の動画です。Ricoh Theta S自体は、全天周撮影を行うカメラですが、それを閉曲面状の複数点で撮影することで、3次元な全天周世界を復元したり、周囲の見た目を再現したり(ライトフィールド)することができます。
ちなみに、iOS Pythonista ( Python ) からの制御コードは、上記参考コードをもとにして、たとえば下のような感じにしています。
def did_discover_services(self, p, error): for s in p.services: print(s.uuid) if 'FFE1' in s.uuid: p.discover_characteristics(s) def did_discover_characteristics(self, s, error): if 'FFE1' in s.uuid: for c in s.characteristics: if 'FFE3' in c.uuid: self.myProcedureWithTheta(c)その上で、(上記コードのmyProcedureWithThetaとしたような部分で)適当なコマンドや値をMakeblock Arduinoボードに渡す(そしてその情報をもとにアームのモータなどを動かす)ことで、持ち歩き用の自動制御アーム付き三脚のできあがり!というわけです。
self.peripheral.write_characteristic_value( c, cmd, False) self.peripheral.write_characteristic_value( c, bytes([step]), False)
2017-05-28[n年前へ]
■ディープラーニング姿勢推定openposeで「妄撮カメラ iOS版」を作ってみる!?
ディープラーニングによる姿勢推定openposeで「男子の夢な(衣服の下を透視する)妄撮カメラ」を作ってみよう!?で書いたコードを元にして、画像をhttpでPOSTすると(httpサーバ側で)姿勢推定を行い、画像に写る人の「服の下が透けて見える妄想映像」を自動生成する画像処理を行って、httpクライアントに妄想撮影画像を返すサーバ側コードを書き、さらに(iOS上でPythonを使うことができるようにするPythonistaを使い)iPhone上でカメラ撮影をすると、自動的に妄撮画像を生成するアプリコードを書くことで、手元のiPhoneを「妄撮カメラ」に仕立ててみました。
試しに、妄撮カメラ(iPhone Pythonista版)を動かしてみたようすが、下に貼り付けた動画です。こういうカメラ、20世紀後半に中2くらいだった男子には需要がありそうな気がするのですが、草食男子化とコンプライアンスという言葉が流行る21世紀の今日この頃には、全く需要も無い気がする今日この頃です。
ちなみに、今や一人一台持ち歩くスマホでなく、現代の化石たるコンパクトデジカメを(メーカ・機種問わず)全て妄撮カメラしてしまう無線LAN SDカードPQI Air内部で動くRubyコードも書いてみたのですが、なぜか思ったように動かなくて悩んでいます。
何はともあれ、勢いで書いたサーバ側コードとPythonistaコードは、中2男子以外の誰の役に立つことも120%無い気がしますが、明日にでもダウンロードできるようにしておこうと思います。
機械学習/ディープラーニングによる姿勢推定アルゴリズム/コードのopenposeを使った「妄撮カメラ」について、 サーバ/クライアントPythonコードをダウンロード可能にして、iOS用ネイティブアプリ作成方法も書いて起きました。( 機械学習による姿勢推定openposeで「妄撮カメラ iOS版(ネイティブアプリ)」を作ってみる!? )
2017-05-30[n年前へ]
■機械学習による姿勢推定openposeで「妄撮カメラ iOS版(ネイティブアプリ)」を作ってみる!?
10日くらい前、機械学習により画像に写る人体の姿勢を推定するアルゴリズム(コード)のopenposeを使い、画像に写る人の衣服を妄想的に脱がす画像処理ソフトを作ってみました(ディープラーニングによる姿勢推定openposeで「男子の夢な(衣服の下を透視する)妄撮カメラ」を作ってみよう!?)。そして、先週末は、そのソフトをiPhoneから自由自在に使うことができるように(カメラを備えたクライアントiPhone側と機械学習や画像処理を行うサーバ側双方の)Pythonコードを書いてみました(ディープラーニング姿勢推定openposeで「妄撮カメラ iOS版」を作ってみる!?)。
書いたPythonコードはここに置いておきます。下記2ファイルのうち、前者がサーバ側ファイルで、後者がiOSアプリたるPythonistaコードです。前者は jupyter notebook ファイルなので、jupyterからコードを実行すると、8080ポートでopenposeを使った妄撮(姿勢推定・類似姿勢検索・画像合成)サービスが起動します。そして、後者がiOS上で動くPython(Pythonista)で実装した、妄撮サーバ機能を使うことができるカメラアプリコードです。
- boysCamera.ipynb.20170530
- boysCamera.py.20170530
とはいえ、これだけでは先週末に書いたコードをアップロードしただけ…ということになってしまうので、今日はPythonistaコードをiOS用ネイティブアプリケーションにする方法についても書いておきます。
まずは、Pythonista用のXcodeプロジェクトをダウンロードします。そして、プロジェクト中の main.py に自分が書いたiOS用Python(Pythonista)コードを貼り付けます。そして、Xcodeでプロジェクトをビルドした上で、ビルドされたアプリケーションをiOSデバイスに転送すると、iOSデバイス上でネイティブアプリケーションとして妄撮カメラを使うことができるようになります。
…というわけで、ネイティブにビルドした妄撮カメラアプリケーションを使って、中二男子大好きな妄想撮影をしてみたようすが、下に貼り付けた動画です。深夜ドラマだった懐かしの「トリック」主人公の姿さえ、透撮できてしまうことに驚きます。
試してみると強烈に実感しますが、現実世界と妄想世界を(中二男子的に)重ね合わせる「妄撮カメラ」アプリケーションは、実に強烈なMR/ARアプリケーションです。…こうしたアプリケーション、ライセンス的に誰もが使用可能なデータベースやソフトウェアコードを書けば、(中二男子に限って言えば)世界を変えるキラーアプリケーションになるかも!と思ったり思わなかったりします。
2017-06-01[n年前へ]
■全てのデジカメをリアル妄撮カメラにしてしまう狂気!無線LAN内蔵SDカードアダプタPQI Air Cardと機械学習の間違った使い方
先日、機械学習を使い人体姿勢を推定するアルゴリズム(コード)openposeをキッカケに、人を妄想的に脱衣させてしまうPC画像処理ソフト(ディープラーニングによる姿勢推定openposeで「男子の夢な(衣服の下を透視する)妄撮カメラ」を作ってみよう!?)や、そのスマホアプリ化(ディープラーニング姿勢推定openposeで「妄撮カメラ iOS版」を作ってみる!?)、さらにはiOSネイティブアプリケーション化をしてみました(機械学習による姿勢推定openposeで「妄撮カメラ iOS版(ネイティブアプリ)」を作ってみる!?)。…今日は、その最終駅として、お仕事で使うようなPCでもなく・いつも持ち歩くスマホでもなくて、もはや過去の遺物になりつつある「デジタルカメラ」をリアル妄想撮影カメラにしてみることにしました。
実際のところ、そんなことはとても簡単です。すでに、撮影した画像をサーバに投げるだけで、姿勢推定や脱衣画像を自動生成するコードは書いてあるので(ディープラーニング姿勢推定openposeで「妄撮カメラ iOS版」を作ってみる!?)、その機能をデジカメから使うようにするだけで良いのです。…というわけで、内部で動作するLinuxを自由に使うことができる無線LAN内蔵SDカードアダプタPQI Air Cardを使い、SDカード内のJPGファイルに対して自動で人体姿勢推定と脱衣画像合成処理をするRubyコードを書いてみました。もちろん、こんなことはPQI Air Cardで動くRubyを知っている人であれば、実に簡単にできる作業です(デジカメ内部でRubyを動かす狂気!無線LAN内蔵SDカードアダプタPQI Air Cardの間違った使い方)。
まずは、PQI Air CardにRuby(あるいはCurlなど)を(前記のリンク先などから)インストールしておきます。それと同時に、PQI Air Card が起動時から外部無線LANアクセスポイントに接続してクライアントとして動作する設定にしておきます(autorun.shから/usr/bin/w2を呼ぶだけですね)。そして、autorun.sh の最終端からRubyコードを起動して、/mnt/sd/DCIM内の".JPG"ファイル群に対して妄撮画像処理を実行させてやると、デジカメで撮影した(そしてSDカード内に保存された)写真に写る人が、いつの間にか中二妄想的な脱衣姿になってしまう…というわけです。
そんなSDカードを作り、作ったSDカードをデジカメに刺して、撮影画像を妄想撮影してみた処理例が、右上の2枚の写真です。まずは左に写る画像が(PCに写る画面を)デジカメで撮影した画像で、デジカメ内部で(サーバを経由して)生成された妄想撮影画像結果が2枚の右側に写る画像です。
機械学習の力を活用したopenposeを使い、SDカードのDCIMディレクトリのJPGファイルをフルオートマチックに妄想撮影画像にしてしまうRubyコードをウンストールしたのが右のSDカードです。このSDカードを刺すだけで(刺したら最期)、ほぼ全てのデジカメが妄撮カメラに変身してしまいます。レンズを向けた風景に写るひと全てが、一皮も二皮も剥けた姿に変わってしまうのです。中二男子には素晴らしい道具ですが、それ以外の人にとっては単なる極悪ツールです。
ちなみに、そんな極悪もしくは中二男子の妄想的機能を備えたRubyコードが動くSDカードを刺したコンパクトデジカメです。つまり、世界初のリアル妄撮コンパクトデジタルカメラ。…世界を変えることはないでしょうが、このカメラをひとたび手にしたならば、あなたが見る世界を・周りに存在する世界を見る目を変えてしまう…かもしれません。
書いたコードは、ここからダウンロードできるようにしておきます。
2018-04-22[n年前へ]
■Python(Pythonista)でiOSカメラを自由自在に使ってみる
iPhone/iPadなどの機器のカメラは、焦点位置や露光時間や感度など、わりと細かく制御することができます。そうした撮影処理を使って、露光時間を変えた撮影を何枚もして画像(ハイダイナミックレンジ:HDR)合成をしたり、焦点位置を変えた撮影から焦点合成(フォーカススタッキング)を行ったりすると、意外に楽しいものです。とはいえ、そんなコード遊びをするのに、毎回Objective-C(やC++)でコーディングするのは少し面倒です。
というわけで、今日はiOSで動くPython ( Pythonista ) で、iOSのカメラをマニュアル撮影的に使うコードを書いてみました。それが下に貼り付けたPythonコード例です。この例では、焦点制御を無効化した上で、最近接位置から無限遠までのレンズ位置を0.0〜1.0の任意位置に制御しつ、撮影を行うことができます。
「開発用マシンでコードを書いてビルドした上で、スマホに転送して動かす」というような手間を掛けずとも、スマホ上で比較的短いコードを書いて、それをスマホ上で瞬時に動かして「自分だけの特殊撮影マシン」を仕立てて遊ぶことができるのは面白いものです。…今回貼り付けた撮影処理部分は全くPythonっぽくないコードですが、ひとたび「ライブラリ化」してしまえば、こんなコードを見る必要もなく、やりたいことだけをPythonから気楽に実行することができるようになります。…となれば、色々遊んでみたくなる人も多いのではないでしょうか。
# coding: utf-8 from objc_util import * import time AVCaptureSession = ObjCClass('AVCaptureSession') AVCaptureDevice = ObjCClass('AVCaptureDevice') AVCaptureDeviceInput = ObjCClass('AVCaptureDeviceInput') AVCapturePhotoOutput = ObjCClass('AVCapturePhotoOutput') def manualCapture(device, output, focusDistance, fileName): def captureOutput_didFinishProcessingPhotoSampleBuffer_ previewPhotoSampleBuffer_resolvedSettings_bracketSettings_error_( _self, _cmd, _output, _photoBuffer, _previewBuffer, _resolveSettings, bracketSettings, _error ): photoBuffer = ObjCInstance(_photoBuffer) jpegPhotoData = ObjCClass('AVCapturePhotoOutput' ).JPEGPhotoDataRepresentationForJPEGSampleBuffer_ previewPhotoSampleBuffer_( photoBuffer, _previewBuffer) jpegPhotoData.writeToFile_atomically_(fileName, True ) # delegate CameraManualPhotoCaptureDelegate = create_objc_class( 'CameraManualPhotoCaptureDelegate', methods=[ captureOutput_didFinishProcessingPhotoSampleBuffer_ previewPhotoSampleBuffer_resolvedSettings_bracketSettings_error_ ], protocols=[ 'AVCapturePhotoCaptureDelegate' ]) device.lockForConfiguration_(None) device.setFocusModeLockedWithLensPosition_completionHandler_( focusDistance, None) device.unlockForConfiguration() time.sleep(1) delegate = CameraManualPhotoCaptureDelegate.new() settings = ObjCClass('AVCapturePhotoSettings' ).photoSettings() settings.AVCaptureFocusMode = 0 output.capturePhotoWithSettings_delegate_( settings, delegate ) time.sleep(1) delegate.release() @on_main_thread def main(): session = AVCaptureSession.alloc().init() device = AVCaptureDevice.defaultDeviceWithMediaType_('vide') _input = AVCaptureDeviceInput.deviceInputWithDevice_error_( device, None) if _input: session.addInput_(_input) else: return session.startRunning() output = AVCapturePhotoOutput.alloc().init() session.addOutput_(output) time.sleep(1) manualCapture(device, output, 0.0, 'sample.jpg') time.sleep(1) session.stopRunning() session.release() output.release() if __name__ == '__main__': main()