tag:blogger.com,1999:blog-1719011024392705312024-03-13T19:31:40.738+09:00かっしぃのメモ帳かっしぃの日々のメモ帳です。
気づいたことや思ったこと、プログラミングのコツ、
最近気になることなどをメモしてます。
Twitter
http://twitter.com/kassy708kassy708http://www.blogger.com/profile/00025482097446561673noreply@blogger.comBlogger33125tag:blogger.com,1999:blog-171901102439270531.post-90444316966293712592022-05-14T15:48:00.003+09:002022-05-14T15:52:50.339+09:00古いMacbookを初期化したら、App StoreにログインできずMac OSを再インストールできなくなった件<p>ふと、10年以上前に使っていた古いMacbook Air 2010をメルカリで売ろうと思い、初期化しようと思ったところ、うまく初期化できなくてハマってしまったので、メモとして残しておきます。</p><p>問題が起きた機種はMacbook Air 2010(OS X Lion)です。</p><p>最終的にはAppleサポートに問い合わせて解決できました。</p><p><br /></p><h2 style="text-align: left;"><span style="font-size: medium;">問題</span></h2><p>メルカリに出品する前に、以下のページを参考にMacの初期化を行っていました。<br />参考:<a href="https://support.apple.com/ja-jp/HT201065#:~:text=Mac%20%E3%81%AE%E9%9B%BB%E6%BA%90%E3%82%92%E5%85%A5%E3%82%8C,%E5%A0%B4%E5%90%88%E3%81%AF%E5%BE%A9%E5%85%83%E3%81%95%E3%82%8C%E3%81%BE%E3%81%99%E3%80%82" target="_blank">Mac を売却、譲渡、下取りに出す前にやっておくべきこと</a>、<a href="https://support.apple.com/ja-jp/HT208496" target="_blank">ディスクユーティリティを使って Intel 搭載の Mac を消去する</a></p><p>すると、こちらの7つめの手順で問題が起こりました。</p><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEgstuegapPg4RCtd1JVPhVYAqpH2VdZcI1Z2D036pcVQ8oZ9kWBUVLv1Dz5Z9bx3KdOQdQjfNvuwx9ga_RsUZVJ0EdFJIj_bD9PZtccCK5vm5_EHLLqAjSN09BI_Ch0Zsyf-IY4Eer49MwLQOONF2SWzp8BgcYzafjvV354xL2pIZkpBRBKTbpX2msMGg" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="800" data-original-width="849" height="240" src="https://blogger.googleusercontent.com/img/a/AVvXsEgstuegapPg4RCtd1JVPhVYAqpH2VdZcI1Z2D036pcVQ8oZ9kWBUVLv1Dz5Z9bx3KdOQdQjfNvuwx9ga_RsUZVJ0EdFJIj_bD9PZtccCK5vm5_EHLLqAjSN09BI_Ch0Zsyf-IY4Eer49MwLQOONF2SWzp8BgcYzafjvV354xL2pIZkpBRBKTbpX2msMGg" width="255" /></a></div><br /><br /><p></p><p><span face=""SF Pro JP", "SF Pro Text", "SF Pro Icons", "Hiragino Kaku Gothic Pro", "\\30D2ラギノ角ゴPro W3", "\\30E1イリオ", Meiryo, "MS Pゴシック", "Helvetica Neue", Helvetica, Arial, sans-serif" style="background-color: white; color: #333333;">ディスクユーティリティでMacを削除したあと、macOSの再インストールする際、App StoreからOSのダウンロードを行うのですが、なぜかApp StoreにログインするためのApple IDの認証が通らずにOSをダウンロードできなくなりました。</span></p><p><span face=""SF Pro JP", "SF Pro Text", "SF Pro Icons", "Hiragino Kaku Gothic Pro", "\\30D2ラギノ角ゴPro W3", "\\30E1イリオ", Meiryo, "MS Pゴシック", "Helvetica Neue", Helvetica, Arial, sans-serif" style="background-color: white; color: #333333;">IDかパスワードが間違っているというようなエラーが表示されてしまいまします。</span></p><p><span face=""SF Pro JP", "SF Pro Text", "SF Pro Icons", "Hiragino Kaku Gothic Pro", "\\30D2ラギノ角ゴPro W3", "\\30E1イリオ", Meiryo, "MS Pゴシック", "Helvetica Neue", Helvetica, Arial, sans-serif" style="background-color: white; color: #333333;">しかし、Apple IDのIDとパスワードは間違っておらず、実際にIDとパスワードを入力するとiPhoneに二要素認証のコードが表示されています。</span></p><p><span face="SF Pro JP, SF Pro Text, SF Pro Icons, Hiragino Kaku Gothic Pro, \\30D2ラギノ角ゴPro W3, \\30E1イリオ, Meiryo, MS Pゴシック, Helvetica Neue, Helvetica, Arial, sans-serif" style="color: #333333;"><span style="background-color: white;">にっちもさっちもいかず、1週間ほど粘ったあとAppleのサポートへ問い合わせました。</span></span></p><p><span face="SF Pro JP, SF Pro Text, SF Pro Icons, Hiragino Kaku Gothic Pro, \\30D2ラギノ角ゴPro W3, \\30E1イリオ, Meiryo, MS Pゴシック, Helvetica Neue, Helvetica, Arial, sans-serif" style="color: #333333;"><span style="background-color: white; font-size: 17px;"><br /></span></span></p><h1 style="text-align: left;"><span face=""SF Pro JP", "SF Pro Text", "SF Pro Icons", "Hiragino Kaku Gothic Pro", "\\30D2ラギノ角ゴPro W3", "\\30E1イリオ", Meiryo, "MS Pゴシック", "Helvetica Neue", Helvetica, Arial, sans-serif" style="background-color: white; color: #333333;"><span style="font-size: medium;">原因</span></span></h1><p><span face=""SF Pro JP", "SF Pro Text", "SF Pro Icons", "Hiragino Kaku Gothic Pro", "\\30D2ラギノ角ゴPro W3", "\\30E1イリオ", Meiryo, "MS Pゴシック", "Helvetica Neue", Helvetica, Arial, sans-serif" style="background-color: white; color: #333333;">どうやら、このときのMacのOSは最初にログインしたApple IDを入力しないといけなかったそうです。</span></p><p><span face=""SF Pro JP", "SF Pro Text", "SF Pro Icons", "Hiragino Kaku Gothic Pro", "\\30D2ラギノ角ゴPro W3", "\\30E1イリオ", Meiryo, "MS Pゴシック", "Helvetica Neue", Helvetica, Arial, sans-serif" style="background-color: white; color: #333333;">そういえば、当時作成したApple IDのメールアドレスがsoftbankのキャリアメールを使用しており、キャリアを乗り換えるときにキャリアメールが使えなくなると困るのでApple IDのメールアドレスを変更したことがありました。</span></p><p><span face=""SF Pro JP", "SF Pro Text", "SF Pro Icons", "Hiragino Kaku Gothic Pro", "\\30D2ラギノ角ゴPro W3", "\\30E1イリオ", Meiryo, "MS Pゴシック", "Helvetica Neue", Helvetica, Arial, sans-serif" style="background-color: white; color: #333333;">そのため、Apple ID自体は同じものですが登録したメールアドレスが変わってしまっていたことによりApple IDのログインができなくなってしまったと思われます。</span></p><p><span face=""SF Pro JP", "SF Pro Text", "SF Pro Icons", "Hiragino Kaku Gothic Pro", "\\30D2ラギノ角ゴPro W3", "\\30E1イリオ", Meiryo, "MS Pゴシック", "Helvetica Neue", Helvetica, Arial, sans-serif" style="background-color: white; color: #333333;"><br /></span></p><h2 style="text-align: left;"><span face=""SF Pro JP", "SF Pro Text", "SF Pro Icons", "Hiragino Kaku Gothic Pro", "\\30D2ラギノ角ゴPro W3", "\\30E1イリオ", Meiryo, "MS Pゴシック", "Helvetica Neue", Helvetica, Arial, sans-serif" style="background-color: white; color: #333333;"><span style="font-size: medium;">解決策</span></span></h2><p><span face=""SF Pro JP", "SF Pro Text", "SF Pro Icons", "Hiragino Kaku Gothic Pro", "\\30D2ラギノ角ゴPro W3", "\\30E1イリオ", Meiryo, "MS Pゴシック", "Helvetica Neue", Helvetica, Arial, sans-serif" style="background-color: white; color: #333333;">標準のApp StoreからOSをダウンロードして再インストールする方法は不可能だということが判明したため、OSをローカルPCでダウンロードしてインストールディスクを作る方法を提案されました。</span></p><p><br /></p><h2 style="text-align: left;"><span face=""SF Pro JP", "SF Pro Text", "SF Pro Icons", "Hiragino Kaku Gothic Pro", "\\30D2ラギノ角ゴPro W3", "\\30E1イリオ", Meiryo, "MS Pゴシック", "Helvetica Neue", Helvetica, Arial, sans-serif" style="background-color: white; color: #333333;"><span style="font-size: medium;">用意するもの</span></span></h2><p></p><ul style="text-align: left;"><li><span face=""SF Pro JP", "SF Pro Text", "SF Pro Icons", "Hiragino Kaku Gothic Pro", "\\30D2ラギノ角ゴPro W3", "\\30E1イリオ", Meiryo, "MS Pゴシック", "Helvetica Neue", Helvetica, Arial, sans-serif" style="background-color: white; color: #333333;">別のMac PC</span></li><li><span face="SF Pro JP, SF Pro Text, SF Pro Icons, Hiragino Kaku Gothic Pro, \\30D2ラギノ角ゴPro W3, \\30E1イリオ, Meiryo, MS Pゴシック, Helvetica Neue, Helvetica, Arial, sans-serif" style="color: #333333;"><span>14 GB 以上の</span></span><span face="SF Pro JP, SF Pro Text, SF Pro Icons, Hiragino Kaku Gothic Pro, \\30D2ラギノ角ゴPro W3, \\30E1イリオ, Meiryo, MS Pゴシック, Helvetica Neue, Helvetica, Arial, sans-serif" style="color: #333333;"><span>USB フラッシュドライブ、もしくは外付けHDD</span></span></li></ul><p></p><p><span face="SF Pro JP, SF Pro Text, SF Pro Icons, Hiragino Kaku Gothic Pro, \\30D2ラギノ角ゴPro W3, \\30E1イリオ, Meiryo, MS Pゴシック, Helvetica Neue, Helvetica, Arial, sans-serif" style="color: #333333;"><span style="background-color: white; font-size: 17px;"></span></span></p><p><br /></p><h2 style="text-align: left;"><span style="font-size: medium;">手順</span></h2><p><span face="SF Pro JP, SF Pro Text, SF Pro Icons, Hiragino Kaku Gothic Pro, \\30D2ラギノ角ゴPro W3, \\30E1イリオ, Meiryo, MS Pゴシック, Helvetica Neue, Helvetica, Arial, sans-serif" style="color: #333333;"><span style="background-color: white;">手順は以下に記載されている通り、Macを使ってインストーラーをダウンロードしてインストールディスクを作成します。</span></span></p><p><span face="SF Pro JP, SF Pro Text, SF Pro Icons, Hiragino Kaku Gothic Pro, \\30D2ラギノ角ゴPro W3, \\30E1イリオ, Meiryo, MS Pゴシック, Helvetica Neue, Helvetica, Arial, sans-serif" style="color: #333333;"><span style="background-color: white;">参考:</span></span><a class="aapl-link" href="https://support.apple.com/kb/HT201372" rel="noopener noreferrer" style="background-color: white; color: #0088cc; font-family: "Helvetica Neue", Arial, Helvetica, Verdana, sans-serif; letter-spacing: -0.37px;">macOS の起動可能なインストーラを作成する方法</a></p><div><br /></div><p>幸い、iMacを所有していたのでインストールディスクを作成することができました。</p><p>インストールディスクを作成するためには、ターミナルでコマンドをうつ必要があるため、エンジニア出ない人には難しく感じるかもしれません。</p><div>ただ、記載されているとおりにすればそれほど躓かないと思います。</div><div><br /></div><div>うっかりつまづきそうな注意点としては以下となります。</div><div><ul style="text-align: left;"><li>インストールドライブを初期化する際、名称は「MyVolume」としなければなりません</li><li>インストールするMac OSはそのMac PCがインストール可能なバーションにする</li><li>作成したインストーラーでOSを新規インストールする際、wi-fiに接続しておく</li></ul></div><p><span face=""SF Pro JP", "SF Pro Text", "SF Pro Icons", "Hiragino Kaku Gothic Pro", "\\30D2ラギノ角ゴPro W3", "\\30E1イリオ", Meiryo, "MS Pゴシック", "Helvetica Neue", Helvetica, Arial, sans-serif" style="background-color: white; color: #333333;"><br /></span></p><p><span face=""SF Pro JP", "SF Pro Text", "SF Pro Icons", "Hiragino Kaku Gothic Pro", "\\30D2ラギノ角ゴPro W3", "\\30E1イリオ", Meiryo, "MS Pゴシック", "Helvetica Neue", Helvetica, Arial, sans-serif" style="background-color: white; color: #333333;"><br /></span></p><p><span face=""SF Pro JP", "SF Pro Text", "SF Pro Icons", "Hiragino Kaku Gothic Pro", "\\30D2ラギノ角ゴPro W3", "\\30E1イリオ", Meiryo, "MS Pゴシック", "Helvetica Neue", Helvetica, Arial, sans-serif" style="background-color: white; color: #333333;">古いOSかつ、Apple IDのメールアドレスを変更するというような、なかなか無いシチュエーションかと思いますが、ご参考になれば幸いです。</span></p><p><br /></p><p><br /></p>kassy708http://www.blogger.com/profile/00025482097446561673noreply@blogger.com0tag:blogger.com,1999:blog-171901102439270531.post-43066347891391725042020-11-07T14:40:00.002+09:002020-11-07T14:42:56.505+09:00iPhone 12にFortniteをインストールして遊ぶ方法(How to install and play Fortnite on your iPhone 12)<h2 style="text-align: left;">Epic vs Appleの全面戦争</h2><p>2020年8月13日、Fortniteを開発・運営するEpic Gamesは、iOSおよびAndroidを含むすべてのプラットフォームにおけるゲームアプリ『フォートナイト』をアップデートし、Epic Gamesから直接購入(課金)できる決済システム「Epic direct payment」を実装しました。</p><p>それにより、AppleはFortniteを規約違反としてストアから削除し、新規にインストールができなくなってしまいました。</p><p><br /></p><h2 style="text-align: left;">取り残された世界で遊び続ける</h2><p>ストアから削除される前にiPhoneにFortniteをインストールしていたユーザーは、端末にアプリが残ったままとなり、遊び続けることができました。</p><p>しかし、以降アップデートが行われないため、2020年8月27日から開始されたチャプター2シーズン4(v14.00)にはアップデートできません。iPhoneユーザーは他のプラットフォームと切り離され、チャプター2シーズン3に取り残された状態で遊び続けることになっています。</p><p>私もその一人としてiPhone 8でチャプター2シーズン3を遊び続けていました。</p><p>一度、Switchの移行してFortniteを遊んでいたのですが、元々FPSが苦手ということもあり全くエイムが定まらず全くビクロイすることができませんでした。</p><p>結局、自動照準ができるiPhone 8に戻り遊び続けていたのですが、高頻度でアプリ落ちするなど端末スペックの限界を感じていました。</p><h2 style="text-align: left;">iPhone 12の発表</h2><p>2020年10月13日にAppleが最新のiPhone 12シリーズを発表しました。</p><p>早速iPhone 12 Proを購入したのですが、iPhone 8からバックアップでデータを引き継いだところ、ストアから削除されたFortniteはインストールすることができませんでした。</p><p>どうしてもiPhone 12でFortniteが遊びたかったため、iPhone 12にインストールする方法を調査しました。</p><p>その結果、iPhone 12 ProでFortniteをインストールして遊べることができたので、その方法をご紹介します。</p><p><br /></p><h2 style="text-align: left;">iPhone 12にFortniteのアプリをインストールする方法</h2><div>Fortniteはストアから削除されているため、アプリをダウンロードすることはできません。</div><div>そのため古いiPhoneからアプリデータ(ipaファイル)を吸い出し、新しいiPhone 12にインストールします。</div><div><br /></div><h3 style="text-align: left;">iMazingのインストール</h3><div>今回、私が使用したソフトは<a href="https://imazing.com/ja/download" target="_blank">iMazing</a>というソフトです。</div><div>Windows版とMac版がありますので、ご使用になっているPCのOSのバージョンをインストールしてください。私はMacを使用しているのでiMazing for Macをインストールしました。</div><div><br /></div><div><div class="separator" style="clear: both; text-align: center;"><a href="https://imazing.com/ja" style="margin-left: 1em; margin-right: 1em;" target="_blank"><img alt="" data-original-height="796" data-original-width="1158" height="220" src="https://lh3.googleusercontent.com/-Nv1hsS9XDcI/X6YnQaWOoBI/AAAAAAAAXy4/u4SjA5tQAh063_tjz_LHxgJ5MOlSJ0N3ACNcBGAsYHQ/%25E3%2582%25B9%25E3%2582%25AF%25E3%2583%25AA%25E3%2583%25BC%25E3%2583%25B3%25E3%2582%25B7%25E3%2583%25A7%25E3%2583%2583%25E3%2583%2588%2B2020-11-07%2B13.48.41.png" width="320" /></a></div><div class="separator" style="clear: both; text-align: center;"><a href="https://imazing.com/ja" target="_blank">https://imazing.com/ja</a></div><br /></div><h3 style="text-align: left;">iMazingでFortniteのアプリデータ(ipa)を吸い出す方法</h3><div>iMazingをインストールした後、PCにFortniteがインストールされた古いiPhoneと新しいiPhone 12を接続してください。</div><div>iMazingを起動すると、ソフトの画面の左側に接続したiPhoneの情報が表示されます。</div><div>Fortniteがインストールされた古いiPhoneのリストから「アプリ」を選択し、「アプリを管理」をクリックしてください。</div><div>途中、Apple IDのログイン画面が表示されるので、Apple IDとパスワードを入力してログインしてください。</div><div><br /></div><div><div class="separator" style="clear: both; text-align: center;"><div class="separator" style="clear: both; text-align: center;"><a href="https://lh3.googleusercontent.com/-_GFM7GriRTI/X6YpwVgr-5I/AAAAAAAAXzQ/56TQp1mlteUTMrrONoj14FAo67CjA_NfACNcBGAsYHQ/%25E3%2582%25B9%25E3%2582%25AF%25E3%2583%25AA%25E3%2583%25BC%25E3%2583%25B3%25E3%2582%25B7%25E3%2583%25A7%25E3%2583%2583%25E3%2583%2588%2B2020-11-07%2B13.56.48.png" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="847" data-original-width="1209" height="224" src="https://lh3.googleusercontent.com/-_GFM7GriRTI/X6YpwVgr-5I/AAAAAAAAXzQ/56TQp1mlteUTMrrONoj14FAo67CjA_NfACNcBGAsYHQ/%25E3%2582%25B9%25E3%2582%25AF%25E3%2583%25AA%25E3%2583%25BC%25E3%2583%25B3%25E3%2582%25B7%25E3%2583%25A7%25E3%2583%2583%25E3%2583%2588%2B2020-11-07%2B13.56.48.png" width="320" /></a></div><br /><br /></div></div><div>「アプリを管理」画面からFortniteを探し出し、右側の雲アイコンをクリックしてアプリをダウンロードしてください。</div><div>ダウンロードが完了すると、以下のようにインストール済みの列にチェックが入ります。</div><div><br /></div><div><div class="separator" style="clear: both; text-align: center;"><a href="https://lh3.googleusercontent.com/--DzHtKKK6uA/X6Yoo0Rh3AI/AAAAAAAAXzE/BwgS5LDmQ98TduN8UM-9i0RpGbPgL57CQCNcBGAsYHQ/%25E3%2582%25B9%25E3%2582%25AF%25E3%2583%25AA%25E3%2583%25BC%25E3%2583%25B3%25E3%2582%25B7%25E3%2583%25A7%25E3%2583%2583%25E3%2583%2588%2B2020-11-07%2B11.34.13.png" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="612" data-original-width="1018" height="192" src="https://lh3.googleusercontent.com/--DzHtKKK6uA/X6Yoo0Rh3AI/AAAAAAAAXzE/BwgS5LDmQ98TduN8UM-9i0RpGbPgL57CQCNcBGAsYHQ/%25E3%2582%25B9%25E3%2582%25AF%25E3%2583%25AA%25E3%2583%25BC%25E3%2583%25B3%25E3%2582%25B7%25E3%2583%25A7%25E3%2583%2583%25E3%2583%2588%2B2020-11-07%2B11.34.13.png" width="320" /></a></div><br /><br /></div><div>Fortniteを右クリックし、「.IPAをエクスポート」を選択し、お好きなディレクトリにエクスポートしてください。</div><div><br /></div><div><div class="separator" style="clear: both; text-align: center;"><a href="https://lh3.googleusercontent.com/-4QrnF12ka9k/X6YqzO7eJVI/AAAAAAAAXzg/f1R5voSH0XEinssh2RJwOPBumJW3qy-cACNcBGAsYHQ/%25E3%2582%25B9%25E3%2582%25AF%25E3%2583%25AA%25E3%2583%25BC%25E3%2583%25B3%25E3%2582%25B7%25E3%2583%25A7%25E3%2583%2583%25E3%2583%2588%2B2020-11-07%2B11.34.28.png" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="612" data-original-width="1019" height="192" src="https://lh3.googleusercontent.com/-4QrnF12ka9k/X6YqzO7eJVI/AAAAAAAAXzg/f1R5voSH0XEinssh2RJwOPBumJW3qy-cACNcBGAsYHQ/%25E3%2582%25B9%25E3%2582%25AF%25E3%2583%25AA%25E3%2583%25BC%25E3%2583%25B3%25E3%2582%25B7%25E3%2583%25A7%25E3%2583%2583%25E3%2583%2588%2B2020-11-07%2B11.34.28.png" width="320" /></a></div><div><br /></div><br />エクスポートが完了すると「Fortnite 13.40.1.ipa」というアプリファイルが出力されます。</div><div><div class="separator" style="clear: both; text-align: center;"><a href="https://lh3.googleusercontent.com/-LnXKMVyEQUM/X6YrJ4FEkaI/AAAAAAAAXzo/6tBcDziMFds2V89A1zOCB4bd1t61_L-IACNcBGAsYHQ/%25E3%2582%25B9%25E3%2582%25AF%25E3%2583%25AA%25E3%2583%25BC%25E3%2583%25B3%25E3%2582%25B7%25E3%2583%25A7%25E3%2583%2583%25E3%2583%2588%2B2020-11-07%2B11.34.46.png" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="434" data-original-width="767" height="181" src="https://lh3.googleusercontent.com/-LnXKMVyEQUM/X6YrJ4FEkaI/AAAAAAAAXzo/6tBcDziMFds2V89A1zOCB4bd1t61_L-IACNcBGAsYHQ/%25E3%2582%25B9%25E3%2582%25AF%25E3%2583%25AA%25E3%2583%25BC%25E3%2583%25B3%25E3%2582%25B7%25E3%2583%25A7%25E3%2583%2583%25E3%2583%2588%2B2020-11-07%2B11.34.46.png" width="320" /></a></div></div><div><br /></div><h3 style="text-align: left;">Fortniteのアプリファイル(ipa)を新しいiPhone 12にインストール</h3><div>出力したipaファイルのインストールもiMazingを利用します。</div><div>iMazingの左側の画面からインストール先の新しいiPhone 12を選択してください。</div><div><br /></div><div>画面下に表示されている「デバイスにコピー」をクリックします。</div><div><br /></div><div><div class="separator" style="clear: both; text-align: center;"><a href="https://lh3.googleusercontent.com/-Qt2f8HzdWrM/X6YsFaNvydI/AAAAAAAAXzw/BQVitqO1hB8EgV9xQe8N_53dwktT69NkwCNcBGAsYHQ/%25E3%2582%25B9%25E3%2582%25AF%25E3%2583%25AA%25E3%2583%25BC%25E3%2583%25B3%25E3%2582%25B7%25E3%2583%25A7%25E3%2583%2583%25E3%2583%2588%2B2020-11-07%2B14.08.17.png" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="844" data-original-width="1210" height="223" src="https://lh3.googleusercontent.com/-Qt2f8HzdWrM/X6YsFaNvydI/AAAAAAAAXzw/BQVitqO1hB8EgV9xQe8N_53dwktT69NkwCNcBGAsYHQ/%25E3%2582%25B9%25E3%2582%25AF%25E3%2583%25AA%25E3%2583%25BC%25E3%2583%25B3%25E3%2582%25B7%25E3%2583%25A7%25E3%2583%2583%25E3%2583%2588%2B2020-11-07%2B14.08.17.png" width="320" /></a></div><br /><br />先程、エクスポートした「Fortnite 13.40.1.ipa」ファイルを選択すると、インストールが始まります。<br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://lh3.googleusercontent.com/-8-j6jQS0qsY/X6YsXGiDcHI/AAAAAAAAXz4/_LJRdURyifc32INDYtzEflCE-QqbhvjKACNcBGAsYHQ/%25E3%2582%25B9%25E3%2582%25AF%25E3%2583%25AA%25E3%2583%25BC%25E3%2583%25B3%25E3%2582%25B7%25E3%2583%25A7%25E3%2583%2583%25E3%2583%2588%2B2020-11-07%2B11.35.14.png" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="443" data-original-width="791" height="179" src="https://lh3.googleusercontent.com/-8-j6jQS0qsY/X6YsXGiDcHI/AAAAAAAAXz4/_LJRdURyifc32INDYtzEflCE-QqbhvjKACNcBGAsYHQ/%25E3%2582%25B9%25E3%2582%25AF%25E3%2583%25AA%25E3%2583%25BC%25E3%2583%25B3%25E3%2582%25B7%25E3%2583%25A7%25E3%2583%2583%25E3%2583%2588%2B2020-11-07%2B11.35.14.png" width="320" /></a></div><div class="separator" style="clear: both; text-align: center;"><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://lh3.googleusercontent.com/-VOG8riIZpIE/X6YsiKV8W9I/AAAAAAAAX0A/-LdQA6k49AswFL2rbo5faFRHikS6tq6rACNcBGAsYHQ/%25E3%2582%25B9%25E3%2582%25AF%25E3%2583%25AA%25E3%2583%25BC%25E3%2583%25B3%25E3%2582%25B7%25E3%2583%25A7%25E3%2583%2583%25E3%2583%2588%2B2020-11-07%2B11.35.54.png" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="233" data-original-width="455" height="164" src="https://lh3.googleusercontent.com/-VOG8riIZpIE/X6YsiKV8W9I/AAAAAAAAX0A/-LdQA6k49AswFL2rbo5faFRHikS6tq6rACNcBGAsYHQ/%25E3%2582%25B9%25E3%2582%25AF%25E3%2583%25AA%25E3%2583%25BC%25E3%2583%25B3%25E3%2582%25B7%25E3%2583%25A7%25E3%2583%2583%25E3%2583%2588%2B2020-11-07%2B11.35.54.png" width="320" /></a></div><div class="separator" style="clear: both; text-align: center;"><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://lh3.googleusercontent.com/-04GW6_cHHLA/X6YsiEWmyeI/AAAAAAAAXz8/1SE2sSBDDK8ymF8OT5PXgnhMUZYLaSZQgCNcBGAsYHQ/%25E3%2582%25B9%25E3%2582%25AF%25E3%2583%25AA%25E3%2583%25BC%25E3%2583%25B3%25E3%2582%25B7%25E3%2583%25A7%25E3%2583%2583%25E3%2583%2588%2B2020-11-07%2B12.03.59.png" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="227" data-original-width="456" height="159" src="https://lh3.googleusercontent.com/-04GW6_cHHLA/X6YsiEWmyeI/AAAAAAAAXz8/1SE2sSBDDK8ymF8OT5PXgnhMUZYLaSZQgCNcBGAsYHQ/%25E3%2582%25B9%25E3%2582%25AF%25E3%2583%25AA%25E3%2583%25BC%25E3%2583%25B3%25E3%2582%25B7%25E3%2583%25A7%25E3%2583%2583%25E3%2583%2588%2B2020-11-07%2B12.03.59.png" width="320" /></a></div></div></div></div><div><br /></div><div>「Fortniteをインストールしました」と表示されれば、無事新しいiPhone 12にインストールが完了です。</div><div><div class="separator" style="clear: both; text-align: center;"><a href="https://lh3.googleusercontent.com/-D6_98iq2u24/X6YtedHRtpI/AAAAAAAAX0U/fyUC8wjBAjg7BctQxtWjmbJ-NOpfidFFQCNcBGAsYHQ/IMG_5734.PNG" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="2532" data-original-width="1170" height="454" src="https://lh3.googleusercontent.com/-D6_98iq2u24/X6YtedHRtpI/AAAAAAAAX0U/fyUC8wjBAjg7BctQxtWjmbJ-NOpfidFFQCNcBGAsYHQ/w210-h454/IMG_5734.PNG" width="210" /></a></div><br /><br /></div><div>新しいiPhone 12でFortniteを楽しみましょう!!</div><div><br /></div><div><div class="separator" style="clear: both; text-align: center;"><a href="https://lh3.googleusercontent.com/-p8MRgSpNX4M/X6Yud0h7qPI/AAAAAAAAX0k/7bSQDdvvRdwhQR1y82CalpD9hisk1MgUwCNcBGAsYHQ/IMG_5733.PNG" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="1170" data-original-width="2532" height="215" src="https://lh3.googleusercontent.com/-p8MRgSpNX4M/X6Yud0h7qPI/AAAAAAAAX0k/7bSQDdvvRdwhQR1y82CalpD9hisk1MgUwCNcBGAsYHQ/w465-h215/IMG_5733.PNG" width="465" /></a></div><div><br /></div><div><br /></div><h3 style="text-align: left;">注意</h3><ul style="text-align: left;"><li>新しいiPhone 12にFortniteをインストールしても、最新のシーズンには参加できません。これまでと同様、iPhoneユーザーだけで閉ざされたチャプター2シーズン3を楽しみましょう。</li><li>Apple IDの異なるiPhoneにはインストールできません。そのため、他人のiPhoneから吸い出したipaファイルを自分のiPhoneにインストールすることはできません。</li><li>当サイトにて紹介した内容で発生した、何らかのトラブルや損失・損害等につきましては一切責任を問わないものとします。当サイトが紹介しているウェブサイトやソフトウェアの合法性、正確性、道徳性、最新性、適切性、著作権の許諾や有無など、その内容については一切の保証を致しかねます。</li></ul></div><div><br /></div><p><br /></p><p><br /></p>kassy708http://www.blogger.com/profile/00025482097446561673noreply@blogger.com0tag:blogger.com,1999:blog-171901102439270531.post-27120157097183231352017-11-18T16:13:00.003+09:002017-11-18T16:13:30.706+09:00快適なVR体験のために視力矯正手術ICL手術を受けてきました。(感想:1年後)ICL手術のその後について前回の更新から11ヶ月経ってしまいましたが、特に何もなかったので気がついたら更新を忘れていました。<br />
<br />
手術から1年経ち、目の調子は全く問題ありません。<br />
先日、1年後定期検診に行き、特に問題なしということでした。<br />
<br />
その間にも3ヶ月後検診、半年後検診も行きましたが、特に問題なしです。<br />
<br />
<br />
ただ、視力は2.0→1.5となっていましたが、2.0は見えすぎて辛かったので1.5で落ち着いたという印象です。<br />
<br />
近くも見えるようになっているので、このくらいがちょうどいいかなと思います。<br />
ただ、これ以上悪くなると困るので、1.5をキープしてくれると嬉しいなぁ・・・<br />
<br />
<br />
これで保証期間が終了してしまったので、今後何か起こると有料となります。<br />
何も異常が無いことを祈って過ごして行きたいと思います。<br />
<br />
<br />kassy708http://www.blogger.com/profile/00025482097446561673noreply@blogger.com3tag:blogger.com,1999:blog-171901102439270531.post-47105483342751289852017-01-04T16:49:00.002+09:002017-01-04T16:49:43.726+09:00快適なVR体験のために視力矯正手術ICL手術を受けてきました。(感想:1か月目)<span style="background-color: #fefdfa; color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px;">ICL手術を受けてから1か月。</span><br style="background-color: #fefdfa; color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px;" /><span style="background-color: #fefdfa; color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px;">定期検診に行ってきました。</span><br />
<span style="background-color: #fefdfa; color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px;"><br /></span>
<span style="background-color: #fefdfa; color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px;">特に異常なく、視力も両目2.0のまま安定しています。</span><br />
<span style="background-color: #fefdfa; color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px;"><br /></span>
<span style="background-color: #fefdfa; color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px;"><br /></span>
<span style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;">最初もらった目薬は3種類</span></span><br />
<span style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;">抗菌1種、抗炎症2種でしたが、今回もらったのは抗炎症剤1種のみでした。</span></span><br />
<span style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;"><br /></span></span>
<span style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;">2ヶ月後の3ヶ月検診まではこれだけでよいらしいです。</span></span><br />
<span style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;"><br /></span></span>
<span style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;">手術で切った目の痛みもほぼなくなってきて、くしゃみして目をギュッと閉じても大丈夫になりました。</span></span><br />
<span style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;"><br /></span></span>
<span style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;"><br /></span></span>
<span style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;">まだスマホを見続けると目がしんどいですが、ほぼほぼ慣れてきましたね。</span></span><br />
<span style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;"><br /></span></span>
<span style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;"><br /></span></span>
<span style="background-color: #fefdfa; color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px;">それでは、次は3ヶ月検診ということで</span><span style="background-color: #fefdfa; color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px;">2ヶ月</span><span style="background-color: #fefdfa; color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px;">後です!</span><br style="background-color: #fefdfa; color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px;" /><span style="background-color: #fefdfa; color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px;"><br /></span><span style="background-color: #fefdfa; color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px;"></span><span style="background-color: #fefdfa; color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px;">-----------</span><br style="background-color: #fefdfa; color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px;" /><span style="background-color: #fefdfa; color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px;">新宿近くで視力矯正に興味のある方は友達紹介制度で割引できます!</span><br style="background-color: #fefdfa; color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px;" /><span style="background-color: #fefdfa; color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px;">私も紹介料がもらえるので嬉しいです</span><br style="background-color: #fefdfa; color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px;" /><span style="background-color: #fefdfa; color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px;">もしご興味がありましたらお声がけください!</span><br style="background-color: #fefdfa; color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px;" /><span style="background-color: #fefdfa; color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px;"><br /></span><span style="background-color: #fefdfa; color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px;"></span><span style="background-color: #fefdfa; color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px;">ICL以外にもレーシック、オルソケラトロジーなど他の手術でも紹介制度がつかえるそうです。</span><br style="background-color: #fefdfa; color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px;" /><span style="background-color: #fefdfa; color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px;"><br /></span><span style="background-color: #fefdfa; color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px;"></span><span style="background-color: #fefdfa; color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px;">ご連絡は<a href="https://twitter.com/kassy708" style="color: #7d181e; text-decoration: none;" target="_blank">Twitter</a>のDMにてどうぞ!</span>kassy708http://www.blogger.com/profile/00025482097446561673noreply@blogger.com0tag:blogger.com,1999:blog-171901102439270531.post-6725627924895836072016-12-12T01:52:00.004+09:002016-12-12T01:52:53.860+09:00快適なVR体験のために視力矯正手術ICL手術を受けてきました。(感想:二週間目)<span style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;">ICL手術を受けてから二週間。</span></span><br />
<span style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;">定期検診に行ってきました。</span></span><br />
<span style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;"><br /></span></span>
<span style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;">視力では両目ともに2.0。</span></span><br />
<span style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;">見え方は良好。</span></span><br />
<span style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;"><br /></span></span>
<span style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;">特に問題なしで10分ほどで終了しました。</span></span><br />
<span style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;"><br /></span></span>
<span style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;">最近は見えすぎて目が疲れやすいので近くが見えやすい眼鏡がほしいかも・・・</span></span><br />
<span style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;"><br /></span></span>
<span style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;">抗菌と抗炎症の目薬は4時間に1回ということでしたが、目にゴミが入ったり乾いたら目薬が入れたくなるので、涙の成分に近い目薬をもらってきました。</span></span><br />
<span style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;"><br /></span></span>
<span style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;">これで朝とか目を洗うときにも使えそうです。</span></span><br />
<span style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;"><br /></span></span>
<span style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;"><br /></span></span>
<span style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;">左目はほぼ痛みもなくなりましたが、右目はまだ目をぎゅっと閉じると痛みを感じます</span></span><br />
<span style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;">お医者さんにはやっちゃだめとは言われつつ、くしゃみとかするときはどうしても無意識に起きてしまうのでどうしようもないのです・・・</span></span><br />
<span style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;"><br /></span></span>
<span style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;"><br /></span></span>
<span style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;">それでは、次は1ヶ月検診ということで二週間後です!</span></span><br />
<span style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;"><br /></span></span>
<span style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;">-----------</span></span><br />
<span style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;">新宿近くで視力矯正に興味のある方は友達紹介制度で割引できます!</span></span><br />
<span style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;">私も紹介料がもらえるので嬉しいです</span></span><br />
<span style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;">もしご興味がありましたらお声がけください!</span></span><br />
<span style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;"><br /></span></span>
<span style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;">ICL以外にもレーシック、オルソケラトロジーなど他の手術でも紹介制度がつかえるそうです。</span></span><br />
<span style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;"><br /></span></span>
<span style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;">ご連絡は<a href="https://twitter.com/kassy708" target="_blank">Twitter</a>のDMにてどうぞ!</span></span>kassy708http://www.blogger.com/profile/00025482097446561673noreply@blogger.com0tag:blogger.com,1999:blog-171901102439270531.post-12486175361461008732016-12-04T22:58:00.000+09:002016-12-12T01:53:26.329+09:00快適なVR体験のために視力矯正手術ICL手術を受けてきました。(感想:一週間目)<span style="background-color: #fefdfa; color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif; font-size: 13px;">ICL手術を受けてから一週間。</span><br />
<span style="background-color: #fefdfa; color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif; font-size: 13px;">定期検診に行ってきました。</span><br />
<span style="background-color: #fefdfa; color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif; font-size: 13px;"><br /></span>
<span style="background-color: #fefdfa; color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif; font-size: 13px;">最初に視力を検査しました。</span><br />
<span style="background-color: #fefdfa; color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif; font-size: 13px;"><br /></span>
<span style="background-color: #fefdfa; color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif; font-size: 13px;">両目ともに2.0。</span><br />
<span style="background-color: #fefdfa; color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif; font-size: 13px;">見え方は良好。</span><br />
<span style="background-color: #fefdfa; color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif; font-size: 13px;"><br /></span>
<span style="background-color: #fefdfa; color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif; font-size: 13px;">右目のブレもほぼなくなり、良く見えるようになりました。</span><br />
<span style="background-color: #fefdfa; color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif; font-size: 13px;"><br /></span>
<span style="background-color: #fefdfa; color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif; font-size: 13px;"><br /></span>
<span style="background-color: #fefdfa; color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif; font-size: 13px;">1週間目の検診は瞳孔を入れる目薬を入れるので瞳孔が開くまで40分くらい待ち</span><br />
<span style="background-color: #fefdfa; color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif; font-size: 13px;">10分くらいで検診を行いました。</span><br />
<span style="background-color: #fefdfa; color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif; font-size: 13px;"><br /></span>
<span style="background-color: #fefdfa; color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif; font-size: 13px;">特に問題無いようなので次は1週間後の2週間目検診となります。</span><br />
<span style="background-color: #fefdfa; color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif; font-size: 13px;"><br /></span>
<span style="background-color: #fefdfa; color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif; font-size: 13px;"><br /></span>
<span style="background-color: #fefdfa; color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif; font-size: 13px;"><br /></span>
<span style="background-color: #fefdfa; color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif; font-size: 13px;">この一週間は月曜日から金曜日までガッツリ仕事をしました。</span><br />
<span style="color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;">病院から貰った資料には一週間はPC作業など目を酷使する仕事は控えるように書かれていましたが、仕事なのでそうもいってられません。</span></span><br />
<span style="background-color: #fefdfa; color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif; font-size: 13px;"><br /></span>
<span style="background-color: #fefdfa; color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif; font-size: 13px;">基本的には一日中デスクでPCと睨み合う仕事なので目が疲れました。</span><br />
<span style="background-color: #fefdfa; color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif; font-size: 13px;"><br /></span>
<span style="background-color: #fefdfa; color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif; font-size: 13px;">両目ともに2.0ということですごく良くなったのですが、代わりにデスクワークが疲れやすくなりました・・・</span><br />
<span style="background-color: #fefdfa; color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif; font-size: 13px;">金曜日は目が疲れて頭痛になり、いつもより早めに退社。</span><br />
<span style="background-color: #fefdfa; color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif; font-size: 13px;">保護メガネをかけるせいで余計に疲れたのかもしれません。</span><br />
<span style="background-color: #fefdfa; color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif; font-size: 13px;"><br /></span>
<span style="background-color: #fefdfa; color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif; font-size: 13px;">もう少し度数が弱いレンズを入れて貰えばよかったな、と思いました。</span><br />
<span style="background-color: #fefdfa; color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif; font-size: 13px;"><br /></span>
<span style="color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;">そういえば、入れるレンズの度数とか最初に指定や説明がなかったなぁっと今更ながら気づく。</span></span><br />
<span style="color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;"><br /></span></span>
<span style="color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;">もともとかけていたメガネは-7.5Dの度数ですが、最初の検査で測った時は視力は-7.7Dと言われました。</span></span><br />
<span style="color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;">その時は目が疲れていて見えづらい状態だったので、通常より視力が落ちてしまっていたのかもしれません。</span></span><br />
<span style="color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;">その時の度数に合わせて作ってしまったのか、少し強すぎたように思います。</span></span><br />
<span style="color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;"><br /></span></span>
<span style="color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;">今のところ2.0で困ることはないですが、この目の疲れがずっと続くのか</span></span><br />
<span style="color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;">もしくは、慣れれば済むものなのか。</span></span><br />
<span style="color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;"><br /></span></span>
<span style="color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;">日頃、10時間以上PCの画面で仕事して、息抜きにスマホでゲームしたりネットサーフィンするため、意外と近くの見やすさも重要ということがわかりました</span></span><br />
<span style="color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;"><br /></span></span>
<span style="color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;">もう少し度数が低くてもよかったなと思います。</span></span><br />
<span style="color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;"><br /></span></span>
<span style="color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;"><br /></span></span>
<span style="color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;">あと、保護メガネがすごくうざいです。</span></span><br />
<span style="color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;">すごく曇りやすいですし、ズリ落ちていつも眼球の上の方で支えてたのですごく痛い。</span></span><br />
<span style="color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;">一週間で外せるのでようやくスッキリしました。</span></span><br />
<span style="color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;"><br /></span></span>
<span style="color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;">まだ、1ヶ月は目に水が入らないようにしないといけないので、気をつけないといけないですが</span></span><br />
<span style="color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;">ようやく裸眼生活に突入できます。</span></span><br />
<span style="color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;"><br /></span></span>
<span style="color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;">検診の時にお医者さんにどのくらいで傷口が塞がるのか聞いたところ</span></span><br />
<span style="color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;">表面が閉じるのが1ヶ月、内側まで完全に閉じるには1年かかるらしいです。</span></span><br />
<span style="color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;"><br /></span></span>
<span style="color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;">結構長い・・・</span></span><br />
<span style="color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;"><br /></span></span>
<span style="color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;">お風呂上がりや汗を書いた時に顔を軽く拭いた際、まぶたを横にこするとすごく痛むことがあります</span></span><br />
<span style="background-color: #fefdfa; color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif; font-size: 13px;">多分、切った傷口はまだ塞がっておらず、こすった時に開いてたのかなと思います。</span><br />
<span style="background-color: #fefdfa; color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif; font-size: 13px;">傷口が開くと、そこから細菌が入って炎症を起こすので絶対やっちゃダメとお医者さんに怒られました。</span><br />
<span style="background-color: #fefdfa; color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif; font-size: 13px;"><br /></span>
<span style="background-color: #fefdfa; color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif; font-size: 13px;">まだまだ万全の状態には時間がかかりそうです。</span><br />
<span style="background-color: #fefdfa; color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif; font-size: 13px;"><br /></span>
<br />
<br />
<span style="color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;">1ヶ月経って傷が塞がったら、いろんなところに遊びに行きたいです。</span></span><br />
<span style="color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;"><br /></span></span>
<span style="color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;"><br /></span></span>
<span style="color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;">それではまた<a href="http://kassymemo.blogspot.jp/2016/12/vricl_12.html" target="_blank">一週間後</a>!</span></span><br />
<span style="color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;"><br /></span></span>
<span style="color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;"><br /></span></span>
<span style="background-color: #fefdfa; color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif; font-size: 13px;">-----------</span><br />
<span style="background-color: #fefdfa; color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif; font-size: 13px;">新宿近くで視力矯正に興味のある方は友達紹介制度で割引できます!</span><br />
<span style="background-color: #fefdfa; color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif; font-size: 13px;">私も紹介料がもらえるので嬉しいです</span><br />
<span style="background-color: #fefdfa; color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif; font-size: 13px;">もしご興味がありましたらお声がけください!</span><br />
<br style="background-color: #fefdfa; color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px;" />
<span style="background-color: #fefdfa; color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif; font-size: 13px;">ICL以外にもレーシック、オルソケラトロジーなど他の手術でも紹介制度がつかえるそうです。</span><br />
<br style="background-color: #fefdfa; color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px;" />
<span style="background-color: #fefdfa; color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif; font-size: 13px;">ご連絡は</span><a href="https://twitter.com/kassy708" style="background-color: #fefdfa; color: #7d181e; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px; text-decoration: none;" target="_blank">Twitter</a><span style="background-color: #fefdfa; color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif; font-size: 13px;">のDMにてどうぞ!</span><br />
<span style="background-color: #fefdfa; color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif; font-size: 13px;"><br /></span>
<span style="color: #333333; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif;"><span style="background-color: #fefdfa; font-size: 13px;"><br /></span></span>kassy708http://www.blogger.com/profile/00025482097446561673noreply@blogger.com0tag:blogger.com,1999:blog-171901102439270531.post-32080097404974396072016-11-27T23:19:00.002+09:002016-12-04T22:58:22.441+09:00快適なVR体験のために視力矯正手術ICL手術を受けてきました。(感想:3日目)ICL手術を受けてから3日目。<br />
<br />
朝目が覚めると、右目の痛みはほぼほぼ無くなりました。<br />
<br />
両目ともに曇りも無くなり、いい感じです。<br />
僅かに右目に乱視のようなブレがありますが、まあ許容範囲。<br />
<br />
3日目検診に行った所、右目1.5、左目2.0と良い感じ。<br />
右目が少しブレることをお医者さんに相談したところ、まだ目の炎症も収まっていないのでこれから治っていきますよ、とのことでした。<br />
<br />
この3日間通っていますが、この医院のお医者さんの対応がちょっとそっけないかなぁっと感じたりしてます。<br />
<br />
<br />
検診は10分ほどで終わったので、新宿をぶらぶらして帰りました。<br />
<br />
明日から月曜日、仕事を再開なのでPC見続けるデスクワークに耐えられるか心配です・・・<br />
<br />
次は<a href="http://kassymemo.blogspot.jp/2016/12/vricl.html" target="_blank">一週間後検診</a>!<br />
早く顔をガシガシ洗いたい!<br />
<br />
-----------<br />
新宿近くで視力矯正に興味のある方は友達紹介制度で割引できます!<br />
私も紹介料がもらえるので嬉しいです<br />
もしご興味がありましたらお声がけください!<br />
<br />
ICL以外にもレーシック、オルソケラトロジーなど他の手術でも紹介制度がつかえるそうです。<br />
<br />
ご連絡は<a href="https://twitter.com/kassy708" target="_blank">Twitter</a>のDMにてどうぞ!kassy708http://www.blogger.com/profile/00025482097446561673noreply@blogger.com0tag:blogger.com,1999:blog-171901102439270531.post-91037437380355933162016-11-26T21:36:00.000+09:002016-11-26T21:59:57.027+09:00快適なVR体験のために視力矯正手術ICL手術を受けてきました。(感想:2日目)今日はICL手術の2日目ということで翌日検査に行ってきました。<br />
<br />
眼圧チェック問題なし、視力両目1.5、炎症やレンズのズレなどもなく、全く問題なしとのことです!<br />
<br />
検査は15分くらいで終了して帰宅しました。<br />
<br />
<br />
実際、左目はほぼ完璧、右目は少し充血して視界がぼやけていますが、時間が経てば治るそうです。<br />
手術後は目に触れてはいけないため、保護メガネを付けているので裸眼の感じが薄いのですが、それでもこんなによく見えるのかとびっくりします。<br />
<br />
ただ、まだ眼が乾くと瞬きの際に痛いので、なるべく目薬をさすようにしています。<br />
<br />
<br />
目の保護でめんどくさいのは寝る時は眼帯を付けて寝る必要があることです。<br />
これが結構鬱陶しい。<br />
<br />
寝返りをしようとすると、眼に眼帯がぶつかって「やべ、仰向けにならなきゃ」って目が覚めるので熟睡できません。<br />
<br />
<br />
保護メガネもサイズがあっていないのか、ズレ下がってきたり、しっかり装着するとまぶたにメガネが当たって痛いです。<br />
<br />
1週間はこれを続けないといけないそうなのでゲンナリしますね・・・<br />
<br />
<br />
眼に水などが入ってはいけないので、洗顔ができません。<br />
そのため、目が覚めて目やにを取るのが大変です。<br />
大量に目薬をさして、ティッシュで拭き取っています。(あんまりいい方法じゃない気がする・・・)<br />
<br />
お風呂も首から下しか洗えないので、顔はレンチンした濡れタオルで軽く拭く程度です。<br />
もっと、ガシガシ洗いたい・・・<br />
<br />
やっぱり手術後が一番めんどくさいですね。<br />
<br />
<br />
<br />
手術後はどんな感じかというと、コンタクトを付けたような感じです。<br />
メガネをかけなくてもよく見えますが、少しゴロゴロする感じがあります。(傷口のせいかもしれません。)<br />
<br />
後、夜間の見え方ですが、やはりハロ・グレアが発生しています。<br />
以前からメガネのときでも電灯を見ると、周りにBloomがかかったような光の拡散が見えましたが、その大きさが倍くらいになった気がします。<br />
右目はまだ視界がぼやけているせいもあり、左目より大きくなっています。<br />
<br />
まあ、光で周りが見えなかったり眩しく感じるということは無いので問題はなさそうです。<br />
また、視力が安定すれば、ハロ・グレアも小さくなるそうです。<br />
<br />
<br />
あと、気になったのは強い光を見るとICL特有のリングが見えることですね。<br />
<br />
ホール型ICLは眼内の液体の循環を行うために穴を開けているのですが、これにより強い光を見ると輪っかが見えるそうです。<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-IbXzw0tlPuA/WDl4gjw0ZMI/AAAAAAAACUQ/D3WVMP-O10AoO-zeIcAcyXK1wUEjzfsLgCLcB/s1600/icl_img08.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="133" src="https://4.bp.blogspot.com/-IbXzw0tlPuA/WDl4gjw0ZMI/AAAAAAAACUQ/D3WVMP-O10AoO-zeIcAcyXK1wUEjzfsLgCLcB/s200/icl_img08.png" width="200" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
日中、太陽の下や、夜の電灯や車のヘッドライトが当たると、視界の中心から視界の半分くらいの半径のリングが見えます。</div>
<div class="separator" style="clear: both; text-align: left;">
レンズフレアの輪っかのイメージです。</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
光が多いところだとリングが視界の端に大量に見えるのでわりと鬱陶しいです。</div>
これはICLのレンズ上、しょうがないですね。<br />
慣れるしかなさそうです。<br />
<br />
強い光を見たイメージはこんな感じです。<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-4E6WtuKtop0/WDmEj0TNBMI/AAAAAAAACUg/6_rLFoUY38gZe30fK5uN8mgm6lBeH0USACLcB/s1600/%25E3%2583%258F%25E3%2583%25AD%25E3%2583%25BB%25E3%2582%25B0%25E3%2583%25AC%25E3%2582%25A2%25E3%2582%25A4%25E3%2583%25A1%25E3%2583%25BC%25E3%2582%25B8%25E5%2589%258D.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="197" src="https://3.bp.blogspot.com/-4E6WtuKtop0/WDmEj0TNBMI/AAAAAAAACUg/6_rLFoUY38gZe30fK5uN8mgm6lBeH0USACLcB/s200/%25E3%2583%258F%25E3%2583%25AD%25E3%2583%25BB%25E3%2582%25B0%25E3%2583%25AC%25E3%2582%25A2%25E3%2582%25A4%25E3%2583%25A1%25E3%2583%25BC%25E3%2582%25B8%25E5%2589%258D.png" width="200" /></a><a href="https://3.bp.blogspot.com/-wHdikZdhCpE/WDmEkXSfAuI/AAAAAAAACUk/e5XV3xIxhc0TUIo_AHAtjA_il1ezZammgCLcB/s1600/%25E3%2583%258F%25E3%2583%25AD%25E3%2583%25BB%25E3%2582%25B0%25E3%2583%25AC%25E3%2582%25A2%25E3%2582%25A4%25E3%2583%25A1%25E3%2583%25BC%25E3%2582%25B8.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="197" src="https://3.bp.blogspot.com/-wHdikZdhCpE/WDmEkXSfAuI/AAAAAAAACUk/e5XV3xIxhc0TUIo_AHAtjA_il1ezZammgCLcB/s200/%25E3%2583%258F%25E3%2583%25AD%25E3%2583%25BB%25E3%2582%25B0%25E3%2583%25AC%25E3%2582%25A2%25E3%2582%25A4%25E3%2583%25A1%25E3%2583%25BC%25E3%2582%25B8.png" width="200" /></a> </div>
<div class="separator" style="clear: both; text-align: center;">
手術前 → 手術後</div>
<br />
<br />
<br />
それでは、次回は明日の2日後検診です。<br />
<br />
<br />
-----------<br />
新宿近くで視力矯正に興味のある方は友達紹介制度で割引できます!<br />
私も紹介料がもらえるので嬉しいです<br />
もしご興味がありましたらお声がけください!<br />
<br />
ICL以外にもレーシック、オルソケラトロジーなど他の手術でも紹介制度がつかえるそうです。<br />
<br />
ご連絡は<a href="https://twitter.com/kassy708" target="_blank">Twitter</a>のDMにてどうぞ!kassy708http://www.blogger.com/profile/00025482097446561673noreply@blogger.com0tag:blogger.com,1999:blog-171901102439270531.post-23473010233628881242016-11-25T23:01:00.002+09:002016-11-26T21:37:29.862+09:00快適なVR体験のために視力矯正手術ICL手術を受けてきました。(感想:手術当日)2016/11/25(金)有給を取り、ICL手術を受けに行きました!<br />
<br />
10時半に病院へ着き、受付。<br />
手術に関する誓約書を提出し、支払いを行いました。<br />
<br />
60万円の手術ですが、資料請求をした際に割引3万円のチケットが入っていたので57万円で済みました。<br />
<br />
事前の検査時に予約を行い、その場でレンズ代30万円を支払っていたので当日の支払いは27万円。<br />
クレジットカードで支払いを行ったところいつも使っているカードが上限で使えなかったので、めったに使わない2枚目のカードで支払いを行いました。<br />
危ないw<br />
<br />
<br />
11時45分くらいから瞳孔を開く目薬や麻酔の目薬を入れていきました。<br />
1時間くらいかけて何度も入れるため待合室に流れているハウルの動く城をずっと見て時間を潰していました。懐かしい・・・。<br />
<br />
その後、眼の検査をして別室へ。<br />
カーテンが閉められた狭い部屋で座り心地の良い椅子で再度30分ほどかけて目薬を何度も入れていきました。<br />
<br />
一通り目薬を入れ終わった後は手術後1週間やらないといけない事や気をつけないといけない事の説明を聞きました。<br />
日中は3~4時間に1度目薬をさすこと。寝る時は眼帯を付けて寝ること。体は洗ってもいいけど顔はNG。濡れたタオルで洗うなどはOKなど。<br />
<br />
その時もらった資料はこんな感じです。<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-qvLd-SVhtBc/WDg87inZ0mI/AAAAAAAACTw/vjNA2IBItFE39MNQ1KRa7wMcfoIyIqwBQCLcB/s1600/30424352833_356f2684e7_o.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="225" src="https://1.bp.blogspot.com/-qvLd-SVhtBc/WDg87inZ0mI/AAAAAAAACTw/vjNA2IBItFE39MNQ1KRa7wMcfoIyIqwBQCLcB/s400/30424352833_356f2684e7_o.jpg" width="400" /></a></div>
<br />
<br />
そしていざ、手術台へ<br />
メガネを外したまま案内されたので、手術室の様子はよくわかりませんでした・・・<br />
<br />
<br />
4,5人のお医者さんが周りにいましたが、主に手術をするのは2人。<br />
<br />
初めに麻酔の注射をうった後、手術する眼だけを出すマスクのようなのを被せられ、シールで固定。<br />
そして、眼が閉じないように固定する器具でまぶたを固定されました。<br />
(アニメとかの拷問シーンで出て来るやつだ・・・って何故かドキドキしました。)<br />
<br />
眼の中を消毒液で洗い流したり、眼の周りを筆?のようなもので消毒していきました。<br />
<br />
<br />
そしていざレンズ注入!<br />
<br />
手術中は洗浄液で目の前はほぼ何も見えず、光がキラキラしている感じでした。<br />
手術台の照明をまっすぐ見るように言われるのですが、眩しすぎて直視するのが難しいw<br />
瞳孔開いてるからかすごい眩しいし、反射的に眼が別のところ見てしまう。<br />
しばらく見ているとだんだん眩しさが麻痺してくるのでどうにかまっすぐ見れました。<br />
<br />
まっすぐ見るように言われているのですが、目の横を切開しているのかレンズを押し込んでいるのか、無理やり眼が別の方向に向かされてしまうのでちょっと怖いですね。<br />
<br />
麻酔のおかげで、痛みはほとんどありませんでした。<br />
普段生活していて間違えて眼に指を突っ込んだときのほうが全然痛いです。<br />
<br />
ただ、ここで間違えて眼を変な方向を向いてしまうとレンズの位置がズレたり切り口がひどいことになりそうですごく怖いです。<br />
眩しい光や時々くる痛みで反射的に動かさないように必死で、緊張しすぎて肩凝りましたw<br />
<br />
<br />
右目にレンズを入れた後は左目。<br />
どちらも順調に進み、特に問題なく終わりました。<br />
大体片目で15分くらいでしょうか。<br />
<br />
終わってみればあっという間でしたが、手術中はかなり長く感じます。<br />
お医者さんの「あ」とか「もうちょっと・・・」というようなつぶやきがすごく不安になりますw<br />
<br />
<br />
手術後は、前にいた個室で目薬を指して1時間ほど目を閉じて安静。<br />
寝ててもいいですよと言われましたが、さっきまであんなことされた後だったのでとても寝れず、ずっと眼を閉じてVRゲームの仕様を考えてました。<br />
<br />
1時間たった後は眼の検査を行いました。<br />
眼圧チェックや多分、レンズがズレていないか、出血がひどくないかなど見てもらいました。<br />
<br />
検査の結果、眼圧は平常。レンズもOK.。手術後は結構充血する人が多いそうですが、私はそのあたりも大丈夫そうでした。<br />
途中、自分で鏡を見た時は少し右目の一部が赤くなっていまいたが、たしかにそれほどひどくない様子。<br />
<br />
問題なし!ということで無事手術は終了しました。<br />
<br />
<br />
その後は帰ってよいとのことだったのですが、やはり手術後は視力が安定せず待合室でゆっくりしました。<br />
<br />
イメージとしては朝ひどい目やにがついているかのように視界がボケた感じです。<br />
実際、目薬を入れまくったためか目やにが多く、鏡をみると黒目の上に目やにがいくつも浮いていました。<br />
目薬を入れてティッシュで拭いて洗い流そうとしましたが流れず・・・<br />
<br />
しばらくしても改善しなかったので帰りました。<br />
<br />
病院を出たのが14時だったので、大体手術に3時間半くらいで終了という感じですね。<br />
<br />
<br />
帰ってからは取りためたアニメを見てぼーっと過ごしていましたが、視界の曇がなかなか晴れず、目が疲れてきたので仮眠を取りました。<br />
<br />
20時ごろに起きて、せっかくなので手術のことをメモしようとブログに書いてみました。<br />
<br />
<br />
左目はだいたい曇りが晴れてきたのですが右目はまだわずかに曇って異物感があります。右目は少し充血しているので治るまでに時間がかかりそうですね。<br />
<br />
手術後には定期検診があり<br />
1日、2日、1週間、2週間、1ヶ月、3ヶ月、6ヶ月、1年と検診を行います。<br />
<br />
ここで問題が起きていなければOKということですね!<br />
<br />
レンズのズレや眼の中に細菌が入るとめんどくさいようなので、問題が起きないかすごく心配です・・・<br />
<br />
<br />
また、検診のたびにブログに術後の様子を書いてみますね。<br />
<br />
それでは次回は<a href="http://kassymemo.blogspot.jp/2016/11/vricl2.html">翌日検診</a>にて。<br />
<br />
-----------<br />
新宿近くで視力矯正に興味のある方は友達紹介制度で割引できます!<br />
私も紹介料がもらえるので嬉しいです<br />
もしご興味がありましたらお声がけください!<br />
<br />
ICL以外にもレーシック、オルソケラトロジーなど他の手術でも紹介制度がつかえるそうです。<br />
<br />
ご連絡は<a href="https://twitter.com/kassy708" target="_blank">Twitter</a>のDMにてどうぞ!kassy708http://www.blogger.com/profile/00025482097446561673noreply@blogger.com0tag:blogger.com,1999:blog-171901102439270531.post-54478212998975931682016-11-25T21:47:00.000+09:002016-11-26T22:00:54.685+09:00快適なVR体験のために視力矯正手術ICL手術を受けてきました。(感想:前日談)VR元年となり、様々なVR機器が発売された2016年<br />
いろんなVRを遊んでいるうちにメガネがすごく鬱陶しく感じ始めました。<br />
<br />
そこで夏頃にICL(有水晶体眼内レンズ)手術というものを知り、興味を持ちました。<br />
ICL参考:<a href="https://jp.discovericl.com/">https://jp.discovericl.com/</a><br />
<br />
そして今日(2016/11/25)、思い切ってICLの手術を受けて来ました!<br />
<br />
せっかくなのでICL手術の感想を残しておこうと思います!<br />
<br />
<br />
■はじめに<br />
私の眼の悪さは小学1年生ごろにゲームのしすぎで0.3まで落ちてしまい、その頃からずっとメガネ生活でした。<br />
高校に入ってからはコンタクトを入れていましたが、PC作業をしていると目がシバシバしたりズレて見えづらかったりとストレスになるので、大学の途中からは付けなくなりました。<br />
手術する前は目の前10cm以下しか見えないくらいの視力で、検査時に計ったときは-7.7Dとのことでした。<br />
<br />
Oculus DK1が発売されたとき、大学・大学院でもVRを研究していたので3万円の価格と視野角の広さに感動して色々開発したり遊んでいました。<br />
<br />
ただ、そこで一番のストレスはメガネがぶつかって痛いことでした。<br />
<br />
その頃からメガネが邪魔だなと思いつつ、きっと将来はVR HMDには度数調整機能がつくだろうと期待して待っていたのですが、その機能を持って発売されたのはGear VRだけでした・・・(細かくいうとOSVRなどもありますが)<br />
Gear VRの度数調整は神機能だと思ったのですが、一番VRを楽しむにはPC,PS4のようなHD系VRコンテンツなので、すごくがっかりしました。Gear VRにもあったんだから、Riftには確実につくと期待していたのですが・・・<br />
まだ、HTC ViveとPSVRはメガネが入りやすい作りなので我慢できましたが、Riftは入りづらくメガネを付けているとHMDの装着自体が結構大変です。HMDを被る事自体が億劫になってしまいます。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-BvpiMu36Q1k/WDhHMksLbzI/AAAAAAAACUA/NQmfmorDpks2Fho1CvXbWa8C9BbTwf8aQCLcB/s1600/IMG_3693.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="300" src="https://3.bp.blogspot.com/-BvpiMu36Q1k/WDhHMksLbzI/AAAAAAAACUA/NQmfmorDpks2Fho1CvXbWa8C9BbTwf8aQCLcB/s400/IMG_3693.JPG" width="400" /></a></div>
<br />
<br />
<br />
そして、視力矯正を決意したのは夏頃に東京ジョイポリスの<a href="http://tokyo-joypolis.com/attraction/1st/zerolatency/">ゼロレイテンシー</a>でした。オープンした時に直ぐに予約して行ったのですが、そこで装着した<a href="http://vrinside.jp/interview/zero-latency-vr/">OSVR</a>がメガネが全く入らない作りでした・・・<br />
度数調整機能がありましたが、私の視力だと全く足りず、結局ぼやけた視界で敵なのか味方なのかわからないオブジェクトを狙うという経験をして、視力をどうにかしないと今後もVRが楽しめないぞと思い、視力矯正を調べ始めました。<br />
<br />
<br />
■視力矯正の種類<br />
視力矯正を調べると有名なレーシック以外にもいろいろあることがわかりました。<br />
<br />
・レーシック<br />
眼球の表面にある角膜をエキシマレーザーで削り、形状を変えることによって近視や乱視などを矯正する術式<br />
参考URL:<a href="https://sightcure.jp/recovery/lasik01.html">https://sightcure.jp/recovery/lasik01.html</a><br />
<br />
・ReLEx(リレックス)<br />
レーシックもリレックスも、「角膜のカーブを変えて視力を矯正する」点は同じ。ただし、カーブを変える方法はレーシックとリレックスで異なり、レーシックは「フタを開けて角膜を削る」のに対し、リレックスは「小さな穴から角膜を抜き取る」方法で角膜のカーブを変化させる。<br />
<br />
レーシックよりも手術の傷口が小さいため、痛みが少なく、術後の視力回復も早い。また、手術時間も短くすむ。<br />
<br />
・オルソケラトロジー<br />
歯の矯正のように、特殊なハードコンタクトレンズをはめることによって角膜にクセをつけ、光の屈折率を調節して視力を回復する術式。<br />
視力回復の効果が永続的でない反面、コンタクトの使用をやめるだけで角膜を元に戻すことができるため、その分、リスクも少なくすむ<br />
参考URL:<a href="https://sightcure.jp/recovery/orthokeratology/orthokeratology01.html">https://sightcure.jp/recovery/orthokeratology/orthokeratology01.html</a><br />
<div>
<br />
・ICLホールタイプ(眼内コンタクトレンズ)<br />
水晶体と虹彩の間に入れるレンズを挿入する術式。<br />
目への負担が少なく、術後の視力の安定度が高い。また、レンズを取り出せば、眼を元の状態に戻せる。<br />
参考URL:<a href="https://sightcure.jp/recovery/icl.html">https://sightcure.jp/recovery/icl.html</a></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
レーシックは前から興味がありましたが、レーシック難民の話を聞いて怖くてできませんでした。</div>
<div>
(今回の検査でレーシックは適応外だったことがわかったので、そもそも無理だったんですけどw)</div>
<div>
<br /></div>
<div>
一番安全そうなのはオルソケラトロジーのようですが、効果が永続的でないのと、毎晩コンタクトを入れる手間、自分のようなものぐさはハードコンタクトをちゃんと管理できる気がしなかったのでなし。</div>
<div>
<br /></div>
<div>
ICLは説明を読む限り安心そうだったので、ICLに興味を持ち手術を考えました。</div>
<div>
<br /></div>
<div>
しかし、手術代が60万円を超えるとのことだったので、なかなか決心がつかず1ヶ月ほど下調べしてましたw</div>
<div>
<br /></div>
<div>
<br /></div>
<div>
■ICLとは</div>
<div>
眼にレンズを入れて視力を矯正する術式。</div>
<div>
費用が50万円~100万するらしく非常に高いです!</div>
<div>
しかし、レーザーで切り取る非可逆式のレーシックと比べてレンズを入れるICLはレンズを取れば戻せるという点で安全そうです。</div>
<div>
<br /></div>
<div>
といっても完璧な手術というわけではないようで、メリットとデメリットを調べてみました。</div>
<div>
<br /></div>
<div>
・メリット</div>
<div>
1.後遺症リスクが低い</div>
<div>
レーシックのようにドライアイやハロ・グレアが起こりづらいそうです。</div>
<div>
ただ、絶対に起こらないわけではありません。</div>
<div>
レンズの大きさが正しくないと、ハロ・グレアが発生するそうです。</div>
<div>
<br /></div>
<div>
2.レーシック適応外の人でも受けられる</div>
<div>
角膜が薄い人はレーシックが受けれられないようですが、ICLなら角膜を削らないため可能だそうです。</div>
<div>
<br /></div>
<div>
3.再近視化が起こりづらい</div>
<div>
レーシックでは視力が再度悪くなることがある(再近視化)ようですが、ICLは起こりずらいそうです。</div>
<div>
<br /></div>
<div>
4.何か問題があればレンズを取り出すことができる</div>
<div>
レーシックは削ってしまうので戻せませんが、ICLはレンズを取り出せば元に戻ります。</div>
<div>
まあ、レンズを取り出す事態になれば相当まずい状況な気もしますが・・・</div>
<div>
<br /></div>
<div>
<br /></div>
<div>
・デメリット</div>
<div>
1.費用が高い</div>
<div>
50万円~100万するので、軽い気持ちではできないですね・・・</div>
<div>
<br /></div>
<div>
2.手術ができるまで時間がかかる</div>
<div>
レンズはその人にあったものを作るので、だいたい1ヶ月くらいかかります。</div>
<div>
乱視が入ると2ヶ月~3ヶ月かかるそうですね。</div>
<div>
<br /></div>
<div>
3.合併症のリスク</div>
<div>
・白内障のリスク</div>
<div>
レンズの大きさがあっていないと、レンズがズレて水晶体にぶつかり白内障になってしまう可能性があるらしいです。手術後の検診であっていないことがわかればレンズを取り出すそうです。</div>
<div>
また、手術中にミスって水晶体を傷つけると白内障になってしまうそうです。</div>
<div>
めったにないそうですが、これが一番危ないリスクですね・・・</div>
<div>
<br /></div>
<div>
・感染</div>
<div>
手術後は眼に切り込みが入っている状態なので、眼の中に細菌が入ると炎症を起こして治りづらいそうです。</div>
<div>
最悪レンズを取る羽目になるので気をつけないといけません。</div>
<div>
そのため手術前と手術後には細菌を抑制する目薬と炎症を抑える目薬を3時間に1度使います。</div>
<div>
また、日中は保護メガネ、睡眠時は眼帯をして絶対に眼に触れないようにします。</div>
<div>
<br /></div>
<div>
<br /></div>
<div>
■レンズの種類</div>
<div>
角膜と虹彩の間に入れる「前房型レンズ」と水晶体と虹彩の間に入れる「後房型レンズ」の2種類があるようです。</div>
<div>
<br /></div>
<div>
「後房型レンズ」にはレンズに穴の開いているホールICLというのがあるようです。</div>
<div>
どうやら穴が空いていないと目の中の水の循環が妨げられ眼圧があがり、緑内障になる可能性gあるため、穴を開けているそうです。</div>
<div>
<br /></div>
<div>
<div>
サイトによると、「後房型レンズ」のホールICLほうが安全そうですね。</div>
<div>
<span style="text-align: center;">私も後房型レンズにしました。</span></div>
<div>
<br /></div>
</div>
<div style="text-align: center;">
<img alt="前房型レンズ" src="https://sightcure.jp/recovery/images/icl_01.png" width="240" /><img alt="後房型レンズ" src="https://sightcure.jp/recovery/images/icl_02.png" width="240" /></div>
<div style="text-align: center;">
<span style="text-align: start;">前房型レンズ </span>後房型レンズ</div>
<div>
参考URL:<a href="https://sightcure.jp/recovery/icl.html">https://sightcure.jp/recovery/icl.html</a></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
こんな感じで1ヶ月ほどICLの解説サイトと感想サイトを回った結果</div>
<div>
白内障のリスクは怖いけど大丈夫そう!という気分になってきたので、家の近くにある病院に無料カウンセリングを予約してきました。</div>
<div>
<br /></div>
<div>
10月頃にカウンセリングと検査を行った結果、ICL適用可だったためその場で予約!</div>
<div>
<br /></div>
<div>
手術代は60万円かかったのですが、レンズ代として前金30万円をその場で支払い、手術当日に30万円を支払いました。</div>
<div>
<br /></div>
<div>
いざ、手術です!</div>
<div>
<br /></div>
<div>
手術当日の様子は<a href="http://kassymemo.blogspot.jp/2016/11/vricl.html">次の記事</a>にて!<br />
<br />
<br />
<br />
<br />
-----------<br />
新宿近くで視力矯正に興味のある方は友達紹介制度で割引できます!<br />
私も紹介料がもらえるので嬉しいです<br />
もしご興味がありましたらお声がけください!<br />
<br />
ICL以外にもレーシック、オルソケラトロジーなど他の手術でも紹介制度がつかえるそうです。<br />
<br />
ご連絡は<a href="https://twitter.com/kassy708" target="_blank">Twitter</a>のDMにてどうぞ!</div>
kassy708http://www.blogger.com/profile/00025482097446561673noreply@blogger.com0tag:blogger.com,1999:blog-171901102439270531.post-26101488467306448062012-07-22T23:51:00.001+09:002012-07-23T00:06:34.321+09:00【code.9leap】画面遷移の基礎!【自作チュートリアルチャレンジ!】いつも9leapで楽しませてもらってる株式会社ユビキタスエンターテインメントが<a href="http://code.9leap.net/">code.9leap</a>というサービスを開始しました。<br />
<a href="http://www.4gamer.net/games/032/G003263/20120702062/">ブラウザ上でゲーム開発を行える「Code.9leap.net」,β版サービスが始まる </a><br />
<br />
<br />
これにあたり、「<a href="http://wise9.jp/archives/7702">code.9leapカスタム・チュートリアルチャレンジ!</a>」というコンテストが開催されました。<br />
<br />
っということで、私もチャレンジしてみようと思います!<br />
<br />
<br />
私がenchant.jsで最初に悩んだところは画面遷移でした。<br />
ということで、そのあたりのチュートリアルを作ってみました 。<br />
<br />
<br />
ゲームの基本「タイトル画面 → プレイ画面 → エンド画面」の流れを簡単に説明しています。<br />
<br />
<br />
<span class="Apple-style-span" style="border-collapse: separate; color: black; font-family: 'Times New Roman'; font-size: 16px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;"></span><br />
<span class="Apple-style-span" style="border-collapse: separate; color: black; font-family: 'Times New Roman'; font-size: 16px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;"></span><br />
<span class="Apple-style-span" style="border-collapse: separate; color: black; font-family: 'Times New Roman'; font-size: 16px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;"></span><br />
<u><span class="Apple-style-span" style="border-collapse: separate; color: black; font-family: 'Times New Roman'; font-size: 16px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;"><span class="Apple-style-span" style="color: #333333; font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; font-size: 13px; line-height: 18px;"></span></span></u><br />
<h4 style="color: inherit; font-family: inherit; font-size: 14px; font-weight: bold; line-height: 18px; margin-bottom: 5px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-rendering: optimizelegibility;">
<u><a href="http://code.9leap.net/codes/show/7168" style="color: #0088cc; text-decoration: none;">ゲームの流れを学ぼう1「タイトル画面」</a></u></h4>
<span class="Apple-style-span" style="border-collapse: separate; color: black; font-family: 'Times New Roman'; font-size: 16px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;"><span class="Apple-style-span" style="color: #333333; font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; font-size: 13px; line-height: 18px;">
</span></span><span class="Apple-style-span" style="border-collapse: separate; color: black; font-family: 'Times New Roman'; font-size: 16px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;"><span class="Apple-style-span" style="color: #333333; font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; font-size: 13px; line-height: 18px;"></span></span><br />
<div class="separator" style="clear: both; text-align: center;">
<span class="Apple-style-span" style="border-collapse: separate; color: black; font-family: 'Times New Roman'; font-size: 16px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;"><span class="Apple-style-span" style="color: #333333; font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; font-size: 13px; line-height: 18px;"><a href="http://code.9leap.net/codes/show/7168"><img border="0" height="320" src="http://4.bp.blogspot.com/-R4oO76CqxRY/UAwSNpIQAZI/AAAAAAAAAHI/fbmsI7AfTLk/s320/1.png" width="319" /></a></span></span></div>
<span class="Apple-style-span" style="border-collapse: separate; color: black; font-family: 'Times New Roman'; font-size: 16px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;"><span class="Apple-style-span" style="color: #333333; font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; font-size: 13px; line-height: 18px;">
</span></span><span class="Apple-style-span" style="border-collapse: separate; color: black; font-family: 'Times New Roman'; font-size: 16px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;"><span class="Apple-style-span" style="color: #333333; font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; font-size: 13px; line-height: 18px;"></span></span><br />
<h4 style="color: inherit; font-family: inherit; font-size: 14px; font-weight: bold; line-height: 18px; margin: 0px 0px 5px; text-rendering: optimizelegibility;">
<span class="Apple-style-span" style="border-collapse: separate; color: black; font-family: 'Times New Roman'; font-size: 16px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;"><span class="Apple-style-span" style="color: #333333; font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; font-size: 13px; line-height: 18px;">
</span></span></h4>
<span class="Apple-style-span" style="border-collapse: separate; color: black; font-family: 'Times New Roman'; font-size: 16px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;"><span class="Apple-style-span" style="color: #333333; font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; font-size: 13px; line-height: 18px;">
</span></span><br />
<h4 style="color: inherit; font-family: inherit; font-size: 14px; font-weight: bold; line-height: 18px; margin: 0px 0px 5px; text-rendering: optimizelegibility;">
<span class="Apple-style-span" style="border-collapse: separate; color: black; font-family: 'Times New Roman'; font-size: 16px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;"><span class="Apple-style-span" style="color: #333333; font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; font-size: 13px; line-height: 18px;">
</span></span></h4>
<span class="Apple-style-span" style="border-collapse: separate; color: black; font-family: 'Times New Roman'; font-size: 16px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;"><span class="Apple-style-span" style="color: #333333; font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; font-size: 13px; line-height: 18px;">
</span></span><span class="Apple-style-span" style="border-collapse: separate; color: black; font-family: 'Times New Roman'; font-size: 16px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;"><span class="Apple-style-span" style="color: #333333; font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; font-size: 13px; line-height: 18px;"></span></span><br />
<h4 style="color: inherit; font-family: inherit; font-size: 14px; font-weight: bold; line-height: 18px; margin: 0px 0px 5px; text-rendering: optimizelegibility;">
<span class="Apple-style-span" style="border-collapse: separate; color: black; font-family: 'Times New Roman'; font-size: 16px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;"><span class="Apple-style-span" style="color: #333333; font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; font-size: 13px; line-height: 18px;">
<u><span class="Apple-style-span" style="border-collapse: separate; color: black; font-family: 'Times New Roman'; font-size: 16px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;"><span class="Apple-style-span" style="color: #333333; font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; font-size: 13px; line-height: 18px;"><h4 style="color: inherit; font-family: inherit; font-size: 14px; font-weight: bold; line-height: 18px; margin-bottom: 5px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-rendering: optimizelegibility;">
<a href="http://code.9leap.net/codes/show/7262" style="color: #0088cc; text-decoration: none;">ゲームの流れを学ぼう2「プレイ画面への遷移」</a></h4>
</span></span><span class="Apple-style-span" style="border-collapse: separate; color: black; font-family: 'Times New Roman'; font-size: 16px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;"><span class="Apple-style-span" style="color: #333333; font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; font-size: 13px; line-height: 18px;">
</span></span></u><span class="Apple-style-span" style="border-collapse: separate; color: black; font-family: 'Times New Roman'; font-size: 16px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;"><span class="Apple-style-span" style="color: #333333; font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; font-size: 13px; line-height: 18px;"><h4 style="color: inherit; font-family: inherit; font-size: 14px; font-weight: bold; line-height: 18px; margin: 0px 0px 5px; text-rendering: optimizelegibility;">
</h4>
</span></span><span class="Apple-style-span" style="border-collapse: separate; color: black; font-family: 'Times New Roman'; font-size: 16px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;"><span class="Apple-style-span" style="color: #333333; font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; font-size: 13px; line-height: 18px;">
</span></span><span class="Apple-style-span" style="border-collapse: separate; color: black; font-family: 'Times New Roman'; font-size: 16px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;"><span class="Apple-style-span" style="color: #333333; font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; font-size: 13px; line-height: 18px;"><div class="separator" style="clear: both; text-align: center;">
<a href="http://code.9leap.net/codes/show/7262"><img border="0" src="http://2.bp.blogspot.com/-_-HWAdG8NV4/UAwSPBCS_9I/AAAAAAAAAHQ/1yRSVrlaWYE/s1600/2.png" /><span id="goog_769078139"></span></a><span id="goog_769078140"></span></div>
</span></span><span class="Apple-style-span" style="border-collapse: separate; color: black; font-family: 'Times New Roman'; font-size: 16px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;"><span class="Apple-style-span" style="color: #333333; font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; font-size: 13px; line-height: 18px;"><h4 style="color: inherit; font-family: inherit; font-size: 14px; font-weight: bold; line-height: 18px; margin: 0px 0px 5px; text-rendering: optimizelegibility;">
</h4>
<h4 style="color: inherit; font-family: inherit; font-size: 14px; font-weight: bold; line-height: 18px; margin: 0px 0px 5px; text-rendering: optimizelegibility;">
</h4>
<h4 style="color: inherit; font-family: inherit; font-size: 14px; font-weight: bold; line-height: 18px; margin: 0px 0px 5px; text-rendering: optimizelegibility;">
<u><span class="Apple-style-span" style="border-collapse: separate; color: black; font-family: 'Times New Roman'; font-size: 16px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;"><span class="Apple-style-span" style="color: #333333; font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; font-size: 13px; line-height: 18px;"><h4 style="color: inherit; font-family: inherit; font-size: 14px; font-weight: bold; line-height: 18px; margin-bottom: 5px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-rendering: optimizelegibility;">
<a href="http://code.9leap.net/codes/show/7279" style="color: #0088cc; text-decoration: none;">ゲームの流れを学ぼう3「タイトルへ戻る」</a></h4>
</span></span></u><span class="Apple-style-span" style="border-collapse: separate; color: black; font-family: 'Times New Roman'; font-size: 16px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;"><span class="Apple-style-span" style="color: #333333; font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; font-size: 13px; line-height: 18px;">
<div class="separator" style="clear: both; text-align: center;">
<a href="http://code.9leap.net/codes/show/7279"><img border="0" src="http://3.bp.blogspot.com/-336QB7LWPa8/UAwSPieXbEI/AAAAAAAAAHY/OJlVcJw21h4/s1600/3.png" /></a></div>
<h4 style="color: inherit; font-family: inherit; font-size: 14px; font-weight: bold; line-height: 18px; margin: 0px 0px 5px; text-rendering: optimizelegibility;">
</h4>
<h4 style="color: inherit; font-family: inherit; font-size: 14px; font-weight: bold; line-height: 18px; margin: 0px 0px 5px; text-rendering: optimizelegibility;">
</h4>
<h4 style="color: inherit; font-family: inherit; font-size: 14px; font-weight: bold; line-height: 18px; margin: 0px 0px 5px; text-rendering: optimizelegibility;">
</h4>
<h4 style="color: inherit; font-family: inherit; font-size: 14px; font-weight: bold; line-height: 18px; margin: 0px 0px 5px; text-rendering: optimizelegibility;">
<span class="Apple-style-span" style="border-collapse: separate; color: black; font-family: 'Times New Roman'; font-size: 16px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;"><span class="Apple-style-span" style="color: #333333; font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; font-size: 13px; line-height: 18px;"><h4 style="color: inherit; font-family: inherit; font-size: 14px; font-weight: bold; line-height: 18px; margin-bottom: 5px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-rendering: optimizelegibility;">
<u><a href="http://code.9leap.net/codes/show/7390" style="color: #0088cc; text-decoration: none;">ゲームの流れを学ぼう4「ゲーム終了」</a></u></h4>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://code.9leap.net/codes/show/7390"><img border="0" src="http://2.bp.blogspot.com/-d28c1mQYr14/UAwSP_OpOnI/AAAAAAAAAHg/_HnEgMnDgOM/s1600/4.png" /></a></div>
<h4 style="color: inherit; font-family: inherit; font-size: 14px; font-weight: bold; line-height: 18px; margin: 0px 0px 5px; text-rendering: optimizelegibility;">
</h4>
<h4 style="color: inherit; font-family: inherit; font-size: 14px; font-weight: bold; line-height: 18px; margin: 0px 0px 5px; text-rendering: optimizelegibility;">
</h4>
<h4 style="color: inherit; font-family: inherit; font-size: 14px; font-weight: bold; line-height: 18px; margin: 0px 0px 5px; text-rendering: optimizelegibility;">
</h4>
</span></span> </h4>
<h4 style="color: inherit; font-family: inherit; font-size: 14px; font-weight: bold; line-height: 18px; margin: 0px 0px 5px; text-rendering: optimizelegibility;">
</h4>
<h4 style="color: inherit; font-family: inherit; font-size: 14px; font-weight: bold; line-height: 18px; margin: 0px 0px 5px; text-rendering: optimizelegibility;">
</h4>
<h4 style="color: inherit; font-family: inherit; font-size: 14px; font-weight: bold; line-height: 18px; margin: 0px 0px 5px; text-rendering: optimizelegibility;">
<span class="Apple-style-span" style="border-collapse: separate; color: black; font-family: 'Times New Roman'; font-size: 16px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;"><span class="Apple-style-span" style="color: #333333; font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; font-size: 13px; line-height: 18px;"><h4 style="color: inherit; font-family: inherit; font-size: 14px; font-weight: bold; line-height: 18px; margin-bottom: 5px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-rendering: optimizelegibility;">
<u><a href="http://code.9leap.net/codes/show/7393" style="color: #0088cc; text-decoration: none;">ゲームの流れを学ぼう5「1からやってみよう!」</a></u></h4>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://code.9leap.net/codes/show/7393"><img border="0" src="http://1.bp.blogspot.com/-F55u1QJMPGU/UAwSQXIlULI/AAAAAAAAAHo/IYCCA66tn7k/s1600/5.png" /></a></div>
<h4 style="color: inherit; font-family: inherit; font-size: 14px; font-weight: bold; line-height: 18px; margin: 0px 0px 5px; text-rendering: optimizelegibility;">
</h4>
<h4 style="color: inherit; font-family: inherit; font-size: 14px; font-weight: bold; line-height: 18px; margin: 0px 0px 5px; text-rendering: optimizelegibility;">
</h4>
<h4 style="color: inherit; font-family: inherit; font-size: 14px; font-weight: bold; line-height: 18px; margin: 0px 0px 5px; text-rendering: optimizelegibility;">
</h4>
<h4 style="color: inherit; font-family: inherit; font-size: 14px; font-weight: normal; line-height: 18px; margin: 0px 0px 5px; text-rendering: optimizelegibility;">
画面遷移が出来れば、ゲームの見栄えも良くなるでしょう。</h4>
<h4 style="color: inherit; font-family: inherit; font-size: 14px; font-weight: normal; line-height: 18px; margin: 0px 0px 5px; text-rendering: optimizelegibility;">
これをベースにゲーム作りができるはずです!</h4>
<h4 style="color: inherit; font-family: inherit; font-size: 14px; font-weight: normal; line-height: 18px; margin: 0px 0px 5px; text-rendering: optimizelegibility;">
</h4>
<h4 style="color: inherit; font-family: inherit; font-size: 14px; font-weight: bold; line-height: 18px; margin: 0px 0px 5px; text-rendering: optimizelegibility;">
<span style="font-weight: normal;">ちょっとcode.9leapの仕様で変な書き方しているところはありますが・・・ </span></h4>
</span></span></h4>
</span></span></h4>
</span></span></span></span></h4>kassy708http://www.blogger.com/profile/00025482097446561673noreply@blogger.com1tag:blogger.com,1999:blog-171901102439270531.post-78137494607085888252012-04-01T15:39:00.000+09:002012-04-01T16:21:32.903+09:00Kinect for Windows SDKによる3次元ポイントクラウド以前、OpenNIを用いたポイントクラウドの方法を紹介していました<br />
<a href="http://kassymemo.blogspot.jp/2011/09/kinect-openni3-3_29.html">Kinect OpenNIによる3次元ポイントクラウド - 3次元描画 高速化</a><br />
<br />
今回はマイクロソフトが公式で公開している<a href="http://www.microsoft.com/en-us/kinectforwindows/">Kinect for Windows SDK</a>を使ってポイントクラウドを行ってみます。<br />
<br />
描画にはいつもどおりOpenGLを使い、その過程でOpenCVを使っています。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<object width="320" height="266" class="BLOGGER-youtube-video" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" data-thumbnail-src="http://i.ytimg.com/vi/s1zEI_n9Dyc/0.jpg"><param name="movie" value="http://www.youtube.com/v/s1zEI_n9Dyc?version=3&f=user_uploads&c=google-webdrive-0&app=youtube_gdata" />
<param name="bgcolor" value="#FFFFFF" />
<embed width="320" height="266" src="http://www.youtube.com/v/s1zEI_n9Dyc?version=3&f=user_uploads&c=google-webdrive-0&app=youtube_gdata" type="application/x-shockwave-flash"></embed></object></div>
<br />
<br />
<br />
まず初めにKinect SDKでRGB画像とDepth画像の取得方法について簡単に説明します。<br />
<br />
細かい説明なんてどうでもいいんだよ!って人は 下のほうでサンプルプログラムがダウンロードできるので、下の方へスクロールしてってください。<br />
<br />
<br />
では、プログラムの初期化処理は以下のようになる <br />
<br />
<script src="https://gist.github.com/2271701.js">
</script>
<br />
<br />
初期化処理では<br />
<pre>HRESULT NuiInitialize(
DWORD dwFlags
)</pre>
<br />
で初期化します。<br />
<br />
引数はRGB画像、Depth画像、骨格情報を得る場合<br />
NUI_INITIALIZE_FLAG_USES_COLOR | NUI_INITIALIZE_FLAG_USES_DEPTH_AND_PLAYER_INDEX | NUI_INITIALIZE_FLAG_USES_SKELETON<br />
とします
<script src="https://gist.github.com/2271660.js">
</script>
次に画像取得のイベントハンドルを設定します。
<script src="https://gist.github.com/2271682.js">
</script>
<br />
<br />
Depth画像の大きさによって使用する<span class="n">NuiImageStreamOpen</span>関数の引数が違うので<br />
<pre><span class="cp">KINECT_DEPTH_WIDTHを#defineで事前に定義して、ここで条件分岐しています。</span></pre>
<pre><span class="cp"> </span></pre>
KinectSDKはBetaの時はDepth画像の解像度を320x240しか設定できなかったのですが<br />
v1.0になり、640x480に設定することが可能となりました。<br />
<br />
上記で設定したイベントで以下のようにしてRGB画像とDepth画像を取得します<br />
<script src="https://gist.github.com/2271751.js">
</script>
<br />
扱いやすい形にするため、OpenCVのMatに格納します<br />
また、その処理を関数化します
<br />
<script src="https://gist.github.com/2271800.js">
</script>
<br />
<br />
ここでは<span class="n">GetImage</span><span class="p">(</span><span class="n">cv</span><span class="o">::</span><span class="n">Mat</span> <span class="o">&</span><span class="n">image</span><span class="p">,</span><span class="n">HANDLE</span> <span class="n">frameEvent</span><span class="p">,</span><span class="n">HANDLE</span> <span class="n">streamHandle</span><span class="p">)</span><br />
という関数を作りました。<br />
<br />
この関数は以下のように用います。<br />
<script src="https://gist.github.com/2271912.js">
</script>
<br />
関数の戻り値が-1の時は取得失敗ということです。<br />
<br />
Kinect SDKではOpenNIを違い、Matへの格納が少しめんどうですね。<br />
<br />
次にポイントクラウドを行う上で、画像のピクセルが現実座標ではどこにあるのかを知る必要があります。<br />
<br />
OpenNIではConvertProjectiveToRealWorldという関数がありました。<br />
<br />
Kinect SDKでは以下の関数を用います<br />
<br />
Vector4 NuiTransformDepthImageToSkeleton(<br />
LONG lDepthX,<br />
LONG lDepthY,<br />
USHORT usDepthValue<br />
)<br />
<br />
<br />
この関数はDepth画像のピクセルの位置(x,y)とその場所の値を与えることで現実座標系で帰ってきます。<br />
<br />
では、Depth画像から現実座標配列を格納する関数を以下のように作ります。<script src="https://gist.github.com/2271943.js">
</script>
<br />
<br />
NuiTransformDepthImageToSkeletonはDepth画像の解像度により引数を追加します。<br />
<br />
これはbetaの時にDepth画像が640x480に対応していなかったからかなぁっと思います。<br />
<br />
<br />
で、最後にポイントクラウドで描画します。<br />
<script src="https://gist.github.com/2271976.js">
</script>
<br />
drawPointCloudではRGB画像とretrievePointCloudMapで取得した三次元位置を渡し、描画します。<br />
<br />
また、この関数内でRGBとDepthのズレを補正しています。<br />
OpepNIでいう<br />
DepthGenerator.GetAlternativeViewPointCap().SetViewPoint は<br />
<br />
KinectSDKでは<br />
NuiImageGetColorPixelCoordinatesFromDepthPixel<br />
または<br />
NuiImageGetColorPixelCoordinatesFromDepthPixelAtResolution<br />
を使います<br />
<br />
これも、Depthの解像度により関数を変える必要があります。<br />
<br />
まあ、NuiImageGetColorPixelCoordinatesFromDepthPixelのなかでNuiImageGetColorPixelCoordinatesFromDepthPixelAtResolutionが呼ばれてるんですけどね<br />
<br />
<br />
<br />
<br />
<br />
これまで長く説明してきましたけど、まあ、こんな説明読むよりサンプルプログラムを見たほうが早いかな?<br />
<br />
全体のプログラムはこんな感じです。<br />
<script src="https://gist.github.com/2272019.js">
</script>
<br />
<br />
<a href="https://github.com/kassy708/KinectSDK-Sample">github</a><br />
<a href="https://github.com/kassy708/KinectSDK-Sample/zipball/master">サンプルダウンロード </a>kassy708http://www.blogger.com/profile/00025482097446561673noreply@blogger.com22tag:blogger.com,1999:blog-171901102439270531.post-24544003219258548052012-03-31T19:37:00.000+09:002012-03-31T19:52:34.744+09:00PhySprite.enchant.jsに多角形とジョイントを追加しました。PhySprite.enchant.jsに機能を追加しました。<br />
<br />
PhySprite.enchant.jsのダウンロード<br />
<a href="https://github.com/kassy708/enchant.js-plugin/zipball/master">ダウンロード</a><br />
<a href="http://kassy708.github.com/" target="_blank">リファレンス </a><br />
<br />
今までのPhySprite.enchant.jsには円形と四角形しか物理オブジェクトをサポートしていませんでした。<br />
<br />
今回は多角形を追加し、さらにオブジェクトにImageを設定しなくても形がわかるDebugDraw機能をつけました。<br />
<br />
これで多角形の物体のように画像が用意しずらいオブジェクトでもわかりやすくなりました。<br />
<br />
<br />
・<b>多角形</b><br />
ではまず、多角形の説明からします。<br />
<br />
多角形のオブジェクトを生成するには以下の関数を用いる
<br />
<pre class="prettyprint">
<b><a href="http://kassy708.github.com/symbols/enchant.PhyPolygonSprite.html#constructor">enchant.PhyPolygonSprite</a></b>(width, height, vertexs, type, density, friction, restitution, awake)</pre>
<div class="description">
多角形の物理シミュレーション用Sprite</div>
<br />
引数は以下の通り
<br />
<dl class="detailList">
<dt class="heading">Parameters:</dt>
<dt>
<span class="light fixedFont">{Number}</span> <b>width</b>
<i>Optional</i>
</dt>
<dd>Spriteの横幅.</dd>
<dt>
<span class="light fixedFont">{Number}</span> <b>height</b>
<i>Optional</i>
</dt>
<dd>Spriteの高さ.</dd>
<dt>
<span class="light fixedFont">{b2Vec2[]}</span> <b>vertexs</b>
</dt>
<dd>多角形の頂点配列</dd>
<dt>
<span class="light fixedFont">{Boolean}</span> <b>type</b>
<i>Optional</i>
</dt>
<dd>静的,動的,キネマティック</dd>
<dt>
<span class="light fixedFont">{Number}</span> <b>density</b>
<i>Optional</i>
</dt>
<dd>Spriteの密度.</dd>
<dt>
<span class="light fixedFont">{Number}</span> <b>friction</b>
<i>Optional</i>
</dt>
<dd>Spriteの摩擦.</dd>
<dt>
<span class="light fixedFont">{Number}</span> <b>restitution</b>
<i>Optional</i>
</dt>
<dd>Spriteの反発.</dd>
<dt>
<span class="light fixedFont">{Boolean}</span> <b>awake</b>
<i>Optional</i>
</dt>
<dd>Spriteが初めから物理演算を行うか.
</dd></dl>
<br />
ここで新しく追加されたvertexsですが、これは多角形の頂点配列です。<br />
<br />
どういうものかというと、例えば四角形の場合のvertexsは<br />
<pre class="prettyprint">
var width = 20;
var height = 50;
var vertexs = new Array(
new b2Vec2(-width / 2, -height / 2),
new b2Vec2(width / 2, -height / 2),
new b2Vec2(width / 2, height / 2),
new b2Vec2(-width / 2, height / 2));
var phyPolygonSprite = new PhyPolygonSprite(width, height, vertexs, DYNAMIC_SPRITE, 1.0, 0.1, 0.2, true);
game.rootScene.addChild(phyPolygonSprite); // シーンに追加</pre>
<br />
<br />
このように四角形を作る<br />
vertexsはSpriteの中心座標を(0,0)として時計回り・または反時計回りに宣言していく。<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-81k2_WaOBa0/T3bGNCMaEvI/AAAAAAAAAGo/8ESaAxIW2vU/s1600/%E5%9B%9B%E8%A7%92%E5%BD%A2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-81k2_WaOBa0/T3bGNCMaEvI/AAAAAAAAAGo/8ESaAxIW2vU/s1600/%E5%9B%9B%E8%A7%92%E5%BD%A2.png" /></a></div>
<br />
では次に五角形を生成してみます。<br />
次は簡略化のためfor文を使います。<br />
<pre class="prettyprint">
var vertexCount = 5;
var radius = 20;
var vertexs = new Array();
for (var i = 0; i < vertexCount; i++) {
vertexs[i] = new b2Vec2(radius * Math.cos(2 * Math.PI / vertexCount * i), radius * Math.sin(2 * Math.PI / vertexCount * i));
}
var phyPolygonSprite = new PhyPolygonSprite(radius * 2, radius * 2, vertexs, DYNAMIC_SPRITE, 1.0, 0.1, 0.2, true);
game.rootScene.addChild(phyPolygonSprite); // シーンに追加</pre>
<br />
<br />
これで五角形を作ることができました。<br />
vertexCountを変更することで三角形でも七角形でも百角形でも可能です。<br />
<br />
<br />
ここで注意することは、頂点と頂点と間に交点ができてしまうとうまく当たり判定がおかしくなるので気をつけて下さい。<br />
<br />
<br />
<br />
・<b>ジョイント</b><br />
では次はジョイントの説明 <br />
<br />
ジョイントは複数のタイプがあります。<br />
<br />
<div class="fixedFont">
<b><a href="http://kassy708.github.com/symbols/enchant.PhyDistanceJoint.html#constructor">enchant.PhyDistanceJoint</a></b>(sprite1, sprite2)
</div>
<div class="description">
距離ジョイント </div>
<div class="description">
<br />
<div class="fixedFont">
<b><a href="http://kassy708.github.com/symbols/enchant.PhyRevoluteJoint.html#constructor">enchant.PhyRevoluteJoint</a></b>(axis, sprite)
</div>
<div class="description">
物体と物体のモーター付きジョイント</div>
<div class="description">
<div class="fixedFont">
</div>
<div class="fixedFont">
<b><a href="http://kassy708.github.com/symbols/enchant.PhyPrismaticJoint.html#constructor">enchant.PhyPrismaticJoint</a></b>(sprite1, sprite2, anchor1, anchor2, ratio)
</div>
<div class="description">
スライドジョイント</div>
<div class="description">
<br />
<div class="fixedFont">
<b><a href="http://kassy708.github.com/symbols/enchant.PhyPulleyJoint.html#constructor">enchant.PhyPulleyJoint</a></b>(sprite1, sprite2, anchor1, anchor2, ratio)
</div>
<div class="description">
滑車ジョイント</div>
<div class="description">
</div>
<div class="description">
</div>
<div class="description">
</div>
<div class="description">
1つ1つ説明していきます。</div>
<div class="description">
<br />
<div class="fixedFont">
<b><a href="http://kassy708.github.com/symbols/enchant.PhyDistanceJoint.html#constructor">enchant.PhyDistanceJoint</a></b>(sprite1, sprite2)
</div>
<div class="description">
距離ジョイント
</div>
<dl class="detailList">
<dt class="heading">Parameters:</dt>
<dt>
<span class="light fixedFont">{<a href="http://kassy708.github.com/symbols/enchant.PhySprite.html">enchant.PhySprite</a>}</span> <b>sprite1</b>
<i>Optional</i>
</dt>
<dd>繋げるスプライト1</dd>
<dt>
<span class="light fixedFont">{<a href="http://kassy708.github.com/symbols/enchant.PhySprite.html">enchant.PhySprite</a>}</span> <b>sprite2</b>
<i>Optional</i>
</dt>
<dd>繋げるスプライト2</dd></dl>
</div>
<div class="description">
これは最も単純なジョイントです。</div>
<div class="description">
</div>
<div class="description">
引数の2つのスプライトをジョイントで繋げます。</div>
<div class="description">
</div>
<div class="description">
例</div>
<div class="description">
<pre class="prettyprint">
//軸
var axis = new PhyCircleSprite(8, STATIC_SPRITE);
axis.position = { x: 160, y: 160 };
game.rootScene.addChild(axis); // シーンに追加
//ボール生成
var ball = new PhyCircleSprite(8, DYNAMIC_SPRITE);
ball.position = { x: 100, y: 250 };
game.rootScene.addChild(ball); // シーンに追加
//距離ジョイント
var joint = new PhyDistanceJoint(axis, ball);
</pre>
</div>
<div class="description">
<br /></div>
<div class="description">
ここでは簡略化のため、物理オブジェクトのパラメータを書いていません。</div>
<div class="description">
この場合、 density=1.0,friction=0.5,restitution=0.3,awake=trueがデフォルトの値となります。</div>
<div class="description">
<br /></div>
<div class="description">
未定義でもいいってのはここで初めて説明したのかな?</div>
<div class="description">
</div>
<div class="description">
</div>
<div class="description">
で、この例ではaxisという静止オブジェクトにballがぶら下がっています。<br />
<br />
<br />
では次<br />
<br />
<br />
<div class="fixedFont">
<b><a href="http://kassy708.github.com/symbols/enchant.PhyRevoluteJoint.html#constructor">enchant.PhyRevoluteJoint</a></b>(axis, sprite)
</div>
<div class="description">
物体と物体のモーター付きジョイント
</div>
<dl class="detailList">
<dt class="heading">Parameters:</dt>
<dt>
<span class="light fixedFont">{<a href="http://kassy708.github.com/symbols/enchant.PhySprite.html">enchant.PhySprite</a>}</span> <b>axis</b>
<i>Optional</i>
</dt>
<dd>軸となるスプライト</dd>
<dt>
<span class="light fixedFont">{<a href="http://kassy708.github.com/symbols/enchant.PhySprite.html">enchant.PhySprite</a>}</span> <b>sprite</b>
<i>Optional</i>
</dt>
<dd>繋げるスプライト</dd></dl>
これは軸(axis)にモーターを設けることができるジョイントです。<br />
<br />
例<br />
<pre class="prettyprint">
//軸
var axis = new PhyCircleSprite(8, STATIC_SPRITE);
axis.position = { x: 160, y: 160 };
game.rootScene.addChild(axis); // シーンに追加
//ボール生成
var ball = new PhyCircleSprite(8, DYNAMIC_SPRITE);
ball.position = { x: 100, y: 250 };
game.rootScene.addChild(ball); // シーンに追加
//距離ジョイント
var joint = new PhyRevoluteJoint(axis, ball);
joint.enableMotor = true;
joint.maxMotorTorque = 100;
joint.motorSpeed = 90;</pre>
<br />
PhyDistanceJointとの違いはenableMotorでモーターを有効化しなければいけないことと<br />
maxMotorTorqueでモーターのトルクを設定します。<br />
<a href="http://ja.wikipedia.org/wiki/%E3%83%88%E3%83%AB%E3%82%AF">トルクとは</a><br />
そしてmotorSpeedでモーターの速度を設定することで、axisに接続されたballが動き出します。<br />
<br />
モーター機能を有効にしていないとPhyDistanceJointと変わりません。<br />
<br />
<br />
<br />
<br />
<div class="fixedFont">
<b><a href="http://kassy708.github.com/symbols/enchant.PhyPrismaticJoint.html#constructor">enchant.PhyPrismaticJoint</a></b>(sprite1, axis)
</div>
<div class="description">
<div class="description">
スライドジョイント</div>
</div>
<dl class="detailList">
<dt class="heading">Parameters:</dt>
<dt>
<span class="light fixedFont">{<a href="http://kassy708.github.com/symbols/enchant.PhySprite.html">enchant.PhySprite</a>}</span> <b>sprite1</b>
<i>Optional</i>
</dt>
<dd>繋げるスプライト1</dd>
<dt>
<span class="light fixedFont">{</span><span class="light fixedFont">b2Vec</span><span class="light fixedFont">}</span> <b>axis</b>
<i>Optional</i>
</dt>
<dd>軸 </dd></dl>
<br />
スライドオブジェクトは文字どおりスプライトをスライドさせます。<br />
<br />
例<br />
<pre class="prettyprint">var box = new PhyBoxSprite(16, 8, DYNAMIC_SPRITE, 1.0, 0.5, 0.2, true);
box.position = { x: game.width * 2 / 3, y: game.height / 2 };
var prismaticAxis = new b2Vec2(1.0, 0); //x軸にスライドを設定(右が正の値)
//スライドジョイント
var prismaticJoint = new PhyPrismaticJoint(box, prismaticAxis);
//スライドオブジェクトにモーター機能を持たせる場合
//prismaticJoint.enableMotor = true; //モータの有効化
//prismaticJoint.maxMotorForce = 100.0; //モータの最大力を設定
//prismaticJoint.motorSpeed = 50; //モータの速度を設定
</pre>
<br />
<br />
引数の<b>axis</b>はスライドさせる軸です。<br />
<br />
右方向を正としてx軸にスライドさせる場合はaxis = new b2Vec2(1.0, 0);とします。<br />
<br />
また、このジョイントにはモーター機能が備わっており、 モータを有効化し最大力を設定することでモータ機能を使うことができます。<br />
<br />
<br />
<br />
<div class="fixedFont">
<b>enchant.PhyPulleyJoint</b>(sprite1, sprite2, anchor1, anchor2, ratio)
</div>
<div class="description">
滑車ジョイント
</div>
<dl class="detailList">
<dt class="heading">Parameters:</dt>
<dt>
<span class="light fixedFont">{<a href="http://kassy708.github.com/symbols/enchant.PhySprite.html">enchant.PhySprite</a>}</span> <b>sprite1</b>
<i>Optional</i>
</dt>
<dd>繋げるスプライト1</dd>
<dt>
<span class="light fixedFont">{<a href="http://kassy708.github.com/symbols/enchant.PhySprite.html">enchant.PhySprite</a>}</span> <b>sprite2</b>
<i>Optional</i>
</dt>
<dd>繋げるスプライト2</dd>
<dt>
<span class="light fixedFont">{b2Vec2}</span> <b>anchor1</b>
<i>Optional</i>
</dt>
<dd>アンカー1の位置</dd>
<dt>
<span class="light fixedFont">{b2Vec2}</span> <b>anchor2</b>
<i>Optional</i>
</dt>
<dd>アンカー2の位置</dd>
<dt>
<span class="light fixedFont">{Number}</span> <b>ratio</b>
<i>Optional</i>
</dt>
<dd>左右のバランス</dd></dl>
<br />
滑車オブジェクトはアンカーを2つ設定し、スプライトを吊り下げることができます。<br />
<br />
例<br />
<pre class="prettyprint">var ball1 = new PhyCircleSprite(8, DYNAMIC_SPRITE);
ball1.position = { x: 80, y: 160 };
var ball2 = new PhyCircleSprite(8, DYNAMIC_SPRITE);
ball2.position = { x: 240, y: 160 };
//滑車ジョイント
var pulleyJoint = new PhyPulleyJoint(ball1, ball2, new b2Vec2(80, 100), new b2Vec2(240, 100), 1);
</pre>
<br />
<img alt="" height="95" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAOkAAABvCAIAAACGvHBxAAAGRUlEQVR4nO3bz0vbfhzH8d123snTJih68SoIIrLb0IFbwYNNkfH10B42u29aCyKDQL/67VBamaA9Wa3gBg42hQmF7xfzhf4BVkE8iIiSIGpq09mkTbLEHQSRtbOxOvd929eDzy0/bODpx5h+cu8UgKZ7v/sDAFQI7QJVaBeoQrtAFdoFqtAuUIV2gSq0C1ShXaAK7QJVaBeoQrtA1Q20u6BpsUIBA+M6Y0HTbrvdpGE8z+Ve5HKcqmJgVDZe5HLPvn5Nfvt2q+2GVPWRLD87ORnP5zEwKhvPT04eyfLf+fxtt8upKm8Y1zwPVLP/DINTVbQL9KBdoArtAlVoF6hCu0AV2gWq0C5QhXaBKrQLVKFdoArtAlVoF6hCu0AV2gWq0C5QhXaBKrQLVKFdoArtAlVoF6hCu0AV2gWq0C5QhXaBKrQLVKFdoArtAlVoF6hCu0AV2gWq0C5QhXaBKrQLVKFdoArtAlVoF6hCu0AV2gWq0C5QhXaBKrQLVKFdoArtAlVoF6hCu0AV2gWq0C5QhXaBKrQLVKFdoArtAlVoF6hCu0AV2gWq0C5QhXaBKrQLVKFdoArtAlVoF6i61XYtyzJNU9f1v2T5jSz/o6qGYViWVdnZoGpZlmUYxr+q+kaWg9msruumadoM6crtWpaVz+czmczGxkY8Hn86MvJkePjPiYnFxcWdnR1FUVAw2GFZlqIoOzs7i4uL7MTEk+HhpyMj8Xh8Y2Mjk8nk8/myIV253ePj40gkwjBMY2Oj0+l86fO98vv/cLs7Ozvr6+u9Xu/e3p6u65VeEVQFwzAEQfB6vfX19Z2dnX1u9yu//6XP53Q6GxsbGYYJh8OSJF1+kiu0a1mWJEktLS0Oh4PjuK2trcPDw3Q6nU6nDw8PRVFcX18PBAJtbW08zyuKcr2rgztLUZREIlFXV9fX17e2tiaK4sWQtra2IpGIx+Pp6uqSJOmS2dduu6ZpCoLgcDj6+/tXVlZ2d3dN0/xhH8Mwtre3OY7r6OiYnJzMZrOVXx/cUbIsz87OMgwzODi4ublpFP2Xb5qmKIrJZNLn87W2tgqC8LN87bZbKBR4nm9ubo7H45dP5svLy+3t7SzLplIpmyeH6rG6uspxXHd39/Ly8iW7SZI0PT1dU1PD87ymaSX3sdWuZVkHBwe9vb2hUEiW5bL7R6NRj8fj9XqL52aoZqZper1elmXn5+fL7pxOpwcGBlwu18HBQcmp11a7uq6nUqna2tpcLmfnMYKqqsFgsKmpqeztNlQVSZKampqCwaCqqmV3tiwrl8vV1tamUqmS//3baleSpFgsxjCM/U/54cMHl8v16dMn+4fAnff582eXy/X+/Xv7hzAME4vFSk6Cttrd398Ph8N+v7/k1oWFhVgRp9PZ0NAQjUbtf0q486LR6OvXr798+VK86eTkpLiiWCz28OHDYDC4v79ffIitdkVRfPv27dDQUMmt4+PjXJHHjx8/ePDg3bt3V7o2uNsmJiYCgUAikSjelMlkiiviOO7+/ftDQ0OiKBYfcgPz7sePH2eKMAyDeRd+cPm8W1zRzMzMdedd3O/CjfgN97t4zgA34jc8Zzh7vutyuQYGBtLpdNn95+fnWZbF8134wdnzXY/HY+dmUpblUCjU29t7ree7p6enmqbxPF9TUzM9PV32e7Xu7m6O41ZXV22eHKpHKpViWba9vb3s92rxeLy5uZnn+UKhUHIfu+1aliUIQmtrq8/nSyaToiiWXM+wubk5ODjIMMzs7Kydb+Cg2mSz2cnJyY6ODo7jtre3S65n2N3dXVlZ6e/vdzgcgiD87K/3ldeRdXV1eTyeSCRycR3Z0dGRKIpra2t9fX11dXWJRALryOBnFEXheb6trS0QCKyvr4uieHR0dHEdGcdxDoejpaXlZtaRnZMkKRwOnz0C6+npYVnW7/e7L6zfFQSh+JcJ4CJd1/f29s7X77rdbr/fz7JsT09PQ0MDwzCRSOT4+Pjyk1zrvYm5ubmxsbHR0dGpqamlpSW8NwH2nb83sbS0NDU1NTo6OjY2Njc39wvfmzj/wWfvq2mapmmarut4Xw0qcPa+2sWQfuH7agD/E2gXqEK7QBXaBarQLlCFdoEqtAtUoV2gCu0CVWgXqEK7QBXaBarQLlD1HUwGZmtAG3+vAAAAAElFTkSuQmCC" width="200" /><br />
<br />
<br />
<br />
以上で簡単な説明を終わります。<br />
<br />
正直、文字で読むよりプログラムを読んだほうがわかりやすいような気がするので、サンプルプログラムをダウンロードして読んでみてください。(説明書くのがめんどくさいわけじゃないんだからね)<br />
<br />
<a href="http://9leap.net/games/1379">多角形,ジョイントサンプル - PhySprite.enchant.js</a><br />
<script src="http://9leap.net/games/1379/embed.js" type="text/javascript">
</script>
<br />
<a href="http://9leap.net/games/1379/download">サンプルダウンロード</a>
<br />
<br />
<br />
<br />
<br />
<br />
<br /></div>
<div class="description">
</div>
<div class="description">
</div>
</div>
</div>
</div>kassy708http://www.blogger.com/profile/00025482097446561673noreply@blogger.com0tag:blogger.com,1999:blog-171901102439270531.post-6353211039592088472012-02-12T15:20:00.000+09:002012-02-12T16:58:16.878+09:00OpenGLのウィンドウを動画でキャプチャするクラスを作ってみた - GLCaptureOpenGLのウィンドウを動画でキャプチャするクラスを作ってみました。<br />
<br />
研究で、OpenGLを使っていますが<br />
プレゼンを作るときにいつもキャプチャソフトを起動、設定して動画を撮るのが面倒でした。<br />
<br />
そこで、プログラムの方から動画を書きだすプログラムを書きました。<br />
<br />
動画サンプル<br />
<iframe allowfullscreen="" frameborder="0" height="315" src="http://www.youtube.com/embed/axSBbFk5bhY" width="420"></iframe>
<br />
<br />
<br />
こんな感じで録画できます。<br />
<br />
<br />
<br />
<br />
<a href="https://github.com/kassy708/GLCapture/zipball/master">ダウンロード</a><br />
<br />
<br />
<br />
使い方はこんな感じです。<br />
<br />
<pre class="prettyprint">
GLCapture glCapture;
void init(){
//glCaptureの設定
glCapture.setWriteFile("output.avi");
}
void display(){
<span class="n">glClear</span> <span class="p">(</span> <span class="n">GL_COLOR_BUFFER_BIT</span> <span class="o">|</span> <span class="n">GL_DEPTH_BUFFER_BIT</span> <span class="p">);</span>
//~描画するプログラム~
glFlush();
glutSwapBuffers();
//動画ファイルに書き込み
glCapture.write();
}
</pre>
と、こんな感じです。<br />
<br />
流れとしては<br />
<br />
GLCapture glCapture;<br />
でクラスの宣言行い。<br />
<br />
glCapture.setWriteFile();<br />
でインスタンスの設定を行う<br />
<br />
その後描画関数内で<br />
glCapture.write();<br />
により、現在の描画された内容を動画に書き出す処理です。
<br />
<br />
<br />
プログラム全体のサンプルは<a href="https://github.com/kassy708/GLCapture/blob/master/sample/main.cpp">github</a>に上げてます。
<br />
<br />
<br />
注意としては、このクラスは中でOpenCVを使っているので
OpenCV2.0以降をインストールしてください。
<br />
<a href="https://github.com/kassy708/GLCapture">github</a>
<br />
<br />
<br />
これでキャプチャソフトいらず\(^o^)/<br />
<br />
キャプチャソフトよりこっちのほうがきれいだしね。kassy708http://www.blogger.com/profile/00025482097446561673noreply@blogger.com1tag:blogger.com,1999:blog-171901102439270531.post-18686126393603221652012-02-05T14:21:00.001+09:002012-02-05T14:24:37.039+09:00OpenNIによるポイントクラウドと骨格追跡 - 3次元描画OpenNIは骨格追跡を行うことができ、更に各関節の3次元位置を取得することができます。<br />
<br />
今回は、OpenGLを使ったポイントクラウドに各関節を描画してみます。<br />
<br />
<br />
まず、ユーザ検出プログラムの説明を行います。<br />
<br />
その前に、OpenNIで骨格追跡を有効にするため「SamplesConfig.xml」に<br />
<Node type="User"/><br />
を追加します。<br />
<br />
<br />
では、プログラムの説明を行います。<br />
<br />
<br />
まず、初期化のところに以下のプログラムを加えます。<br />
<br />
<pre class="prettyprint">
context.FindExistingNode(XN_NODE_TYPE_USER, userGenerator);
xn::SkeletonCapability skeleton = userGenerator.GetSkeletonCap();
// ユーザー認識のコールバックを登録
// キャリブレーションのコールバックを登録
XnCallbackHandle userCallbacks, calibrationCallbacks;
userGenerator.RegisterUserCallbacks(&::UserDetected, 0, 0, userCallbacks);
skeleton.RegisterCalibrationCallbacks( 0, &::CalibrationEnd, 0, calibrationCallbacks );
skeleton.SetSkeletonProfile(XN_SKEL_PROFILE_ALL);</pre>
<br />
ここで、UserGeneratorの準備とキャリブレーションのコールバックを登録しました。<br />
<br />
UserDetectedはユーザの検出時のコールバック<br />
CalibrationEndはユーザロスト時のコールバックです<br />
<br />
<pre class="prettyprint">// ユーザー検出
void XN_CALLBACK_TYPE UserDetected( xn::UserGenerator& generator, XnUserID nId, void* pCookie )
{
printf("ユーザID%d 検出 %d人目\n",nId,generator.GetNumberOfUsers());
generator.GetSkeletonCap().RequestCalibration(nId, TRUE);
}
// キャリブレーションの終了
void XN_CALLBACK_TYPE CalibrationEnd(xn::SkeletonCapability& capability, XnUserID nId, XnBool bSuccess, void* pCookie)
{
if ( bSuccess ) {
printf("ユーザID%d キャリブレーション成功\n",nId);
capability.StartTracking(nId);
}
else {
printf("ユーザID%d キャリブレーション失敗\n",nId);
}
}</pre>
<br />
<br />
では、実際にユーザの骨格位置の取得を行います。<br />
<br />
<br />
<pre class="prettyprint">XnUserID aUsers[15];
XnUInt16 nUsers = 15;
userGenerator.GetUsers(aUsers, nUsers);
for (int i = 0; i < nUsers; ++i){
if (userGenerator.GetSkeletonCap().IsTracking(aUsers[i])){
XnSkeletonJointPosition joint;
//aUsers[i]の頭部位置をjointに格納
userGenerator.GetSkeletonCap().GetSkeletonJointPosition(aUsers[i], XN_SKEL_HEAD, joint);
}
}</pre>
<br />
上記のプログラムは全ユーザの頭部位置をjoingに格納して取得するプログラム例です。<br />
<br />
・各関数の説明<br />
userGenerator.GetUsers(aUsers, nUsers);<br />
aUsersの配列に検出されたユーザのIDを格納<br />
nUsersに検出したユーザの数を格納<br />
<br />
userGenerator.GetSkeletonCap().IsTracking(aUsers[i]);<br />
aUsers[i]がトラッキングされているかを返す<br />
<br />
userGenerator.GetSkeletonCap().GetSkeletonJointPosition(aUsers[i], XN_SKEL_HEAD, joint);<br />
aUsers[i]の頭部位置をjointに格納<br />
<br />
XN_SKEL_HEADは「enum XnSkeletonJoint」で宣言されており、他にも<br />
XN_SKEL_HEAD <br />
XN_SKEL_NECK <br />
XN_SKEL_TORSO <br />
XN_SKEL_WAIST <br />
XN_SKEL_LEFT_COLLAR <br />
XN_SKEL_LEFT_SHOULDER <br />
XN_SKEL_LEFT_ELBOW <br />
XN_SKEL_LEFT_WRIST <br />
XN_SKEL_LEFT_HAND <br />
XN_SKEL_LEFT_FINGERTIP <br />
XN_SKEL_RIGHT_COLLAR <br />
XN_SKEL_RIGHT_SHOULDER <br />
XN_SKEL_RIGHT_ELBOW <br />
XN_SKEL_RIGHT_WRIST <br />
XN_SKEL_RIGHT_HAND <br />
XN_SKEL_RIGHT_FINGERTIP <br />
XN_SKEL_LEFT_HIP <br />
XN_SKEL_LEFT_KNEE <br />
XN_SKEL_LEFT_ANKLE <br />
XN_SKEL_LEFT_FOOT <br />
XN_SKEL_RIGHT_HIP <br />
XN_SKEL_RIGHT_KNEE <br />
XN_SKEL_RIGHT_ANKLE <br />
XN_SKEL_RIGHT_FOOT<br />
と24箇所の関節が取得できる。<br />
<br />
<br />
<br />
では、以上のことを踏まえてOpenGLで骨格を描画してみます。<br />
<br />
プログラムは「<a href="http://kassymemo.blogspot.com/2011/09/kinect-openni3-3_29.html">Kinect OpenNIによる3次元ポイントクラウド - 3次元描画 高速化</a>」のプログラムに<br />
追加していく感じでやってきます。<br />
<br />
<pre class="prettyprint">#include <GL/glut.h>
#include <opencv2/opencv.hpp>
#ifdef _DEBUG
//Debugモードの場合
#pragma comment(lib,"C:\\OpenCV2.2\\lib\\opencv_core220d.lib") // opencv_core
#pragma comment(lib,"C:\\OpenCV2.2\\lib\\opencv_imgproc220d.lib") // opencv_imgproc
#pragma comment(lib,"C:\\OpenCV2.2\\lib\\opencv_highgui220d.lib") // opencv_highgui
#else
//Releaseモードの場合
#pragma comment(lib,"C:\\OpenCV2.2\\lib\\opencv_core220.lib") // opencv_core
#pragma comment(lib,"C:\\OpenCV2.2\\lib\\opencv_imgproc220.lib") // opencv_imgproc
#pragma comment(lib,"C:\\OpenCV2.2\\lib\\opencv_highgui220.lib") // opencv_highgui
#endif
#include <XnCppWrapper.h>
#pragma comment(lib,"C:/Program files/OpenNI/Lib/openNI.lib")
#define SAMPLE_XML_PATH "C:/Program Files/OpenNI/Data/SamplesConfig.xml"
using namespace cv;
using namespace xn;
//openNIのための宣言・定義
//マクロ定義
#define KINECT_IMAGE_WIDTH 640
#define KINECT_IMAGE_HEGIHT 480
#define KINECT_DEPTH_WIDTH 640
#define KINECT_DEPTH_HEGIHT 480
DepthGenerator depthGenerator;// depth context
ImageGenerator imageGenerator;//image context
UserGenerator userGenerator;
DepthMetaData depthMD;
ImageMetaData imageMD;
Context context;
//トラッキングの際のコールバック
void XN_CALLBACK_TYPE UserDetected( xn::UserGenerator& generator, XnUserID nId, void* pCookie );
void XN_CALLBACK_TYPE CalibrationEnd(xn::SkeletonCapability& capability, XnUserID nId, XnBool bSuccess, void* pCookie);
Mat image(480,640,CV_8UC3);
Mat depth(480,640,CV_16UC1);
//ポイントクラウドの座標
Mat pointCloud_XYZ(480,640,CV_32FC3,cv::Scalar::all(0));
void retrievePointCloudMap(Mat &depth,Mat &pointCloud_XYZ); //3次元ポイントクラウドのための座標変換
void drawPointCloud(Mat &rgbImage,Mat &pointCloud_XYZ); //ポイントクラウド描画
void drawUserJoint(); //ユーザの関節を描画
void DrawLimb(XnUserID player, XnSkeletonJoint eJoint1, XnSkeletonJoint eJoint2);
void DrawJoint(XnUserID player, XnSkeletonJoint eJoint1);
//openGLのための宣言・定義
//---変数宣言---
int FormWidth = 640;
int FormHeight = 480;
int mButton;
float twist, elevation, azimuth;
float cameraDistance = 0,cameraX = 0,cameraY = 0;
int xBegin, yBegin;
//---マクロ定義---
#define glFovy 45 //視角度
#define glZNear 1.0 //near面の距離
#define glZFar 150.0 //far面の距離
void polarview(); //視点変更
//描画
void display(){
// clear screen and depth buffer
glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
// Reset the coordinate system before modifying
glLoadIdentity();
glEnable(GL_DEPTH_TEST); //「Zバッファ」を有効
gluLookAt(0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0); //視点の向き設定
//wait and error processing
context.WaitAnyUpdateAll();
imageGenerator.GetMetaData(imageMD);
depthGenerator.GetMetaData(depthMD);
depthGenerator.GetAlternativeViewPointCap().SetViewPoint(imageGenerator);//ズレを補正
memcpy(image.data,imageMD.Data(),image.step * image.rows); //イメージデータを格納
memcpy(depth.data,depthMD.Data(),depth.step * depth.rows); //深度データを格納
//3次元ポイントクラウドのための座標変換
retrievePointCloudMap(depth,pointCloud_XYZ);
//視点の変更
polarview();
//ポイントクラウド
drawPointCloud(image,pointCloud_XYZ);
//関節の描画
drawUserJoint();
//convert color space RGB2BGR
cvtColor(image,image,CV_RGB2BGR);
imshow("image",image);
imshow("depth",depth);
glFlush();
glutSwapBuffers();
}
//初期化
void init(){
context.InitFromXmlFile(SAMPLE_XML_PATH);
context.FindExistingNode(XN_NODE_TYPE_DEPTH, depthGenerator);
context.FindExistingNode(XN_NODE_TYPE_IMAGE, imageGenerator);
context.FindExistingNode(XN_NODE_TYPE_USER, userGenerator);
if (!userGenerator.IsCapabilitySupported(XN_CAPABILITY_SKELETON)) { // スケルトン・トラッキングをサポートしているか確認
printf("ユーザー検出をサポートしてません\n");
}
// キャリブレーションにポーズが必要
xn::SkeletonCapability skeleton = userGenerator.GetSkeletonCap();
if ( skeleton.NeedPoseForCalibration() ) {
printf("このOpenNIのバージョンはポーズ無しには対応していません\n");
}
// ユーザー認識のコールバックを登録
// キャリブレーションのコールバックを登録
XnCallbackHandle userCallbacks, calibrationCallbacks;
userGenerator.RegisterUserCallbacks(&::UserDetected, 0, 0, userCallbacks);
skeleton.RegisterCalibrationCallbacks( 0, &::CalibrationEnd, 0, calibrationCallbacks );
skeleton.SetSkeletonProfile(XN_SKEL_PROFILE_ALL);
}
// アイドル時のコールバック
void idle(){
//再描画要求
glutPostRedisplay();
}
//ウィンドウのサイズ変更
void reshape (int width, int height){
FormWidth = width;
FormHeight = height;
glViewport (0, 0, (GLsizei)width, (GLsizei)height);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
//射影変換行列の指定
gluPerspective (glFovy, (GLfloat)width / (GLfloat)height,glZNear,glZFar);
glMatrixMode (GL_MODELVIEW);
}
//マウスの動き
void motion(int x, int y){
int xDisp, yDisp;
xDisp = x - xBegin;
yDisp = y - yBegin;
switch (mButton) {
case GLUT_LEFT_BUTTON:
azimuth += (float) xDisp/2.0;
elevation -= (float) yDisp/2.0;
break;
case GLUT_MIDDLE_BUTTON:
cameraX -= (float) xDisp/40.0;
cameraY += (float) yDisp/40.0;
break;
case GLUT_RIGHT_BUTTON:
cameraDistance += (float) xDisp/40.0;
break;
}
xBegin = x;
yBegin = y;
}
//マウスの操作
void mouse(int button, int state, int x, int y){
if (state == GLUT_DOWN) {
switch(button) {
case GLUT_RIGHT_BUTTON:
case GLUT_MIDDLE_BUTTON:
case GLUT_LEFT_BUTTON:
mButton = button;
break;
}
xBegin = x;
yBegin = y;
}
}
//視点変更
void polarview(){
glTranslatef( cameraX, cameraY, cameraDistance);
glRotatef( -twist, 0.0, 0.0, 1.0);
glRotatef( -elevation, 1.0, 0.0, 0.0);
glRotatef( -azimuth, 0.0, 1.0, 0.0);
}
//メイン
int main(int argc, char *argv[]){
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(FormWidth, FormHeight);
glutCreateWindow(argv[0]);
//コールバック
glutReshapeFunc (reshape);
glutDisplayFunc(display);
glutIdleFunc(idle);
glutMouseFunc(mouse);
glutMotionFunc(motion);
init();
glutMainLoop();
context.Shutdown();
return 0;
}
//ポイントクラウド描画
void drawPointCloud(Mat &rgbImage,Mat &pointCloud_XYZ){
static int x,y;
glPointSize(2);
glBegin(GL_POINTS);
uchar *p = rgbImage.data;
Point3f *point = (Point3f*)pointCloud_XYZ.data;
for(y = 0;y < KINECT_DEPTH_HEGIHT;y++){
for(x = 0;x < KINECT_DEPTH_WIDTH;x++,p += 3,point++){
if(point->z == 0)
continue;
glColor3ubv(p);
glVertex3f(point->x,point->y,point->z);
}
}
glEnd();
}
//3次元ポイントクラウドのための座標変換
void retrievePointCloudMap(Mat &depth,Mat &pointCloud_XYZ){
static const int size = KINECT_DEPTH_HEGIHT * KINECT_DEPTH_WIDTH;
static XnPoint3D proj[size] = {0};
static int x,y;
XnPoint3D *p = proj;
unsigned short* dp = (unsigned short*)depth.data;
for(y = 0; y < KINECT_DEPTH_HEGIHT; y++ ){
for(x = 0; x < KINECT_DEPTH_WIDTH; x++, p++, dp++){
p->X = x;
p->Y = y;
p->Z = *dp * 0.001f; // from mm to meters
}
}
//現実座標に変換
depthGenerator.ConvertProjectiveToRealWorld(size, proj, (XnPoint3D*)pointCloud_XYZ.data);
}
//人物の骨格を描画
void drawUserJoint(){
XnUserID aUsers[15];
XnUInt16 nUsers = 15;
userGenerator.GetUsers(aUsers, nUsers);
for (int i = 0; i < nUsers; ++i){
if (userGenerator.GetSkeletonCap().IsTracking(aUsers[i])){
//各関節に点を打つ
glPointSize(5);
glBegin(GL_POINTS);
glColor4f(0,255,0, 1);
for(int Joint = XN_SKEL_HEAD;Joint < XN_SKEL_RIGHT_FOOT + 1;Joint++)
DrawJoint(aUsers[i],(XnSkeletonJoint)Joint);
glEnd();
//各肢に線を書く
glBegin(GL_LINES);
glColor4f(255,0,0, 1);
DrawLimb(aUsers[i], XN_SKEL_HEAD, XN_SKEL_NECK);
DrawLimb(aUsers[i], XN_SKEL_NECK, XN_SKEL_LEFT_SHOULDER);
DrawLimb(aUsers[i], XN_SKEL_LEFT_SHOULDER, XN_SKEL_LEFT_ELBOW);
DrawLimb(aUsers[i], XN_SKEL_LEFT_ELBOW, XN_SKEL_LEFT_HAND);
DrawLimb(aUsers[i], XN_SKEL_NECK, XN_SKEL_RIGHT_SHOULDER);
DrawLimb(aUsers[i], XN_SKEL_RIGHT_SHOULDER, XN_SKEL_RIGHT_ELBOW);
DrawLimb(aUsers[i], XN_SKEL_RIGHT_ELBOW, XN_SKEL_RIGHT_HAND);
DrawLimb(aUsers[i], XN_SKEL_LEFT_SHOULDER, XN_SKEL_TORSO);
DrawLimb(aUsers[i], XN_SKEL_RIGHT_SHOULDER, XN_SKEL_TORSO);
DrawLimb(aUsers[i], XN_SKEL_TORSO, XN_SKEL_LEFT_HIP);
DrawLimb(aUsers[i], XN_SKEL_LEFT_HIP, XN_SKEL_LEFT_KNEE);
DrawLimb(aUsers[i], XN_SKEL_LEFT_KNEE, XN_SKEL_LEFT_FOOT);
DrawLimb(aUsers[i], XN_SKEL_TORSO, XN_SKEL_RIGHT_HIP);
DrawLimb(aUsers[i], XN_SKEL_RIGHT_HIP, XN_SKEL_RIGHT_KNEE);
DrawLimb(aUsers[i], XN_SKEL_RIGHT_KNEE, XN_SKEL_RIGHT_FOOT);
DrawLimb(aUsers[i], XN_SKEL_LEFT_HIP, XN_SKEL_RIGHT_HIP);
glEnd();
}
}
}
void DrawJoint(XnUserID player, XnSkeletonJoint eJoint){
XnSkeletonJointPosition joint;
userGenerator.GetSkeletonCap().GetSkeletonJointPosition(player, eJoint, joint);
//信頼性の低い場合描画しない
if (joint.fConfidence < 0.5)
return;
glVertex3f(joint.position.X* 0.001f, joint.position.Y* 0.001f, joint.position.Z* 0.001f);
}
void DrawLimb(XnUserID player, XnSkeletonJoint eJoint1, XnSkeletonJoint eJoint2){
XnSkeletonJointPosition joint1, joint2;
userGenerator.GetSkeletonCap().GetSkeletonJointPosition(player, eJoint1, joint1);
userGenerator.GetSkeletonCap().GetSkeletonJointPosition(player, eJoint2, joint2);
//信頼性の低い場合描画しない
if (joint1.fConfidence < 0.5 || joint2.fConfidence < 0.5)
return;
glVertex3f(joint1.position.X* 0.001f, joint1.position.Y* 0.001f, joint1.position.Z* 0.001f);
glVertex3f(joint2.position.X* 0.001f, joint2.position.Y* 0.001f, joint2.position.Z* 0.001f);
}
// ユーザー検出
void XN_CALLBACK_TYPE UserDetected( xn::UserGenerator& generator, XnUserID nId, void* pCookie )
{
printf("ユーザID%d 検出 %d人目\n",nId,generator.GetNumberOfUsers());
generator.GetSkeletonCap().RequestCalibration(nId, TRUE);
}
// キャリブレーションの終了
void XN_CALLBACK_TYPE CalibrationEnd(xn::SkeletonCapability& capability, XnUserID nId, XnBool bSuccess, void* pCookie)
{
if ( bSuccess ) {
printf("ユーザID%d キャリブレーション成功\n",nId);
capability.StartTracking(nId);
}
else {
printf("ユーザID%d キャリブレーション失敗\n",nId);
}
}
</pre>
<br />
<br />
<a href="https://github.com/kassy708/OpenNI-Sample/zipball/master">プログラムダウンロード</a><br />
<br />
<a href="https://github.com/kassy708/OpenNI-Sample/blob/master/PointCloud-SkeletonTracking/main.cpp">github</a>kassy708http://www.blogger.com/profile/00025482097446561673noreply@blogger.com0tag:blogger.com,1999:blog-171901102439270531.post-48046724239039594212011-12-31T14:48:00.000+09:002012-01-13T00:47:12.095+09:00enchant.js物理シミュレーションプラグインPhySpriteを作ってみたenchant.js用の物理シミュレーションプラグインを作りました。<br />
<br />
物理シミュレーションには<a href="http://code.google.com/p/box2dweb/">Box2dWeb</a>を用いてます。<br />
<br />
PhySprite.enchant.jsのダウンロード<br />
<a href="https://github.com/kassy708/enchant.js-plugin/zipball/master">ダウンロード</a><br />
<a href="http://kassy708.github.com/" target="_blank">リファレンス </a><br />
<br />
<br />
<a href="https://github.com/kassy708/enchant.js-plugin/tree/master/PhySprite">github</a><br />
<br />
<br />
<br />
また<a href="http://code.google.com/p/box2dweb/">Box2dWeb</a>のサイトから「Box2dWeb-○○○.js」の最新版をダウンロードして、「PhySprite.enchant.js」と同じフォルダに入れてください。<br />
<br />
<br />
<br />
使い方<br />
<hr />
<br />
・プラグインの読み込み<br />
<br />
index.htmlでenchant.jsの後に以下のファイルを読み込んでください<br />
・Box2DWeb-○○○.js<br />
・PhySprite.enchant.js<br />
<pre class="prettyprint">
<script type="text/javascript" src="enchant.js"></script>
<!-- プラグイン読み込み -->
<script type="text/javascript" src="Box2dWeb-2.1.a.3.js"></script>
<script type="text/javascript" src="PhySprite.enchant.js"></script>
</pre>
<br />
<br />
・ワールド生成
<br />
<pre class="prettyprint">
//物理シミュレーションの世界を設定(y軸方向に重力 9.8[m/s^2])
physicsWorld = new PhysicsWorld(0, 9.8);
</pre>
<br />
<br />
・物理シミュレーション用Spriteの生成
<br />
<pre class="prettyprint">
//ボール生成
var phyBall = new PhyCircleSprite(8, DYNAMIC_SPRITE, 1.0, 0.5, 0.2, true);
phyBall.image = game.assets["icon1.png"];
phyBall.position = { x: 160, y: 10 };
game.rootScene.addChild(phyBall); // シーンに追加
//床生成
var floor = new PhyBoxSprite(256, 16, STATIC_SPRITE, 1.0, 0.5, 0.3, true);
floor.image = game.assets["floor.gif"];
floor.position = { x: 160, y: 300 };
game.rootScene.addChild(floor);
</pre>
<br />
<br />
・毎フレームの処理
<br />
<pre class="prettyprint">
//毎フレーム処理
game.rootScene.addEventListener(enchant.Event.ENTER_FRAME, function (e) {
physicsWorld.step(game.fps); //物理シミュレーション内の時間を進める
});</pre>
<br />
PhyCircleSpriteは円、PhyBoxSpriteは四角の物理シミュレーションSpriteです<br />
enchant.Spriteを継承しています<br />
<br />
生成時の引数は<br />
<pre class="prettyprint">
PhyBoxSprite(width, height, staticOrDynamic, density, friction, restitution, isSleeping);
PhyCircleSprite(radius, staticOrDynamic, density, friction, restitution, isSleeping);
</pre>
<br />
引数の説明<br />
width:Spriteの横幅.<br />
height:Spriteの高さ.<br />
radius:Spriteの半径.<br />
staticOrDynamic:静止物体か動体か。STATIC_SPRITEの時、動かない物体。DYNAMIC_SPRITEの時、動く物体<br />
density:Spriteの密度.<br />
friction:Spriteの摩擦.<br />
restitution:Spriteの反発.<br />
isSleeping:Spriteが初めから物理演算を行うか.<br />
<br />
<br />
では、サンプルプログラム1<br />
<pre class="prettyprint">
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<title>PhySprite demo</title>
<script type="text/javascript" src="enchant.js"></script>
<!-- プラグイン読み込み -->
<script type="text/javascript" src="Box2dWeb-2.1.a.3.js"></script>
<script type="text/javascript" src="PhySprite.enchant.js"></script>
<script type="text/javascript">
enchant();
window.onload = function () {
var game = new Game(320, 320);
game.fps = 24;
game.preload("icon1.png", "floor.gif");
game.rootScene.backgroundColor = "black";
game.onload = function () {
//物理シミュレーションの世界を設定(y軸方向に重力 9.8[m/s^2])
var physicsWorld = new PhysicsWorld(0, 9.8);
//ボール生成
var phyBall = new PhyCircleSprite(8, DYNAMIC_SPRITE, 1.0, 0.5, 0.2, true);
phyBall.image = game.assets["icon1.png"];
phyBall.position = { x: 160, y: 10 };
game.rootScene.addChild(phyBall); // シーンに追加
//床生成
var floor = new PhyBoxSprite(256, 16, STATIC_SPRITE, 1.0, 0.5, 0.3, true);
floor.image = game.assets["floor.gif"];
floor.position = { x: 160, y: 300 };
game.rootScene.addChild(floor);
game.rootScene.addEventListener(enchant.Event.ENTER_FRAME, function (e) {
physicsWorld.step(game.fps); //物理シミュレーション内の時間を進める
});
};
game.start(); // ゲームスタート
}
</script>
<style type="text/css">
body
{
margin: 0px;
}
</style>
</head>
<body>
</body>
</html>
</pre>
<br />
PhySprite.enchant.jsのサンプル2
<br />
<script src="http://9leap.net/games/1068/embed.js" type="text/javascript">
</script>
<br />
<br />
<br />
<br />
<a href="http://kassy708.github.com/" target="_blank">リファレンス </a>kassy708http://www.blogger.com/profile/00025482097446561673noreply@blogger.com3tag:blogger.com,1999:blog-171901102439270531.post-32627699373316794982011-11-12T17:39:00.001+09:002011-12-11T23:38:11.603+09:00Kinect OpenNIによるWindowsでのマルチキネクト - UDPKinectを複数使う場合、Macならマルチキネクト(Multi-Kinect)が可能です。<br />
<br />
<strike>しかし、Windows環境ではまだドライバが対応しておらず、マルチキネクト(Multi-Kinect)を行うことができません。</strike><br />
できるみたいです。<br />
USB端子の大元?が異なる端子で繋げば出来るみたい。<br />
ex)デスクトップPCの前面パネルと後面パネルのUSB端子<br />
<br />
<br />
ドライバが対応してないなら、違うPCで動かせばいいじゃない<br />
<br />
っということで取得したKinectの画像を送受信してみます。<br />
<br />
<br />
今回はUDPによって送受信を行います。<br />
<br />
UDPはTCPと違い、相手に正しくデータが届くとは限りません。<br />
届いたかどうかや誤りの確認をしていないからです。<br />
そのかわり、高速でデータを送信することが可能となります。<br />
よく、音声や画像のストリーム形式での配信に用いられるプロトコルです。<br />
<br />
<br />
まず、Kinectから取得できるRGB画像と深度画像のサイズを計算してみます。<br />
<br />
RGB画像<br />
8bit (1byte)<br />
3Channel -> 921600byte -> 900KB<br />
480 * 640<br />
<br />
深度画像<br />
16bit (2byte)<br />
1Channel -> 614400byte -> 600KB<br />
480 * 640<br />
<br />
合計 1500KB<br />
<br />
RGB画像と深度画像のサイズは1500KB(約1.5MB)となります。<br />
<br />
<br />
結構大きいですね・・・<br />
<br />
<br />
では、このデータをUDPで送信することになりますが、UDPはこのような大きなサイズを一気に送ることはできません。<br />
なので分割して送ります。<br />
<br />
大体UDPで送ることができる最大サイズは60KBくらいなので、60KBで分割します。<br />
<br />
RGB画像:900KB / 60KB = 15分割<br />
深度画像:600KB / 60KB = 10分割<br />
<br />
<br />
このことを頭において、プログラムを作ると<br />
<br />
<br />
<br />
送信<br />
<fieldset>
/*<br />
送信<br />
ServerName : IPアドレス<br />
PortNo : ポート番号<br />
image : 送信するRGBイメージ<br />
depth : 送信する深度イメージ<br />
*/<br />
int sendKinectImage(char*ServerName,unsigned short PortNo,Mat &image,Mat &depth){<br />
HOSTENT*pHostent=gethostbyname(ServerName);<br />
if(pHostent==NULL){<br />
DWORD addr=inet_addr(ServerName);<br />
pHostent=gethostbyaddr((char*)&addr,4,AF_INET);<br />
}<br />
if(pHostent==NULL) return -1;//サーバーが見つかりません<br />
<br />
SOCKET s = socket(AF_INET,SOCK_DGRAM,0);<br />
if(s<0) return -2;//ソケットエラー<br />
<br />
SOCKADDR_IN sockaddrin;<br />
memset(&sockaddrin,0,sizeof(sockaddrin));<br />
memcpy(&(sockaddrin.sin_addr),pHostent->h_addr_list[0],pHostent->h_length);<br />
sockaddrin.sin_family = AF_INET;<br />
sockaddrin.sin_port = htons(PortNo);<br />
<br />
//RGBイメージ<br />
static const int sendSize = 61440; //1度に送信する画像のバッファサイズ:60KB(61440byte)<br />
static char buff[sendSize + 2]; //送信するバッファ(ヘッダ部 + 画像データ)<br />
static const int divImageNum = (image.rows * image.step) / sendSize; //RGB画像の分割数<br />
static const int divDepthNum = (depth.rows * depth.step) / sendSize; //深度画像の分割数<br />
<br />
//RGBイメージ<br />
for(int i = 0;i < divImageNum;i++){<br />
//ヘッダ部の入力<br />
buff[0] = 'R'; //RGB画像だという識別記号<br />
buff[1] = i; //分割された何番目か<br />
//画像データの入力<br />
memcpy(&buff[2],&image.data[sendSize * i],sendSize);<br />
sendto(s,buff,sendSize + 2,4,(LPSOCKADDR)&sockaddrin,sizeof(sockaddrin));<br />
<br />
}<br />
//Depthイメージ<br />
for(int i = 0;i < divDepthNum;i++){ <br />
//ヘッダ部の入力<br />
buff[0] = 'D'; //Depth画像だという識別記号<br />
buff[1] = i; //分割された何番目か<br />
//画像データの入力<br />
memcpy(&buff[2],&depth.data[sendSize * i],sendSize);<br />
sendto(s,buff,sendSize + 2,4,(LPSOCKADDR)&sockaddrin,sizeof(sockaddrin));<br />
}<br />
closesocket(s);<br />
return 0; //成功<br />
}</fieldset>
<br />
<br />
<br />
<br />
送信するためにbuffという配列を用意します。<br />
<br />
buffには画像に関する情報のヘッダ部と画像データを格納します。<br />
<br />
<br />
ここでヘッダ部では<br />
buff[0]にRGB画像か深度画像か判別する情報を入れます<br />
つぎに <br />
buff[1]にこのデータが何分割目のデータを格納します。<br />
なぜこのようなことをするのかというと、UDPは送信したデータが相手に届くかわからず、また順番も送信した順になるとはかぎりません。<br />
なので、受信側が分割されたデータを1つの画像に復元する際、必要になります。<br />
<br />
<br />
<br />
データの送信はsendtoで行います<br />
<br />
<br />
次に受信<br />
<br />
<br />
受信<br />
<br />
<fieldset>
/*<br />
受信<br />
PortNo : ポート番号<br />
image : 受信したRGBイメージを格納する変数<br />
depth : 受信した深度イメージを格納する変数<br />
*/<br />
int receiveKinectImage(unsigned short PortNo,Mat &image,Mat &depth){ <br />
SOCKET s = socket(AF_INET,SOCK_DGRAM,0);<br />
if(s<0) return -1;//ソケットエラー<br />
<br />
SOCKADDR_IN sockaddrin;<br />
memset(&sockaddrin,0,sizeof(sockaddrin));<br />
sockaddrin.sin_family = AF_INET;<br />
sockaddrin.sin_port = htons(PortNo);<br />
sockaddrin.sin_addr.S_un.S_addr = INADDR_ANY;<br />
if(SOCKET_ERROR == bind(s,(LPSOCKADDR)&sockaddrin,(int)sizeof(sockaddrin))){<br />
closesocket(s);<br />
return -2;//bindエラー<br />
}<br />
SOCKADDR_IN from;<br />
int fromlen=(int)sizeof(from);<br />
<br />
static const int receiveSize = 61440; //1度に受信する画像のバッファサイズ 60KB(61440byte)<br />
static char buff[receiveSize + 2]; //受信するバッファ(ヘッダ部 + 画像データ)<br />
static const int divImageNum = (image.rows * image.step) / receiveSize; //RGB画像の分割数<br />
static const int divDepthNum = (depth.rows * depth.step) / receiveSize; //深度画像の分割数<br />
static int re;<br />
static char header;<br />
static char divNum;<br />
static int identificationNum;<br />
static char imageOrDepth;<br />
<br />
re = recvfrom(s,buff,receiveSize + 2,0,(SOCKADDR*)&from,&fromlen);//受信するまでここで停止<br />
if(re!=SOCKET_ERROR){//エラーで無ければ表示<br />
imageOrDepth = buff[0]; //RGB画像か深度画像か<br />
divNum = buff[1]; //分割番号<br />
<br />
if(imageOrDepth == 'R') //RGBイメージ<br />
memcpy(&image.data[receiveSize * divNum],&buff[2],receiveSize);<br />
<br />
else if(imageOrDepth == 'D') //Depthイメージ<br />
memcpy(&depth.data[receiveSize * divNum],&buff[2],receiveSize);<br />
}<br />
<br />
closesocket(s);<br />
return 0;<br />
}</fieldset>
<br />
<br />
ヘッダ部の情報を元に、RGB画像か深度画像のどちらにデータを格納するか選び<br />
分割番号を元に、格納するデータの位置を決定します。 <br />
<br />
<br />
<br />
これでKinectの画像データを他のPCに送ることができます。<br />
<br />
<br />
<br />
データの受信はrecvfromで行います<br />
ちなみにrecvfromはデータを受信するまで、待ち状態になります。 <br />
利用する際は、受信は別スレッドで動作させましょう。<br />
<br />
<br />
ここではUDPのくわしいプログラムは説明しません。<br />
<br />
各自調べてください。<br />
<br />
<br />
<br />
これでWindows環境でもマルチキネクト(<span class="short_text" id="result_box" lang="en"><span class="hps atn">Multi-Kinect</span></span>) が可能に!?<br />
<br />
骨格情報に関しては紹介しませんでしたが、同じような感じでできるんじゃないでしょうか。<br />
<br />
<br />
<br />
<br />
ということで、サンプルプログラムどん<br />
<br />
<fieldset>
#include <winsock2.h><br />
#pragma comment(lib, "wsock32.lib")<br />
#include <opencv2/opencv.hpp><br />
#ifdef _DEBUG<br />
//Debugモードの場合<br />
#pragma comment(lib,"C:\\OpenCV2.2\\lib\\opencv_core220d.lib") // opencv_core<br />
#pragma comment(lib,"C:\\OpenCV2.2\\lib\\opencv_imgproc220d.lib") // opencv_imgproc<br />
#pragma comment(lib,"C:\\OpenCV2.2\\lib\\opencv_highgui220d.lib") // opencv_highgui<br />
#else<br />
//Releaseモードの場合<br />
#pragma comment(lib,"C:\\OpenCV2.2\\lib\\opencv_core220.lib") // opencv_core<br />
#pragma comment(lib,"C:\\OpenCV2.2\\lib\\opencv_imgproc220.lib") // opencv_imgproc<br />
#pragma comment(lib,"C:\\OpenCV2.2\\lib\\opencv_highgui220.lib") // opencv_highgui<br />
#endif<br />
#include <XnCppWrapper.h><br />
#pragma comment(lib,"C:/Program files/OpenNI/Lib/openNI.lib")<br />
<br />
#define SAMPLE_XML_PATH "C:/Program Files/OpenNI/Data/SamplesConfig.xml"<br />
using namespace cv;<br />
using namespace xn;<br />
<br />
//受信スレッド<br />
DWORD WINAPI ThreadFunc(LPVOID vdParam);<br />
int sendKinectImage(char*ServerName,unsigned short PortNo,Mat &image,Mat &depth); //送信<br />
int receiveKinectImage(unsigned short PortNo,Mat &image,Mat &depth); //受信<br />
<br />
//ポート番号<br />
#define PORT 1000<br />
//IPアドレス(送信するPCのIPアドレスを指定してください)<br />
#define SEND_IPADDRESS "192.168.12.55"<br />
//送信するか受信するか<br />
enum Type{SEND,RECEIVE}; <br />
<br />
<br />
Mat receiveImage(480,640,CV_8UC3); //受信RGB画像<br />
Mat receiveDepth(480,640,CV_16UC1); //受信深度画像<br />
<br />
int main()<br />
{<br />
//OpenNI<br />
DepthGenerator depthGenerator;<br />
ImageGenerator imageGenerator;<br />
DepthMetaData depthMD;<br />
ImageMetaData imageMD;<br />
Context context;<br />
<br />
//OpenCV<br />
Mat image(480,640,CV_8UC3); //RGB画像<br />
Mat depth(480,640,CV_16UC1); //深度画像<br />
<br />
//OpenNIの初期化<br />
context.InitFromXmlFile(SAMPLE_XML_PATH); <br />
context.FindExistingNode(XN_NODE_TYPE_DEPTH, depthGenerator); <br />
context.FindExistingNode(XN_NODE_TYPE_IMAGE, imageGenerator);<br />
<br />
//RGB画像と振動画像のズレを補正<br />
depthGenerator.GetAlternativeViewPointCap().SetViewPoint(imageGenerator);<br />
<br />
//送信するか受信するか<br />
//Type sendOrReceive = SEND; //送信する<br />
Type sendOrReceive = RECEIVE; //受信する<br />
<br />
DWORD dwID; //スレッドのID<br />
if(sendOrReceive == RECEIVE){<br />
//受信スレッド起動<br />
CreateThread(NULL , 0 , ThreadFunc , 0 , 0 , &dwID);<br />
cvNamedWindow("receiveImage"); //ウィンドウの準備<br />
cvNamedWindow("receiveDepth");<br />
}<br />
<br />
//ウィンドウの準備<br />
cvNamedWindow("image");<br />
cvNamedWindow("depth");<br />
int key = 0;<br />
while (key!='q'){<br />
context.WaitAndUpdateAll();<br />
<br />
imageGenerator.GetMetaData(imageMD);<br />
depthGenerator.GetMetaData(depthMD);<br />
<br />
memcpy(image.data,imageMD.Data(),image.step * image.rows); //イメージデータを格納<br />
memcpy(depth.data,depthMD.Data(),depth.step * depth.rows); //深度データを格納<br />
<br />
//BGRをRGBへ<br />
cvtColor(image,image,CV_RGB2BGR);<br />
<br />
//画面に表示<br />
imshow("image",image);<br />
imshow("depth",depth);<br />
<br />
if(sendOrReceive == SEND){ //送信 <br />
sendKinectImage(SEND_IPADDRESS,PORT,image,depth);<br />
}<br />
else if(sendOrReceive == RECEIVE){ //受信<br />
//受信した画像を表示する<br />
imshow("receiveImage",receiveImage);<br />
imshow("receiveDepth",receiveDepth);<br />
}<br />
<br />
key = waitKey(33);<br />
}<br />
context.Shutdown();<br />
return 0;<br />
}<br />
<br />
/*<br />
送信<br />
ServerName : IPアドレス<br />
PortNo : ポート番号<br />
image : 送信するRGBイメージ<br />
depth : 送信する深度イメージ<br />
*/<br />
int sendKinectImage(char*ServerName,unsigned short PortNo,Mat &image,Mat &depth){<br />
HOSTENT*pHostent=gethostbyname(ServerName);<br />
if(pHostent==NULL){<br />
DWORD addr=inet_addr(ServerName);<br />
pHostent=gethostbyaddr((char*)&addr,4,AF_INET);<br />
}<br />
if(pHostent==NULL) return -1;//サーバーが見つかりません<br />
<br />
SOCKET s = socket(AF_INET,SOCK_DGRAM,0);<br />
if(s<0) return -2;//ソケットエラー<br />
<br />
SOCKADDR_IN sockaddrin;<br />
memset(&sockaddrin,0,sizeof(sockaddrin));<br />
memcpy(&(sockaddrin.sin_addr),pHostent->h_addr_list[0],pHostent->h_length);<br />
sockaddrin.sin_family = AF_INET;<br />
sockaddrin.sin_port = htons(PortNo);<br />
<br />
//RGBイメージ<br />
static const int sendSize = 61440; //1度に送信する画像のバッファサイズ:60KB(61440byte)<br />
static char buff[sendSize + 2]; //送信するバッファ(ヘッダ部 + 画像データ)<br />
static const int divImageNum = (image.rows * image.step) / sendSize; //RGB画像の分割数<br />
static const int divDepthNum = (depth.rows * depth.step) / sendSize; //深度画像の分割数<br />
<br />
//RGBイメージ<br />
for(int i = 0;i < divImageNum;i++){<br />
//ヘッダ部の入力<br />
buff[0] = 'R'; //RGB画像だという識別記号<br />
buff[1] = i; //分割された何番目か<br />
//画像データの入力<br />
memcpy(&buff[2],&image.data[sendSize * i],sendSize);<br />
sendto(s,buff,sendSize + 2,4,(LPSOCKADDR)&sockaddrin,sizeof(sockaddrin));<br />
<br />
}<br />
//Depthイメージ<br />
for(int i = 0;i < divDepthNum;i++){ <br />
//ヘッダ部の入力<br />
buff[0] = 'D'; //Depth画像だという識別記号<br />
buff[1] = i; //分割された何番目か<br />
//画像データの入力<br />
memcpy(&buff[2],&depth.data[sendSize * i],sendSize);<br />
sendto(s,buff,sendSize + 2,4,(LPSOCKADDR)&sockaddrin,sizeof(sockaddrin));<br />
}<br />
closesocket(s);<br />
return 0; //成功<br />
}<br />
/*<br />
受信<br />
PortNo : ポート番号<br />
image : 受信したRGBイメージを格納する変数<br />
depth : 受信した深度イメージを格納する変数<br />
*/<br />
int receiveKinectImage(unsigned short PortNo,Mat &image,Mat &depth){ <br />
SOCKET s = socket(AF_INET,SOCK_DGRAM,0);<br />
if(s<0) return -1;//ソケットエラー<br />
<br />
SOCKADDR_IN sockaddrin;<br />
memset(&sockaddrin,0,sizeof(sockaddrin));<br />
sockaddrin.sin_family = AF_INET;<br />
sockaddrin.sin_port = htons(PortNo);<br />
sockaddrin.sin_addr.S_un.S_addr = INADDR_ANY;<br />
if(SOCKET_ERROR == bind(s,(LPSOCKADDR)&sockaddrin,(int)sizeof(sockaddrin))){<br />
closesocket(s);<br />
return -2;//bindエラー<br />
}<br />
SOCKADDR_IN from;<br />
int fromlen=(int)sizeof(from);<br />
<br />
static const int receiveSize = 61440; //1度に受信する画像のバッファサイズ 60KB(61440byte)<br />
static char buff[receiveSize + 2]; //受信するバッファ(ヘッダ部 + 画像データ)<br />
static const int divImageNum = (image.rows * image.step) / receiveSize; //RGB画像の分割数<br />
static const int divDepthNum = (depth.rows * depth.step) / receiveSize; //深度画像の分割数<br />
static int re;<br />
static char header;<br />
static char divNum;<br />
static int identificationNum;<br />
static char imageOrDepth;<br />
<br />
re = recvfrom(s,buff,receiveSize + 2,0,(SOCKADDR*)&from,&fromlen);//受信するまでここで停止<br />
if(re!=SOCKET_ERROR){//エラーで無ければ表示<br />
imageOrDepth = buff[0]; //RGB画像か深度画像か<br />
divNum = buff[1]; //分割番号<br />
<br />
if(imageOrDepth == 'R') //RGBイメージ<br />
memcpy(&image.data[receiveSize * divNum],&buff[2],receiveSize);<br />
<br />
else if(imageOrDepth == 'D') //Depthイメージ<br />
memcpy(&depth.data[receiveSize * divNum],&buff[2],receiveSize);<br />
}<br />
<br />
closesocket(s);<br />
return 0;<br />
}<br />
//受信スレッド<br />
DWORD WINAPI ThreadFunc(LPVOID vdParam) {<br />
while (TRUE) {<br />
receiveKinectImage(PORT,receiveImage,receiveDepth);<br />
}<br />
}</fieldset>
<br />
<br />
<br />
<br />
<br />
<br />
参考<br />
<a href="http://7ujm.net/C++/UDP.html">プログラミング色々 </a><br />
<br />
<br />kassy708http://www.blogger.com/profile/00025482097446561673noreply@blogger.com0tag:blogger.com,1999:blog-171901102439270531.post-57212731464944292102011-11-11T21:38:00.001+09:002011-11-14T00:15:40.199+09:00Kinect OpenNIによる人物領域の抽出 - OpenCVOpenNIでは人物の領域をマスク画像として取得することができます。<br />
<br />
そこで、OpenCVのMatを用いてマスク画像から人物のRGB画像、深度画像を取得してみます。<br />
<br />
あと、ついでに背景も抽出してます。<br />
<br />
まず、 「SamplesConfig.xml」を編集します。<br />
<br />
「<Node type="User" name="User1"/>」を追加しましょう。<br />
<br />
<br />
例<br />
<fieldset>
<OpenNI><br />
<Licenses><br />
<!-- Add licenses here <br />
<License vendor="vendor" key="key"/><br />
--><br />
</Licenses><br />
<Log writeToConsole="false" writeToFile="false"><br />
<!-- 0 - Verbose, 1 - Info, 2 - Warning, 3 - Error (default) --><br />
<LogLevel value="3"/><br />
<Masks><br />
<Mask name="ALL" on="true"/><br />
</Masks><br />
<Dumps><br />
</Dumps><br />
</Log><br />
<ProductionNodes><br />
<Node type="Depth" name="Depth1"><br />
<Configuration><br />
<Mirror on="true"/><br />
</Configuration><br />
</Node><br />
<Node type="Image" name="Image1" stopOnError="false"><br />
<Configuration><br />
<Mirror on="true"/><br />
</Configuration><br />
</Node><br />
<Node type="User" name="User1"/><br />
<!--<br />
<Node type="Audio" name="Audio1"/><br />
--><br />
</ProductionNodes><br />
</OpenNI></fieldset>
<br />
これでユーザ検出が可能となりました。<br />
<br />
<br />
てことでサンプルどん<br />
<br />
<fieldset>
#include <opencv2/opencv.hpp><br />
#ifdef _DEBUG<br />
//Debugモードの場合<br />
#pragma comment(lib,"C:\\OpenCV2.2\\lib\\opencv_core220d.lib") // opencv_core<br />
#pragma comment(lib,"C:\\OpenCV2.2\\lib\\opencv_imgproc220d.lib") // opencv_imgproc<br />
#pragma comment(lib,"C:\\OpenCV2.2\\lib\\opencv_highgui220d.lib") // opencv_highgui<br />
#else<br />
//Releaseモードの場合<br />
#pragma comment(lib,"C:\\OpenCV2.2\\lib\\opencv_core220.lib") // opencv_core<br />
#pragma comment(lib,"C:\\OpenCV2.2\\lib\\opencv_imgproc220.lib") // opencv_imgproc<br />
#pragma comment(lib,"C:\\OpenCV2.2\\lib\\opencv_highgui220.lib") // opencv_highgui<br />
#endif<br />
#include <XnCppWrapper.h><br />
#pragma comment(lib,"C:/Program files/OpenNI/Lib/openNI.lib")<br />
<br />
#define SAMPLE_XML_PATH "C:/Program Files/OpenNI/Data/SamplesConfig.xml"<br />
using namespace cv;<br />
using namespace xn;<br />
<br />
int main()<br />
{<br />
//OpenNI<br />
DepthGenerator depthGenerator;<br />
ImageGenerator imageGenerator;<br />
UserGenerator userGenerator;<br />
DepthMetaData depthMD;<br />
ImageMetaData imageMD;<br />
SceneMetaData sceneMD; <br />
Context context;<br />
<br />
//OpenCV<br />
Mat image(480,640,CV_8UC3); //RGB画像<br />
Mat depth(480,640,CV_16UC1); //深度画像<br />
Mat mask(480,640,CV_16UC1); //プレイヤーマスク画像 <br />
Mat player(480,640,CV_8UC3); //人間画像<br />
Mat playerDepth(480,640,CV_16UC1); //人間画像<br />
Mat background(480,640,CV_8UC3); //背景画像<br />
Mat useMask(480,640,CV_16UC1); //使用するマスク<br />
<br />
int maskSize = mask.step * mask.rows; //マスク画像の配列数<br />
<br />
//OpenNIの初期化<br />
context.InitFromXmlFile(SAMPLE_XML_PATH); <br />
context.FindExistingNode(XN_NODE_TYPE_DEPTH, depthGenerator); <br />
context.FindExistingNode(XN_NODE_TYPE_IMAGE, imageGenerator);<br />
context.FindExistingNode(XN_NODE_TYPE_USER, userGenerator);<br />
<br />
//RGB画像と振動画像のズレを補正<br />
depthGenerator.GetAlternativeViewPointCap().SetViewPoint(imageGenerator);<br />
<br />
//ウィンドウの準備<br />
cvNamedWindow("image");<br />
cvNamedWindow("depth");<br />
cvNamedWindow("player");<br />
cvNamedWindow("playerDepth");<br />
cvNamedWindow("background");<br />
<br />
int key = 0;<br />
while (key!='q'){<br />
context.WaitAndUpdateAll();<br />
<br />
imageGenerator.GetMetaData(imageMD);<br />
depthGenerator.GetMetaData(depthMD);<br />
userGenerator.GetUserPixels(0,sceneMD); //ユーザピクセル取得<br />
<br />
memcpy(image.data,imageMD.Data(),image.step * image.rows); //イメージデータを格納<br />
memcpy(depth.data,depthMD.Data(),depth.step * depth.rows); //深度データを格納<br />
<br />
//BGRをRGBへ<br />
cvtColor(image,image,CV_RGB2BGR);<br />
<br />
player = 0; //初期化<br />
playerDepth = 0; //初期化 <br />
memcpy(mask.data,sceneMD.Data(),maskSize); //マスクデータをコピー <br />
mask.convertTo(useMask,CV_8UC1); //マスクの変換<br />
image.copyTo(player,useMask); //マスクを利用した人物抽出<br />
depth.copyTo(playerDepth,useMask); //マスクを利用した人物奥行き抽出<br />
background = image - player; //背景のみ取得<br />
<br />
//画面に表示<br />
imshow("image",image);<br />
imshow("depth",depth);<br />
imshow("player",player);<br />
imshow("playerDepth",playerDepth);<br />
imshow("background",background);<br />
<br />
key = waitKey(33);<br />
}<br />
context.Shutdown();<br />
return 0;<br />
}</fieldset>
<br />
<br />
人物のRGBデータと深度データをマスクを用いて抽出しています。<br />
<br />
マスク画像の取得は<br />
・userGenerator<br />
・sceneMD<br />
この2つを用いて取得します。<br />
<br />
取得したマスク画像を格納するOpenCVのMatクラスはMat mask(480,640,CV_16UC1);です。<br />
<br />
<br />
では、OpenNIからマスク画像の取得方法です。<br />
<br />
<br />
<fieldset>
userGenerator.GetUserPixels(0,sceneMD); //ユーザピクセル取得</fieldset>
<br />
これでsceneMDにマスク画像が格納されました。<br />
<br />
次にsceneMDからmaskにデータを格納します。<br />
<br />
<br />
<br />
<fieldset>
memcpy(mask.data,sceneMD.Data(),maskSize);</fieldset>
<br />
sceneMD.Data()でマスクの配列が取得できるので、その値をそのままmaskにコピーしています。<br />
<br />
<br />
もし、Matを使わずに取得したい場合は <br />
<br />
<fieldset>
g_UserGenerator.GetUserPixels(0,sceneMD); //ピクセル取得<br />
const XnLabel* pLabels = sceneMD.Data();<br />
if(pLabels == NULL){<br />
return;<br />
}</fieldset>
これでpLabelにアクセスすることで可能です。<br />
<br />
1ピクセルだけでいいなら<br />
<fieldset>
sceneMD(x,y)</fieldset>
でいいのかな。 <br />
<br />
<br />
<br />
<br />
次にマスクから人物領域を取得する方法<br />
<br />
<fieldset>
player = 0; //初期化<br />
playerDepth = 0; //初期化 <br />
memcpy(mask.data,sceneMD.Data(),maskSize); //マスクデータをコピー mask.convertTo(useMask,CV_8UC1); //マスクの変換<br />
image.copyTo(player,useMask); //マスクを利用した人物抽出<br />
depth.copyTo(playerDepth,useMask); //マスクを利用した人物奥行き抽出<br />
background = image - player; //背景のみ取得</fieldset>
<br />
まず最初に前回抽出した人物画像を初期化します。<br />
<br />
次にマスクデータをコピー<br />
<br />
そしてつぎ、コピーしたマスクデータのままではcopyToがうまくできないので変換します<br />
<br />
そしてRGB画像と深度画像からそれぞれ人物領域のみを抽出し、コピーします。 <br />
<br />
で、あとはRGB画像から人物画像を引くと、背景のみ取得できます。<br />
<br />
<br />
<br />
この方法ならピクセル一つ一つにアクセスしていないので高速に人物領域の画像を取得することができます。 <br />
<br />kassy708http://www.blogger.com/profile/00025482097446561673noreply@blogger.com0tag:blogger.com,1999:blog-171901102439270531.post-81727494559923525582011-10-28T22:09:00.001+09:002011-10-28T22:18:46.441+09:009leap 「9Days Challenge #5」 & 「コミPo!チャレンジ」優秀賞をいただきました!<br />
9月に開催された「<a href="http://wise9.jp/archives/3874">9leap 9Days Challenge #5</a>」と「<a href="http://wise9.jp/archives/4415">9leap 9Days コミPo! Challenge</a>」にて優秀賞をいただきました!<br />
<br />
<br />
<a href="http://wise9.jp/archives/5108">9leap 「9Days Challenge #5」 & 「コミPo!チャレンジ」結果発表!</a><br />
<br />
優秀賞<br />
「お天気バトル」by kassy708<br />
<script src="http://9leap.net/games/672/embed.js" type="text/javascript">
</script>
<br />
<blockquote class="tr_bq">
現在地の天気がそのまま能力となるゲーム。晴れの日は攻撃力アップ・曇りの日は防御力アップ。全国のその日の天気を参照しているので、自分との相性を考えて敵に戦いを挑むことも…。外に出なくても気温や風の強さが分かるのもポイントかもw @kassy708さんには、賞品「<a href="http://casio.jp/dc/products/ex_h20g/">GPS内蔵デジタルカメラ カシオ EX-H20G</a>」を差し上げます。おめでとうございます!</blockquote>
<br />
優秀賞<br />
まねまねしょーぶ!! by @kassy708<br />
<script src="http://9leap.net/games/693/embed.js" type="text/javascript">
</script>
<br />
<blockquote class="tr_bq">
今回の優秀賞は「まねまねしょーぶ!」です。GPSチャレンジに引き続き二連覇となりました。数字や文字と違って、ポーズを覚えるのは実はなかなか難しい!まずは遊んでみてください。<br />
優秀賞を受賞されたkassy708さんには、「<a href="http://cweb.canon.jp/camera/powershot/g12/index.html">Canon PowerShot G12</a>、<a href="http://www.comipo.com/">コミPo! ダウンロード版および素材集</a>」をお送りします。</blockquote>
<br />
やったあああああああ!!!!<br />
<br />
いや、まさか2つも受賞するとは。。。<br />
<br />
<br />
前からデジカメほしーって思ってたらまさか2つも手に入るとは<br />
<br />
しかも「コミPo! Challenge」の方のカメラはすげー・・・<br />
<br />
使いこなせるかな<br />
<br />
というか手に余る<br />
<br />
また、親にプレゼントしよう。<br />
<br />
<br />
あと、コミPo!便利だけど、ゲーム作りに使ってもいいのかな・・・<br />
<br />
絵が下手だから、これ使えると便利なんだけど。<br />
<br />
<br />
そういや「<a href="http://wise9.jp/archives/3874">9Days Challenge #5</a>」が発表されたけど「<a href="http://wise9.jp/archives/2816">9Days Challenge #4</a>」ってどうなったんだろ<br />
<br />
<br />
テレビとコラボしてるから時間かかってるのかな?<br />
<br />
まあ、いいや<br />
<br />
<br />
これからもいっぱいゲーム作ろう<br />
<br />
やっぱりゲームは楽しんで作らないと!<br />
<br />
<br />
次はenchant PROを使った「<a href="http://www.4gamer.net/games/032/G003263/20111022006/">Open leap</a>」をがんばろうかな<br />
<br />
今作ってるandroidゲームを移植してみよう。kassy708http://www.blogger.com/profile/00025482097446561673noreply@blogger.com0tag:blogger.com,1999:blog-171901102439270531.post-57478121419859893142011-10-05T17:29:00.000+09:002012-02-05T00:43:31.218+09:00Kinect OpenNIによる3次元テクスチャマップ - 3次元描画前回「<a href="http://kassymemo.blogspot.com/2011/09/kinect-openni3-3_27.html">Kinect OpenNIによる3次元ポイントクラウド - 3次元描画</a>」でポイントクラウド(Point Cloud)にしてみました<br />
<br />
しかし、ポイントクラウドでは近づいたときに点と点の隙間から奥の何もない空間が見えてしまい荒く見えてしまいます。<br />
<br />
ということで、次はテクスチャマップ(Texture Maps)してみましょう。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='320' height='266' src='https://www.blogger.com/video.g?token=AD6v5dwfUH1DFa3qaG64BbSXT-rXBddRSO5vrEAoDCQYxxuIBXehSGqsK4l_jQbXJru2smigP-lDllWVuCu8YnCMgg' class='b-hbp-video b-uploaded' frameborder='0'></iframe></div>
<br />
<br />
<br />
<br />
テクスチャを貼るサンプル<br />
<br />
<pre class="prettyprint">//ポイントクラウド描画
void drawTextureMaps(Mat &rgbImage,Mat &pointCloud_XYZ){
static int x,y;
static uchar *p[2];
static Point3f *point[2];
int channel = rgbImage.channels();
p[0] = rgbImage.data; //上の色
p[1] = rgbImage.data + rgbImage.step; //下の色
point[0] = (Point3f*)pointCloud_XYZ.data; //上の座標
point[1] = &((Point3f*)pointCloud_XYZ.data)[KINECT_DEPTH_WIDTH]; //下の座標
for(y = 0;y < KINECT_DEPTH_HEGIHT - 1;y++){
for(x = 0;x < KINECT_DEPTH_WIDTH - 1;x++,p[1] += channel,point[1]++,p[0] += channel,point[0]++){
//奥行きが取得できてなかったら何もしない
if(point[0]->z == 0)
continue;
//対角の奥行きが遠ければテクスチャを貼らない
if(abs(point[0]->z - (point[1] + 1)->z) > THRESHOLD || abs((point[0] + 1)->z - point[1]->z) > THRESHOLD)
continue;
//テクスチャを貼る
glBegin(GL_TRIANGLE_STRIP);
//左上
glTexCoord2f(0, 0);
glColor3ubv(p[0]);
glVertex3f(point[0]->x,point[0]->y,point[0]->z);
//左下
glTexCoord2f(1, 0);
glColor3ubv(p[1]);
glVertex3f(point[1]->x,point[1]->y,point[1]->z);
//右上
glTexCoord2f(0, 1);
glColor3ubv(p[0]+channel);
glVertex3f((point[0] + 1)->x,(point[0] + 1)->y,(point[0] + 1)->z);
//右下
glTexCoord2f(1, 1);
glColor3ubv(p[1]+channel);
glVertex3f((point[1] + 1)->x,(point[1] + 1)->y,(point[1] + 1)->z);
glEnd();
}
p[0] += channel,point[0]++;
p[1] += channel,point[1]++;
}
}
</pre>
<br />
<br />
<pre class="prettyprint">//対角の奥行きが閾値より遠ければテクスチャを貼らない
if(abs(point[0]->z - (point[1] + 1)->z) > THRESHOLD ||
abs((point[0] + 1)->z - point[1]->z) > THRESHOLD)
continue;
</pre>
このif文は隣の画素が閾値より奥行き距離が離れていたらテクスチャを貼らないという処理です<br />
<br />
ここで対角の距離を調べれば4点の奥行きがそれぞれ離れていないことがわかるんじゃないでしょうか。 <br />
<br />
<br />
ちなみに<br />
<br />
glBegin(GL_TRIANGLE_STRIP);<br />
と<br />
glEnd();<br />
の間に書かれた点で面を貼ることができます。<br />
<br />
OpenGLの詳しい説明は調べてください。<br />
<br />
ポインタを使ってOpenCVのMatクラスにアクセスしてるので高速化できてるかと思いますが・・・<br />
<br />
もし、もっと速度が欲しい時は<br />
<br />
GPUを使った描画などで高速化してはどうでしょうか<br />
<br />
glewを使うんですかね?<br />
<br />
今度調べるかもしれません。 <br />
<br />
<br />
<br />
全体サンプル<br />
<br />
<br />
<pre class="prettyprint">#include <GL/glut.h>
#include <opencv2/opencv.hpp>
#ifdef _DEBUG
//Debugモードの場合
#pragma comment(lib,"C:\\OpenCV2.2\\lib\\opencv_core220d.lib") // opencv_core
#pragma comment(lib,"C:\\OpenCV2.2\\lib\\opencv_imgproc220d.lib") // opencv_imgproc
#pragma comment(lib,"C:\\OpenCV2.2\\lib\\opencv_highgui220d.lib") // opencv_highgui
#else
//Releaseモードの場合
#pragma comment(lib,"C:\\OpenCV2.2\\lib\\opencv_core220.lib") // opencv_core
#pragma comment(lib,"C:\\OpenCV2.2\\lib\\opencv_imgproc220.lib") // opencv_imgproc
#pragma comment(lib,"C:\\OpenCV2.2\\lib\\opencv_highgui220.lib") // opencv_highgui
#endif
#include <XnCppWrapper.h>
#pragma comment(lib,"C:/Program files/OpenNI/Lib/openNI.lib")
#define SAMPLE_XML_PATH "C:/Program Files/OpenNI/Data/SamplesConfig.xml"
using namespace cv;
using namespace xn;
//openNIのための宣言・定義
//マクロ定義
#define KINECT_IMAGE_WIDTH 640
#define KINECT_IMAGE_HEGIHT 480
#define KINECT_DEPTH_WIDTH 640
#define KINECT_DEPTH_HEGIHT 480
DepthGenerator depthGenerator;// depth context
ImageGenerator imageGenerator;//image context
DepthMetaData depthMD;
ImageMetaData imageMD;
Context context;
Mat image(480,640,CV_8UC3);
Mat depth(480,640,CV_16UC1);
//ポイントクラウドの座標
Mat pointCloud_XYZ(480,640,CV_32FC3,cv::Scalar::all(0));
void retrievePointCloudMap(Mat &depth,Mat &pointCloud_XYZ); //3次元ポイントクラウドのための座標変換
void drawTextureMaps(Mat &rgbImage,Mat &pointCloud_XYZ); //テクスチャマップ描画
//openGLのための宣言・定義
//---変数宣言---
int FormWidth = 640;
int FormHeight = 480;
int mButton;
float twist, elevation, azimuth;
float cameraDistance = 0,cameraX = 0,cameraY = 0;
int xBegin, yBegin;
//---マクロ定義---
#define glFovy 45 //視角度
#define glZNear 1.0 //near面の距離
#define glZFar 150.0 //far面の距離
void polarview(); //視点変更
//テクスチャを貼る閾値
#define THRESHOLD 0.1
//描画
void display(){
// clear screen and depth buffer
glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
// Reset the coordinate system before modifying
glLoadIdentity();
glEnable(GL_DEPTH_TEST); //「Zバッファ」を有効
gluLookAt(0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0); //視点の向き設定
//wait and error processing
context.WaitAnyUpdateAll();
imageGenerator.GetMetaData(imageMD);
depthGenerator.GetMetaData(depthMD);
depthGenerator.GetAlternativeViewPointCap().SetViewPoint(imageGenerator);//ズレを補正
memcpy(image.data,imageMD.Data(),image.step * image.rows); //イメージデータを格納
memcpy(depth.data,depthMD.Data(),depth.step * depth.rows); //深度データを格納
//3次元ポイントクラウドのための座標変換
retrievePointCloudMap(depth,pointCloud_XYZ);
//視点の変更
polarview();
//テクスチャマップ
drawTextureMaps(image,pointCloud_XYZ);
//convert color space RGB2BGR
cvtColor(image,image,CV_RGB2BGR);
imshow("image",image);
imshow("depth",depth);
glFlush();
glutSwapBuffers();
}
//初期化
void init(){
context.InitFromXmlFile(SAMPLE_XML_PATH);
context.FindExistingNode(XN_NODE_TYPE_DEPTH, depthGenerator);
context.FindExistingNode(XN_NODE_TYPE_IMAGE, imageGenerator);
}
// アイドル時のコールバック
void idle(){
//再描画要求
glutPostRedisplay();
}
//ウィンドウのサイズ変更
void reshape (int width, int height){
FormWidth = width;
FormHeight = height;
glViewport (0, 0, (GLsizei)width, (GLsizei)height);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
//射影変換行列の指定
gluPerspective (glFovy, (GLfloat)width / (GLfloat)height,glZNear,glZFar);
glMatrixMode (GL_MODELVIEW);
}
//マウスの動き
void motion(int x, int y){
int xDisp, yDisp;
xDisp = x - xBegin;
yDisp = y - yBegin;
switch (mButton) {
case GLUT_LEFT_BUTTON:
azimuth += (float) xDisp/2.0;
elevation -= (float) yDisp/2.0;
break;
case GLUT_MIDDLE_BUTTON:
cameraX -= (float) xDisp/40.0;
cameraY += (float) yDisp/40.0;
break;
case GLUT_RIGHT_BUTTON:
cameraDistance += (float) xDisp/40.0;
break;
}
xBegin = x;
yBegin = y;
}
//マウスの操作
void mouse(int button, int state, int x, int y){
if (state == GLUT_DOWN) {
switch(button) {
case GLUT_RIGHT_BUTTON:
case GLUT_MIDDLE_BUTTON:
case GLUT_LEFT_BUTTON:
mButton = button;
break;
}
xBegin = x;
yBegin = y;
}
}
//視点変更
void polarview(){
glTranslatef( cameraX, cameraY, cameraDistance);
glRotatef( -twist, 0.0, 0.0, 1.0);
glRotatef( -elevation, 1.0, 0.0, 0.0);
glRotatef( -azimuth, 0.0, 1.0, 0.0);
}
//メイン
int main(int argc, char *argv[]){
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(FormWidth, FormHeight);
glutCreateWindow(argv[0]);
//コールバック
glutReshapeFunc (reshape);
glutDisplayFunc(display);
glutIdleFunc(idle);
glutMouseFunc(mouse);
glutMotionFunc(motion);
init();
glutMainLoop();
context.Shutdown();
return 0;
}
//テクスチャマップ描画
void drawTextureMaps(Mat &rgbImage,Mat &pointCloud_XYZ){
static int x,y;
static uchar *p[2];
static Point3f *point[2];
int channel = rgbImage.channels();
p[0] = rgbImage.data; //上の色
p[1] = rgbImage.data + rgbImage.step; //下の色
point[0] = (Point3f*)pointCloud_XYZ.data; //上の座標
point[1] = &((Point3f*)pointCloud_XYZ.data)[KINECT_DEPTH_WIDTH]; //下の座標
for(y = 0;y < KINECT_DEPTH_HEGIHT - 1;y++){
for(x = 0;x < KINECT_DEPTH_WIDTH - 1;x++,p[1] += channel,point[1]++,p[0] += channel,point[0]++){
//奥行きが取得できてなかったら何もしない
if(point[0]->z == 0)
continue;
//対角の奥行きが遠ければテクスチャを貼らない
if(abs(point[0]->z - (point[1] + 1)->z) > THRESHOLD || abs((point[0] + 1)->z - point[1]->z) > THRESHOLD)
continue;
//テクスチャを貼る
glBegin(GL_TRIANGLE_STRIP);
//左上
glTexCoord2f(0, 0);
glColor3ubv(p[0]);
glVertex3f(point[0]->x,point[0]->y,point[0]->z);
//左下
glTexCoord2f(1, 0);
glColor3ubv(p[1]);
glVertex3f(point[1]->x,point[1]->y,point[1]->z);
//右上
glTexCoord2f(0, 1);
glColor3ubv(p[0]+channel);
glVertex3f((point[0] + 1)->x,(point[0] + 1)->y,(point[0] + 1)->z);
//右下
glTexCoord2f(1, 1);
glColor3ubv(p[1]+channel);
glVertex3f((point[1] + 1)->x,(point[1] + 1)->y,(point[1] + 1)->z);
glEnd();
}
p[0] += channel,point[0]++;
p[1] += channel,point[1]++;
}
}
//3次元ポイントクラウドのための座標変換
void retrievePointCloudMap(Mat &depth,Mat &pointCloud_XYZ){
static const int size = KINECT_DEPTH_HEGIHT * KINECT_DEPTH_WIDTH;
static XnPoint3D proj[size] = {0};
static int x,y;
XnPoint3D *p = proj;
unsigned short* dp = (unsigned short*)depth.data;
for(y = 0; y < KINECT_DEPTH_HEGIHT; y++ ){
for(x = 0; x < KINECT_DEPTH_WIDTH; x++, p++, dp++){
p->X = x;
p->Y = y;
p->Z = *dp * 0.001f; // from mm to meters
}
}
//現実座標に変換
depthGenerator.ConvertProjectiveToRealWorld(size, proj, (XnPoint3D*)pointCloud_XYZ.data);
} </pre>
<br />
<a href="https://github.com/kassy708/OpenNI-Sample/zipball/master">サンプルダウンロード</a><br />
<br />
<a href="https://github.com/kassy708/OpenNI-Sample/blob/master/TextureMap/main.cpp" target="_blank">github</a>kassy708http://www.blogger.com/profile/00025482097446561673noreply@blogger.com4tag:blogger.com,1999:blog-171901102439270531.post-87883652733734662872011-10-04T19:00:00.002+09:002011-10-04T19:00:58.336+09:00新作ゲーム投稿<a href="http://9leap.net/games/713">CAB - 法則性パズル【就活対策!】</a><br />
<br />
<script src="http://9leap.net/games/713/embed.js" type="text/javascript">
</script>
<br />
新作ゲーム投稿しました<br />
<br />
IT業界へ就職活動するときによく出会う問題ですね。<br />
<br />
今回は<a href="http://wise9.jp/archives/4657">9days Challenge「パズルゲームチャレンジ」</a>に参加<br />
<br />
今回の商品は<strong>「Sony Tablet」</strong>だそうで。<br />
<br />
かなりほしぃ<br />
<br />
<br />
もうすぐ応用情報技術者試験受けるので、あまり時間をかけれませんでした。<br />
<br />
<br />
<br />
そろそろ勉強しないとやばいので、今日から本気だす。 kassy708http://www.blogger.com/profile/00025482097446561673noreply@blogger.com0tag:blogger.com,1999:blog-171901102439270531.post-30599465985221062652011-09-30T11:37:00.002+09:002011-09-30T11:38:01.293+09:009leap優秀賞受賞<a href="http://9leap.net/games/482">かけらあつめ</a>が9leap優秀賞を受賞しました。<br />
<br />
4Gamer.net <br />
<a href="http://www.4gamer.net/games/000/G000000/20110928071/">スマートフォン向けオリジナルゲームコンテスト“9leap”の前期審査会で優秀作品が決定</a><br />
<br />
ファミ通App<br />
<a href="http://www.famitsu.com/news/201109/29051129.html">【ゲーム付き】オリジナルゲーム開発コンテスト“9leap”前期審査会が開催 未来のクリエイターが作ったゲームはコレだ!</a><br />
<br />
<br />
<script src="http://9leap.net/games/482/embed.js" type="text/javascript">
</script>
<br />
9leapとは<br />
<blockquote>
“9leap”とは、プログラマを目指す学生からJavaSprictベースのスマホ向けゲームを募集するコンテストで、期間は2011年5月~12月
と長期間に渡って行われている。審査は2011年5月~8月までの前期、9月1日から12月31日までの後期に分けられていて、それぞれの期間で優秀作品
を発表。受賞作品の開発者には、賞品として最新モデルのMacBook ProまたはMacBook Airが贈呈される。
<br />
<br />
前期後期を通じてもっとも高い評価を得た3作品に最優秀賞が贈られ、受賞作品開発者3名は2012年3月5日から9日にかけて開催予定の世界最大のゲー
ム開発者会議“Game Developers
Conference”の視察旅行に無料で参加できるほか、IGDA日本の主催するイベントに登壇できる権利も得ることができる内容だ。</blockquote>
ファミ通Appより<br />
<br />
<br />
やったああああああああああああああああああああああああああ!!!<br />
<br />
<br />
それほどプレイ数稼げてるわけでもないので諦めてましたけど受賞できました。<br />
<br />
<br />
審査員の方のコメント<br />
<blockquote>
「万人に受け入れられそうで、加速度センサーを使った操作も簡単。かつ、グラフィックの美しさを評価しました」(宝珠山氏)</blockquote>
ということでした。<br />
<br />
グラフィックに力入れたので評価されてうれしいです。<br />
<br />
<br />
そしてMacがもらえる!!!<br />
<br />
すでに持ってるけど!!!<br />
<br />
<br />
むう、どうしよう。<br />
<br />
Windows機に変えてもらってもいいけど、どうせならMBAのほうがいいなぁ<br />
<br />
iPadとandroidタブレット・・・は欲張りすぎか<br />
<br />
<br />
まあ、MBAもらって母親にあげようかな<br />
<br />
最近iPad2買ったけどPCが古すぎて同期せずに使ってるんだよな。<br />
<br />
もうすぐ誕生日だし。<br />
<br />
<br />
<br />
よし、後期もはりきってこー!kassy708http://www.blogger.com/profile/00025482097446561673noreply@blogger.com0tag:blogger.com,1999:blog-171901102439270531.post-74513644996027195652011-09-29T11:10:00.000+09:002012-02-05T00:36:20.580+09:00Kinect OpenNIによる3次元ポイントクラウド - 3次元描画 高速化前回の「<a href="http://kassymemo.blogspot.com/2011/09/kinect-openni3-3_27.html">Kinect OpenNIによる3次元ポイントクラウド - 3次元描画</a>」でOpenGLによる3次元ポイントクラウドの方法を紹介しました。<br />
<br />
しかし、cv::Matのアクセス方法によりちょっと速度が遅くなっているので、高速化を図りたいと思います。<br />
<br />
cv::Matのアクセスで最も早いのはポインタへのアクセスです。<br />
<br />
なので画素のアクセスはすべてポインタアクセスで行うことにします。<br />
<br />
<br />
<pre class="prettyprint">
//ポイントクラウド描画
void drawPointCloud(Mat &rgbImage,Mat &pointCloud_XYZ){
static int x,y;
glPointSize(2);
glBegin(GL_POINTS);
uchar *p = rgbImage.data;
Point3f *point = (Point3f*)pointCloud_XYZ.data;
for(y = 0;y < 480;y++){
for(x = 0;x < 640;x++,p += 3,point++){
if(point->z == 0)
continue;
glColor3ubv(p);
glVertex3f(point->x,point->y,point->z);
}
}
glEnd();
}
</pre>
<pre class="prettyprint">
//3次元ポイントクラウドのための座標変換
void retrievePointCloudMap(Mat &depth,Mat &pointCloud_XYZ){
static const int size = 480 * 640;
static XnPoint3D proj[size] = {0};
static int x,y;
XnPoint3D *p = proj;
unsigned short* dp = (unsigned short*)depth.data;
for(y = 0; y < 480; y++ ){
for(x = 0; x < 640; x++, p++, dp++){
p->X = x;
p->Y = y;
p->Z = *dp * 0.001f; // from mm to meters
}
}
//現実座標に変換
depthGenerator.ConvertProjectiveToRealWorld(size, proj, (XnPoint3D*)pointCloud_XYZ.data);
}
</pre>
<br />
今まで画素のアクセスに<br />
Point3f &point = ((Point3f*)(pointCloud_XYZ.data + pointCloud_XYZ.step.p[0]*y))[x];<br />
やら<br />
SEQ = y * step + x * channel;<br />
rgbImage.data[SEQ + 0]<br />
やらしていたので、 計算コストがかかってました<br />
<br />
ということで、どうせ画素の配列は1次元配列で並んでるのならポインタをスライドさせていこうということです。<br />
<br />
<br />
ポインタに慣れていない人にはわかりづらいかもしれませんが、慣れている人なら逆にこっちのほうがわかりやすいでしょう。<br />
<br />
簡単に説明すると<br />
uchar *p = rgbImage.data;<br />
Point3f *point = (Point3f*)pointCloud_XYZ.data;<br />
でRGBデータと3次元位置データの先頭アドレスを格納します。<br />
<br />
for(x = 0;x < 640;x++,p += 3,point++){ }<br />
のp += 3,point++でポインタをとなりのデータの場所に移動してるわけです<br />
<br />
<br />
ということでサンプルどん <br />
<br />
<pre class="prettyprint">#include <GL/glut.h>
#include <opencv2/opencv.hpp>
#ifdef _DEBUG
//Debugモードの場合
#pragma comment(lib,"C:\\OpenCV2.2\\lib\\opencv_core220d.lib") // opencv_core
#pragma comment(lib,"C:\\OpenCV2.2\\lib\\opencv_imgproc220d.lib") // opencv_imgproc
#pragma comment(lib,"C:\\OpenCV2.2\\lib\\opencv_highgui220d.lib") // opencv_highgui
#else
//Releaseモードの場合
#pragma comment(lib,"C:\\OpenCV2.2\\lib\\opencv_core220.lib") // opencv_core
#pragma comment(lib,"C:\\OpenCV2.2\\lib\\opencv_imgproc220.lib") // opencv_imgproc
#pragma comment(lib,"C:\\OpenCV2.2\\lib\\opencv_highgui220.lib") // opencv_highgui
#endif
#include <XnCppWrapper.h>
#pragma comment(lib,"C:/Program files/OpenNI/Lib/openNI.lib")
#define SAMPLE_XML_PATH "C:/Program Files/OpenNI/Data/SamplesConfig.xml"
using namespace cv;
using namespace xn;
//openNIのための宣言・定義
//マクロ定義
#define KINECT_IMAGE_WIDTH 640
#define KINECT_IMAGE_HEGIHT 480
#define KINECT_DEPTH_WIDTH 640
#define KINECT_DEPTH_HEGIHT 480
DepthGenerator depthGenerator;// depth context
ImageGenerator imageGenerator;//image context
DepthMetaData depthMD;
ImageMetaData imageMD;
Context context;
Mat image(480,640,CV_8UC3);
Mat depth(480,640,CV_16UC1);
//ポイントクラウドの座標
Mat pointCloud_XYZ(480,640,CV_32FC3,cv::Scalar::all(0));
void retrievePointCloudMap(Mat &depth,Mat &pointCloud_XYZ); //3次元ポイントクラウドのための座標変換
void drawPointCloud(Mat &rgbImage,Mat &pointCloud_XYZ); //ポイントクラウド描画
//openGLのための宣言・定義
//---変数宣言---
int FormWidth = 640;
int FormHeight = 480;
int mButton;
float twist, elevation, azimuth;
float cameraDistance = 0,cameraX = 0,cameraY = 0;
int xBegin, yBegin;
//---マクロ定義---
#define glFovy 45 //視角度
#define glZNear 1.0 //near面の距離
#define glZFar 150.0 //far面の距離
void polarview(); //視点変更
//描画
void display(){
// clear screen and depth buffer
glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
// Reset the coordinate system before modifying
glLoadIdentity();
glEnable(GL_DEPTH_TEST); //「Zバッファ」を有効
gluLookAt(0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0); //視点の向き設定
//wait and error processing
context.WaitAnyUpdateAll();
imageGenerator.GetMetaData(imageMD);
depthGenerator.GetMetaData(depthMD);
depthGenerator.GetAlternativeViewPointCap().SetViewPoint(imageGenerator);//ズレを補正
memcpy(image.data,imageMD.Data(),image.step * image.rows); //イメージデータを格納
memcpy(depth.data,depthMD.Data(),depth.step * depth.rows); //深度データを格納
//3次元ポイントクラウドのための座標変換
retrievePointCloudMap(depth,pointCloud_XYZ);
//視点の変更
polarview();
//ポイントクラウド
drawPointCloud(image,pointCloud_XYZ);
//convert color space RGB2BGR
cvtColor(image,image,CV_RGB2BGR);
imshow("image",image);
imshow("depth",depth);
glFlush();
glutSwapBuffers();
}
//初期化
void init(){
context.InitFromXmlFile(SAMPLE_XML_PATH);
context.FindExistingNode(XN_NODE_TYPE_DEPTH, depthGenerator);
context.FindExistingNode(XN_NODE_TYPE_IMAGE, imageGenerator);
}
// アイドル時のコールバック
void idle(){
//再描画要求
glutPostRedisplay();
}
//ウィンドウのサイズ変更
void reshape (int width, int height){
FormWidth = width;
FormHeight = height;
glViewport (0, 0, (GLsizei)width, (GLsizei)height);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
//射影変換行列の指定
gluPerspective (glFovy, (GLfloat)width / (GLfloat)height,glZNear,glZFar);
glMatrixMode (GL_MODELVIEW);
}
//マウスの動き
void motion(int x, int y){
int xDisp, yDisp;
xDisp = x - xBegin;
yDisp = y - yBegin;
switch (mButton) {
case GLUT_LEFT_BUTTON:
azimuth += (float) xDisp/2.0;
elevation -= (float) yDisp/2.0;
break;
case GLUT_MIDDLE_BUTTON:
cameraX -= (float) xDisp/40.0;
cameraY += (float) yDisp/40.0;
break;
case GLUT_RIGHT_BUTTON:
cameraDistance += (float) xDisp/40.0;
break;
}
xBegin = x;
yBegin = y;
}
//マウスの操作
void mouse(int button, int state, int x, int y){
if (state == GLUT_DOWN) {
switch(button) {
case GLUT_RIGHT_BUTTON:
case GLUT_MIDDLE_BUTTON:
case GLUT_LEFT_BUTTON:
mButton = button;
break;
}
xBegin = x;
yBegin = y;
}
}
//視点変更
void polarview(){
glTranslatef( cameraX, cameraY, cameraDistance);
glRotatef( -twist, 0.0, 0.0, 1.0);
glRotatef( -elevation, 1.0, 0.0, 0.0);
glRotatef( -azimuth, 0.0, 1.0, 0.0);
}
//メイン
int main(int argc, char *argv[]){
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(FormWidth, FormHeight);
glutCreateWindow(argv[0]);
//コールバック
glutReshapeFunc (reshape);
glutDisplayFunc(display);
glutIdleFunc(idle);
glutMouseFunc(mouse);
glutMotionFunc(motion);
init();
glutMainLoop();
context.Shutdown();
return 0;
}
//ポイントクラウド描画
void drawPointCloud(Mat &rgbImage,Mat &pointCloud_XYZ){
static int x,y;
glPointSize(2);
glBegin(GL_POINTS);
uchar *p = rgbImage.data;
Point3f *point = (Point3f*)pointCloud_XYZ.data;
for(y = 0;y < KINECT_DEPTH_HEGIHT;y++){
for(x = 0;x < KINECT_DEPTH_WIDTH;x++,p += 3,point++){
if(point->z == 0)
continue;
glColor3ubv(p);
glVertex3f(point->x,point->y,point->z);
}
}
glEnd();
}
//3次元ポイントクラウドのための座標変換
void retrievePointCloudMap(Mat &depth,Mat &pointCloud_XYZ){
static const int size = KINECT_DEPTH_HEGIHT * KINECT_DEPTH_WIDTH;
static XnPoint3D proj[size] = {0};
static int x,y;
XnPoint3D *p = proj;
unsigned short* dp = (unsigned short*)depth.data;
for(y = 0; y < KINECT_DEPTH_HEGIHT; y++ ){
for(x = 0; x < KINECT_DEPTH_WIDTH; x++, p++, dp++){
p->X = x;
p->Y = y;
p->Z = *dp * 0.001f; // from mm to meters
}
}
//現実座標に変換
depthGenerator.ConvertProjectiveToRealWorld(size, proj, (XnPoint3D*)pointCloud_XYZ.data);
}
</pre>
<br />
<a href="https://github.com/kassy708/OpenNI-Sample/zipball/master">サンプルダウンロード</a><br />
<br />
<a href="https://github.com/kassy708/OpenNI-Sample/blob/master/PointCloud/main.cpp">github</a><br />
<br />
<br />
追記:テクスチャマップ<br />
<a href="http://kassymemo.blogspot.com/2011/10/kinect-openni3-3.html">Kinect OpenNIによる3次元テクスチャマップ - 3次元描画</a>kassy708http://www.blogger.com/profile/00025482097446561673noreply@blogger.com0tag:blogger.com,1999:blog-171901102439270531.post-50973373566476758202011-09-27T18:06:00.001+09:002011-10-05T21:42:55.525+09:00Kinect OpenNIによる3次元ポイントクラウド - 3次元描画前回の続き<br />
前回:<a href="http://kassymemo.blogspot.com/2011/09/kinect-openni3-3.html">Kinect OpenNIによる3次元ポイントクラウド - 3次元座標取得</a><br />
<br />
前回の話でKinectからの奥行き情報から3次元座標を取得しました。<br />
<br />
次はその3次元座標を目に見える形に描画しましょう。<br />
<br />
ここでは3D描画に<span class="st">OpenGLという</span><span class="st">グラフィックスライブラリを用います。</span><br />
<span class="st"> </span><br />
<span class="st">OpenGLの導入方法を説明しません。</span><br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='320' height='266' src='https://www.blogger.com/video.g?token=AD6v5dwca5pJWEidLwUa0dtomPvGJZcWXQzF9S0zC5nyFTHaO9vGdNdSlx-ekduGLeAUC-kfVPEf9KmDdsZvDKal9g' class='b-hbp-video b-uploaded' frameborder='0'></iframe></div>
<br />
<br />
<br />
<span class="st"><br /></span><br />
<span class="st"><br /></span><br />
<span class="st">ということでサンプルどーん</span><br />
<fieldset>
#include <GL/glut.h><br />
#include <opencv2/opencv.hpp><br />
#ifdef _DEBUG<br />
//Debugモードの場合<br />
#pragma comment(lib,"C:\\OpenCV2.2\\lib\\opencv_core220d.lib") // opencv_core<br />
#pragma comment(lib,"C:\\OpenCV2.2\\lib\\opencv_imgproc220d.lib") // opencv_imgproc<br />
#pragma comment(lib,"C:\\OpenCV2.2\\lib\\opencv_highgui220d.lib") // opencv_highgui<br />
#else<br />
//Releaseモードの場合<br />
#pragma comment(lib,"C:\\OpenCV2.2\\lib\\opencv_core220.lib") // opencv_core<br />
#pragma comment(lib,"C:\\OpenCV2.2\\lib\\opencv_imgproc220.lib") // opencv_imgproc<br />
#pragma comment(lib,"C:\\OpenCV2.2\\lib\\opencv_highgui220.lib") // opencv_highgui<br />
#endif<br />
<br />
#include <XnCppWrapper.h><br />
#pragma comment(lib,"C:/Program files/OpenNI/Lib/openNI.lib")<br />
<br />
#define SAMPLE_XML_PATH "C:/Program Files/OpenNI/Data/SamplesConfig.xml"<br />
using namespace cv;<br />
using namespace xn;<br />
<br />
//openNIのための宣言・定義<br />
//マクロ定義<br />
#define KINECT_IMAGE_WIDTH 640<br />
#define KINECT_IMAGE_HEGIHT 480 <br />
#define KINECT_DEPTH_WIDTH 640<br />
#define KINECT_DEPTH_HEGIHT 480 <br />
<br />
DepthGenerator depthGenerator;// depth context<br />
ImageGenerator imageGenerator;//image context<br />
DepthMetaData depthMD;<br />
ImageMetaData imageMD;<br />
Context context;<br />
<br />
Mat image(480,640,CV_8UC3);<br />
Mat depth(480,640,CV_16UC1); <br />
//ポイントクラウドの座標<br />
Mat pointCloud_XYZ(480,640,CV_32FC3,cv::Scalar::all(0));<br />
<br />
void retrievePointCloudMap(Mat &depth,Mat &pointCloud_XYZ); //3次元ポイントクラウドのための座標変換<br />
void drawPointCloud(Mat &rgbImage,Mat &pointCloud_XYZ); //ポイントクラウド描画<br />
<br />
//openGLのための宣言・定義<br />
//---変数宣言---<br />
int FormWidth = 640;<br />
int FormHeight = 480;<br />
int mButton;<br />
float twist, elevation, azimuth;<br />
float cameraDistance = 0,cameraX = 0,cameraY = 0;<br />
int xBegin, yBegin;<br />
//---マクロ定義---<br />
#define glFovy 45 //視角度<br />
#define glZNear 1.0 //near面の距離<br />
#define glZFar 150.0 //far面の距離<br />
void polarview(); //視点変更<br />
<br />
//描画<br />
void display(){ <br />
// clear screen and depth buffer<br />
glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); <br />
// Reset the coordinate system before modifying<br />
glLoadIdentity(); <br />
glEnable(GL_DEPTH_TEST); //「Zバッファ」を有効 <br />
gluLookAt(0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0); //視点の向き設定<br />
//wait and error processing<br />
context.WaitAnyUpdateAll();<br />
<br />
imageGenerator.GetMetaData(imageMD);<br />
depthGenerator.GetMetaData(depthMD);<br />
depthGenerator.GetAlternativeViewPointCap().SetViewPoint(imageGenerator);//ズレを補正<br />
<br />
memcpy(image.data,imageMD.Data(),image.step * image.rows); //イメージデータを格納<br />
memcpy(depth.data,depthMD.Data(),depth.step * depth.rows); //深度データを格納<br />
<br />
//3次元ポイントクラウドのための座標変換<br />
retrievePointCloudMap(depth,pointCloud_XYZ);<br />
<br />
//視点の変更<br />
polarview(); <br />
//ポイントクラウド<br />
drawPointCloud(image,pointCloud_XYZ);<br />
<br />
//convert color space RGB2BGR<br />
cvtColor(image,image,CV_RGB2BGR); <br />
<br />
imshow("image",image);<br />
imshow("depth",depth);<br />
<br />
glFlush();<br />
glutSwapBuffers();<br />
}<br />
//初期化<br />
void init(){<br />
context.InitFromXmlFile(SAMPLE_XML_PATH); <br />
context.FindExistingNode(XN_NODE_TYPE_DEPTH, depthGenerator); <br />
context.FindExistingNode(XN_NODE_TYPE_IMAGE, imageGenerator);<br />
}<br />
// アイドル時のコールバック<br />
void idle(){<br />
//再描画要求<br />
glutPostRedisplay();<br />
}<br />
//ウィンドウのサイズ変更<br />
void reshape (int width, int height){<br />
FormWidth = width;<br />
FormHeight = height;<br />
glViewport (0, 0, (GLsizei)width, (GLsizei)height);<br />
glMatrixMode (GL_PROJECTION);<br />
glLoadIdentity ();<br />
//射影変換行列の指定<br />
gluPerspective (glFovy, (GLfloat)width / (GLfloat)height,glZNear,glZFar); <br />
glMatrixMode (GL_MODELVIEW);<br />
}<br />
//マウスの動き<br />
void motion(int x, int y){<br />
int xDisp, yDisp; <br />
xDisp = x - xBegin;<br />
yDisp = y - yBegin;<br />
switch (mButton) {<br />
case GLUT_LEFT_BUTTON:<br />
azimuth += (float) xDisp/2.0;<br />
elevation -= (float) yDisp/2.0;<br />
break;<br />
case GLUT_MIDDLE_BUTTON:<br />
case GLUT_RIGHT_BUTTON:<br />
cameraX -= (float) xDisp/40.0;<br />
cameraY += (float) yDisp/40.0;<br />
break;<br />
}<br />
xBegin = x;<br />
yBegin = y;<br />
}<br />
//マウスの操作<br />
void mouse(int button, int state, int x, int y){<br />
if (state == GLUT_DOWN) {<br />
switch(button) {<br />
case GLUT_RIGHT_BUTTON:<br />
case GLUT_MIDDLE_BUTTON:<br />
case GLUT_LEFT_BUTTON:<br />
mButton = button;<br />
break;<br />
}<br />
xBegin = x;<br />
yBegin = y;<br />
}<br />
}<br />
//視点変更<br />
void polarview(){<br />
glTranslatef( cameraX, cameraY, cameraDistance);<br />
glRotatef( -twist, 0.0, 0.0, 1.0);<br />
glRotatef( -elevation, 1.0, 0.0, 0.0);<br />
glRotatef( -azimuth, 0.0, 1.0, 0.0);<br />
}<br />
//メイン<br />
int main(int argc, char *argv[]){<br />
glutInit(&argc, argv);<br />
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGB);<br />
glutInitWindowSize(FormWidth, FormHeight);<br />
glutCreateWindow(argv[0]);<br />
//コールバック<br />
glutReshapeFunc (reshape);<br />
glutDisplayFunc(display);<br />
glutIdleFunc(idle);<br />
glutMouseFunc(mouse);<br />
glutMotionFunc(motion);<br />
init();<br />
glutMainLoop();<br />
context.Shutdown();<br />
return 0;<br />
}<br />
<br />
//ポイントクラウド描画<br />
void drawPointCloud(Mat &rgbImage,Mat &pointCloud_XYZ){<br />
int SEQ = 0;//配列番号<br />
int channel = rgbImage.channels();<br />
int step = rgbImage.step;<br />
glPointSize(2); //点の大きさ<br />
glBegin(GL_POINTS); //今から点を描画しますよっと<br />
for(int y = 0;y < KINECT_DEPTH_HEGIHT;y++){<br />
for(int x = 0;x < KINECT_DEPTH_WIDTH;x++){ <br />
//Point3f &point = &pointCloud_XYZ.at<Point3f>(y,x);<br />
Point3f &point = ((Point3f*)(pointCloud_XYZ.data + pointCloud_XYZ.step.p[0]*y))[x];<br />
if(point.z == 0) //奥行きがとれてなければ描画しない<br />
continue;<br />
SEQ = y * step + x * channel;<br />
glColor3f(rgbImage.data[SEQ + 0] / 255.0f,rgbImage.data[SEQ + 1] / 255.0f,rgbImage.data[SEQ + 2] / 255.0f);<br />
glVertex3f(point.x,point.y,point.z);<br />
}<br />
}<br />
glEnd(); //描画終了<br />
}<br />
//3次元ポイントクラウドのための座標変換<br />
void retrievePointCloudMap(Mat &depth,Mat &pointCloud_XYZ){<br />
static XnPoint3D proj[KINECT_DEPTH_HEGIHT * KINECT_DEPTH_WIDTH] = {0};<br />
int SEQ = 0; //配列番号<br />
for(int y = 0; y < KINECT_DEPTH_HEGIHT; y++ ){<br />
for(int x = 0; x < KINECT_DEPTH_WIDTH; x++ ){ <br />
proj[SEQ].X = (XnFloat)x;<br />
proj[SEQ].Y = (XnFloat)y;<br />
proj[SEQ].Z = ((unsigned short*)(depth.data + depth.step.p[0]*y))[x] * 0.001f; // from mm to meters<br />
SEQ++;<br />
}<br />
}<br />
//現実座標に変換<br />
depthGenerator.ConvertProjectiveToRealWorld(KINECT_DEPTH_HEGIHT*KINECT_DEPTH_WIDTH, proj, (XnPoint3D*)pointCloud_XYZ.data);<br />
} </fieldset>
<br />
<br />
ほとんどOpenGLの設定です。<br />
<br />
ここでポイントクラウド(Point Cloud)の処理を行っているのは<br />
retrievePointCloudMap()と<br />
drawPointCloud()だけですね。<br />
<br />
<br />
OpenGLの説明をするとOpenGLの話だけになってしまいそうなので、基本的なところだけ説明します。 <br />
<br />
<br />
とりあえずdisplay()の中だけ説明。<br />
<br />
<fieldset>
void display(){ <br />
// clear screen and depth buffer<br />
glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); <br />
// Reset the coordinate system before modifying<br />
glLoadIdentity(); <br />
glEnable(GL_DEPTH_TEST); //「Zバッファ」を有効 <br />
gluLookAt(0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0); //視点の向き設定<br />
//wait and error processing<br />
context.WaitAnyUpdateAll();<br />
<br />
imageGenerator.GetMetaData(imageMD);<br />
depthGenerator.GetMetaData(depthMD);<br />
depthGenerator.GetAlternativeViewPointCap().SetViewPoint(imageGenerator);//ズレを補正<br />
<br />
memcpy(image.data,imageMD.Data(),image.step * image.rows); //イメージデータを格納<br />
memcpy(depth.data,depthMD.Data(),depth.step * depth.rows); //深度データを格納<br />
<br />
//3次元ポイントクラウドのための座標変換<br />
retrievePointCloudMap(depth,pointCloud_XYZ);<br />
<br />
//視点の変更<br />
polarview(); <br />
//ポイントクラウド<br />
drawPointCloud(image,pointCloud_XYZ);<br />
<br />
//convert color space RGB2BGR<br />
cvtColor(image,image,CV_RGB2BGR); <br />
<br />
imshow("image",image);<br />
imshow("depth",depth);<br />
<br />
glFlush();<br />
glutSwapBuffers();<br />
}</fieldset>
<br />
glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); <br />
画面を初期化して消してます<br />
<br />
glLoadIdentity(); <br />
視点を初期に戻します(まあ、簡単に言うとだけど)<br />
<br />
glEnable(GL_DEPTH_TEST);<br />
「Zバッファ」を有効にします。<br />
これにより、奥の座標にあるものは手前のものに隠れて見えなくなります。<br />
<br />
gluLookAt(0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0);<br />
視点の向きをZ方向に向けます。<br />
<br />
glFlush(); <br />
今までの処理をすべて実行する。<br />
OpenGLでは関数を呼んでも、すぐには行われずいくつか溜まってから処理を行います。<br />
なので、ここで溜まった処理を実行するわけです。<br />
<br />
glutSwapBuffers();<br />
描画を行います。<br />
この描画は<span class="st">ダブルバッファモードのときだけです。</span><br />
<span class="st">詳しくは調べてください。</span><br />
<br />
<br />
<span class="st">といった感じで描画してきます。</span><br />
<br />
<span class="st">では点を描画している </span>drawPointCloud()の説明を行います。<br />
<br />
<br />
<fieldset>
void drawPointCloud(Mat &rgbImage,Mat &pointCloud_XYZ){<br />
int SEQ = 0;//配列番号<br />
int channel = rgbImage.channels();<br />
int step = rgbImage.step;<br />
glPointSize(2); //点の大きさ<br />
<br />
glBegin(GL_POINTS); //今から点を描画しますよっと<br />
for(int y = 0;y < KINECT_DEPTH_HEGIHT;y++){<br />
for(int x = 0;x < KINECT_DEPTH_WIDTH;x++){ <br />
//Point3f &point = &pointCloud_XYZ.at<Point3f>(y,x);<br />
Point3f &point = ((Point3f*)(pointCloud_XYZ.data + pointCloud_XYZ.step.p[0]*y))[x];<br />
if(point.z == 0) //奥行きがとれてなければ描画しない<br />
continue;<br />
SEQ = y * step + x * channel;<br />
glColor3f(rgbImage.data[SEQ + 0] / 255.0f,rgbImage.data[SEQ + 1] / 255.0f,rgbImage.data[SEQ + 2] / 255.0f);<br />
glVertex3f(point.x,point.y,point.z);<br />
}<br />
}<br />
glEnd(); //描画終了<br />
}</fieldset>
<br />
<br />
drawPointCloud(Mat &rgbImage,Mat &pointCloud_XYZ)<br />
引数にRGBイメージと3次元座標を格納したMatクラスを入れます<br />
<br />
<br />
glPointSize();<br />
描画する点の大きさを設定します。<br />
<br />
glBegin(GL_POINTS);<br />
いまからglEnd()まで点を描画する処理を行いますよっということを意味する<br />
<br />
で、for文の中<br />
<br />
glColor3f();<br />
点の色をr,g,bで設定<br />
<br />
glVertex3f();<br />
引数のx,y,zに点を描画<br />
<br />
<br />
とまあ、こんな感じで3次元ポイントクラウドを表現します。<br />
<br />
サンプルプログラムはマウスで視点を変更することができます。<br />
<br />
もっといろいろしてみたい!っという人はOpenGLを勉強してください。<br />
<br />
<br />
んー、次はテクスチャマップでもしようかな?<br />
<br />
<br />
<br />
追記:高速化目指しました。<br />
<a href="http://kassymemo.blogspot.com/2011/09/kinect-openni3-3_29.html">Kinect OpenNIによる3次元ポイントクラウド - 3次元描画 高速化</a><br />
<br />
<br />
追記:テクスチャマップ<br />
<a href="http://kassymemo.blogspot.com/2011/10/kinect-openni3-3.html">Kinect OpenNIによる3次元テクスチャマップ - 3次元描画</a>
<br />
<br />
<br />
<span class="st"></span>kassy708http://www.blogger.com/profile/00025482097446561673noreply@blogger.com3tag:blogger.com,1999:blog-171901102439270531.post-7371243002286044152011-09-26T18:02:00.001+09:002011-09-27T18:15:02.385+09:00Kinect OpenNIによる3次元ポイントクラウド - 3次元座標取得<br />
<br />
<br />
<br />
Kinect Hackといえば点で部屋を3次元復元する動画が有名ですよね。<br />
<br />
<br />
誰もが最初にしてみたいと思うはず!たぶん!<br />
<br />
<br />
ということでOpenNIを使ってKinectセンサで取得した奥行き情報から3次元位置を求める方法を紹介します。<br />
<br />
これも実はOpenNIを使えば簡単にできます。<br />
<br />
<br />
<br />
この関数でできます。<br />
<b>DepthGenerator.ConvertProjectiveToRealWorld(座標数,奥行き情報の配列,現実座標の配列);</b><br />
<br />
<br />
ということでサンプルプログラム<br />
<br />
<br />
<fieldset>
#include <opencv2/opencv.hpp><br />
#ifdef _DEBUG<br />
//Debugモードの場合<br />
#pragma comment(lib,"C:\\OpenCV2.2\\lib\\opencv_core220d.lib") // opencv_core<br />
#pragma comment(lib,"C:\\OpenCV2.2\\lib\\opencv_imgproc220d.lib") // opencv_imgproc<br />
#pragma comment(lib,"C:\\OpenCV2.2\\lib\\opencv_highgui220d.lib") // opencv_highgui<br />
#pragma comment(lib,"C:\\OpenCV2.2\\lib\\opencv_objdetect220d.lib") // opencv_objdetect<br />
#else<br />
//Releaseモードの場合<br />
#pragma comment(lib,"C:\\OpenCV2.2\\lib\\opencv_core220.lib") // opencv_core<br />
#pragma comment(lib,"C:\\OpenCV2.2\\lib\\opencv_imgproc220.lib") // opencv_imgproc<br />
#pragma comment(lib,"C:\\OpenCV2.2\\lib\\opencv_highgui220.lib") // opencv_highgui<br />
#pragma comment(lib,"C:\\OpenCV2.2\\lib\\opencv_objdetect220.lib") // opencv_objdetect<br />
#endif<br />
<br />
#include <XnCppWrapper.h><br />
#pragma comment(lib,"C:/Program files/OpenNI/Lib/openNI.lib")<br />
<br />
#define SAMPLE_XML_PATH "C:/Program Files/OpenNI/Data/SamplesConfig.xml"<br />
using namespace cv;<br />
using namespace xn;<br />
<br />
//マクロ定義<br />
#define KINECT_IMAGE_WIDTH 640<br />
#define KINECT_IMAGE_HEGIHT 480 <br />
#define KINECT_DEPTH_WIDTH 640<br />
#define KINECT_DEPTH_HEGIHT 480 <br />
<br />
DepthGenerator depthGenerator;// depth context<br />
ImageGenerator imageGenerator;//image context<br />
DepthMetaData depthMD;<br />
ImageMetaData imageMD;<br />
<br />
void retrievePointCloudMap(Mat &depth,Mat &pointCloud_XYZ);<br />
<br />
int main()<br />
{<br />
Context context;<br />
EnumerationErrors errors;<br />
<br />
context.InitFromXmlFile(SAMPLE_XML_PATH); <br />
context.FindExistingNode(XN_NODE_TYPE_DEPTH, depthGenerator); <br />
context.FindExistingNode(XN_NODE_TYPE_IMAGE, imageGenerator);<br />
<br />
Mat image(480,640,CV_8UC3);<br />
Mat depth(480,640,CV_16UC1); <br />
//ポイントクラウドの座標<br />
Mat pointCloud_XYZ(480,640,CV_32FC3,cv::Scalar::all(0));<br />
<br />
int key = 0;<br />
bool isWarp=false;<br />
while (key!='q')<br />
{<br />
//wait and error processing<br />
context.WaitAnyUpdateAll();<br />
<br />
imageGenerator.GetMetaData(imageMD);<br />
depthGenerator.GetMetaData(depthMD);<br />
depthGenerator.GetAlternativeViewPointCap().SetViewPoint(imageGenerator);//ズレを補正<br />
<br />
memcpy(image.data,imageMD.Data(),image.step * image.rows); //イメージデータを格納<br />
memcpy(depth.data,depthMD.Data(),depth.step * depth.rows); //深度データを格納<br />
<br />
//3次元ポイントクラウドのための座標変換<br />
retrievePointCloudMap(depth,pointCloud_XYZ);<br />
<br />
//convert color space RGB2BGR<br />
cvtColor(image,image,CV_RGB2BGR); <br />
<br />
imshow("image",image);<br />
imshow("depth",depth);<br />
key = waitKey(33);<br />
}<br />
context.Shutdown();<br />
return 0;<br />
}<br />
//3次元ポイントクラウドのための座標変換<br />
void retrievePointCloudMap(Mat &depth,Mat &pointCloud_XYZ){<br />
static XnPoint3D proj[KINECT_DEPTH_HEGIHT * KINECT_DEPTH_WIDTH] = {0};<br />
int SEQ = 0; //配列番号<br />
for(int y = 0; y < KINECT_DEPTH_HEGIHT; y++ ){<br />
for(int x = 0; x < KINECT_DEPTH_WIDTH; x++ ){ <br />
proj[SEQ].X = (XnFloat)x;<br />
proj[SEQ].Y = (XnFloat)y;<br />
proj[SEQ].Z = ((unsigned short*)(depth.data + depth.step.p[0]*y))[x] * 0.001f; // from mm to meters<br />
SEQ++;<br />
}<br />
}<br />
//現実座標に変換 depthGenerator.ConvertProjectiveToRealWorld(KINECT_DEPTH_HEGIHT*KINECT_DEPTH_WIDTH, proj, (XnPoint3D*)pointCloud_XYZ.data);<br />
} </fieldset>
<br />
今回<br />
<b>void retrievePointCloudMap(Mat &depth,Mat &pointCloud_XYZ);</b><br />
<br />
という関数を作りました。<br />
<br />
これは引数に、深度画像と変換した現実座標を格納するMatクラスを渡しています。<br />
<br />
現実座標を格納するMatクラスは<br />
<b>Mat pointCloud_XYZ(480,640,CV_32FC3,cv::Scalar::all(0));</b><br />
<br />
と宣言しています。 <br />
<br />
CV_32FC3で<span class="st">32 ビット 3チャンネル(x,y,z float型)を意味します。</span><br />
<br />
<br />
<span class="st">なので、このプログラムでは深度データ取得後</span><br />
<br />
retrievePointCloudMap(depth,pointCloud_XYZ);<br />
<span class="st"> を呼ぶことにより。</span><br />
<br />
<span class="st">depthからの情報で</span>pointCloud_XYZに変換された3次元座標の情報を格納することができます。<br />
<br />
<br />
<br />
3次元座標にアクセスするには<a href="http://kassymemo.blogspot.com/2011/09/opencv2cvmat.html">OpenCV2のcv::Matから画素を取り出す</a>で紹介した方法で取り出します。<br />
<br />
<br />
<fieldset>
for(int y = 0 ; y < pointCloud_XYZ.rows; y++){<br />
for(int x = 0 ; x < pointCloud_XYZ.cols; x++){<br />
Point3f &point = pointCloud_XYZ.at<Point3f>(y,x);<br />
printf("%f %f %f\n",point.x,point.y,point.z); //座標を表示<br />
}<br />
}</fieldset>
<br />
または<br />
<fieldset>
for(int y = 0 ; y < pointCloud_XYZ.rows; y++){<br />
for(int x = 0 ; x < pointCloud_XYZ.cols; x++){<br />
Point3f &point = ((Point3f*)(data + step.p[0]*y))[x];<br />
printf("%f %f %f\n",point.x,point.y,point.z); //座標を表示<br />
}<br />
}</fieldset>
<br />
<br />
<br />
次回は取り出した3次元位置座標をOpenGLで3D描画する方法を紹介しようかと思います。<br />
<br />
ポイントクラウドというやつですね。<br />
次回:<a href="http://kassymemo.blogspot.com/2011/09/kinect-openni3-3_27.html">Kinect OpenNIによる3次元ポイントクラウド - 3次元描画 </a>kassy708http://www.blogger.com/profile/00025482097446561673noreply@blogger.com0