タグ「programming」が付けられているエントリー

SCIS2010ナイトセッション

| | コメント(0) | トラックバック(0) SCIS2010ナイトセッション
scis2010.png

SCISは宮崎からの参加で,今年は3年目になります.CSS×2.0デビューはしていますが,SCISナイトセッションにはデビューしていませんでした.今回,ひょうんなことから「理論と実装のギャップ(仮)」というタイトルで発表の機会を与えられましたので,全力で挑んできました.

SCIS2010ナイトセッション「理論と実装のギャップ(仮)」

発表資料は公開します.ナイトセッションで使わなかったスライドには右上に赤丸が表示されています.基本的には変更していませんが,一部を修正しています.なお,プログラムソースが見えると思いますが,見ないで下さい.

ナイトセッションでは研究速報枠を3分ほどいただきました.どの辺が研究速報なのかは不明ですが・・・.真面目な内容にもかかわらず,やや受けをいただいて,嬉しい限りです.みんなやさしい!

なお,この発表の様子はyoutubeで公開されています.別ソースもあるのですが,公開していいのかどうか・・・.

関連:
素因数分解twitterボットfactoring_botを作りました - 4403 is written
SCIS2009ナイトセッションの資料 - 4403 is written
CSS×2.0 in CSS2008 - 4403 is written
CSS×2.0 in CSS2009 - 4403 is written

まだ夏の自由研究が終わっていない気がしますが,冬の自由研究を決めました.冬はGoogle Chromeの拡張機能を書いてみようかと思っています.HTMLとJavaScriptで書けるらしいので,まぁなんとかなるかなって.JSが心配だけど.これが上手くいった暁にはお蔵入りしているid:d:kakku22との共著論文を再投稿したいと思う.っていつの話やねん!って言われかねないw.

関連:
「HTMLとJavaScriptで作れます」、グーグルが「Chrome拡張」を解説 - ニュース:ITpro
GoogleChromeの拡張を作る上でFirefoxアドオン作者が知っておくべき10の違い【GoogleChromeでニコ動拡張を作ってみた感想】 - love_firefoxportableの日記
青図~夏の自由研究 - 4403 is written
夏の自由研究が頓挫しそうな件について - 4403 is written
夏の自由研究をまだやっている件 - 4403 is written
CSS×2.0 in CSS2009 - 4403 is written

たぶん,まだ誰も書いていなさそうだから,勢いで書いてみる.今日公開になったような気がするGoogleの新しいプログラミング言語であるGoをUbuntu9.04(x86_64)で動かしてみる.てか,最初は失敗したんだ.なのに,ここの説明通りにやったら成功したんだ.何も違わないのに・・・.なので,手順はそのままです.

$ cd ~
$ mkdir bin
$ export GOROOT=$HOME/go
$ export GOOS=linux
$ export GOARCH=amd64
$ export PATH=$PATH:$HOME/bin
$ source .bashrc
$ sudo apt-get install python-setuptools
$ sudo easy_install mercurial
$ hg clone -r release https://go.googlecode.com/hg/ $GOROOT
$ sudo apt-get install bison gcc libc6-dev ed
$ cd $GOROOT/src
$ ./all.bash
$ cat >hello.go <<EOF
package main
import "fmt"
func main() {
  fmt.Printf("Hello, Go!\n")
}
EOF
$ 6g hello.go
$ 6l hello.6
$ ./6.out
Hello, Go!
$

動いた.そんだけ.

関連:
The Go Programming Language
新プログラミング言語「Go」をCentOSにインストールしてみた « zaru blog

初めてjQueryを使った(やや嘘を含む)のだが,包み隠さず正直にその感想を述べるならば,「超便利」の一言に尽きると思う.JavaScriptでの実装をしたことがないわけではなく,普通のJSとPrototype.jsを少々.本格的にJSで何かを書いたことはないです.そんなボクが,やめればいいのに,クライアントサイドだけでグリグリ動くアプリを作ることに.一応,ほかの言語も検討しました.C言語とPHP.どっちも向かなさそうだったので,JSに頼った次第です.

JSを選んだのには理由があって,Twitterでもつぶやいた(誰も反応しなかったけど)んですが,Pubsubhubbubデモみたいなのを作りたかったんです.

http://www.youtube.com/watch?v=ewQBgbysSOQ&fmt=18#t=2m45s 大まじめなつぶやき.pubsubhubbubのデモvideoにある追加されたのがリアルタイムに更新されていく見せ方はどのように実装するんですか??

Twitter / 4403: http://bit.ly/AAYTg 大まじめなつ ...

で.いろいろと調べた結果,jQueryでできるらしかったのです.それがshow()とhide()なんです.そんなわけで,jQueryでプログラムを書いてみたんですが,テラ便利.何が便利かって,充実のプラグイン.かゆいところまで手が届きすぎます.車輪の再発明は不要なので,ライブラリをグリグリ使わせていただいて,自分が手を加える箇所は最小限に.怠けているんじゃないよ?コードの信頼性を上げているんだよ.オレの書くコードなんて信用ならないもんね.それから「そんなことまでできるの!?」と驚きを隠せないのが,jQuery UI.カラーピッカーやスライダーが秒殺実装可能です.

あとは,なんといっても,Ajaxも簡単にできます.AjaxはJSの醍醐味ですね(ちがう?).当初はサーバサイドにもスクリプト(PHPでやるつもりだった)をおいて,JSONでAjaxな感じを思い描いていたわけですが,想定外にjQueryが強力で,クライアントサイドだけで事足りました.すごいぞ!jQuery!デレデレです.

まとめ:
jQueryラブ. 

関連:
jQuery: The Write Less, Do More, JavaScript Library
Plugins | jQuery Plugins
jQuery UI - Home
jQuery 1.3.2 日本語リファレンス
jQuery入門 – ポンクソフト
jQuery 開発者向けメモ

前回,頓挫しそうだったのでぼやいたら,アドバイスをいただいたので,それに従って追試をしてみた.

まず,そもそもQRコードは読めるのか論だが,qr.quel.jpqr-coder.comの両方で作成したものをそのままlibdecodeqrにかけてみたところ,問題なく読み込めた.素材として,使える.

090924_qrcode01.png

続いて,これを印刷して,ARToolKitベースのあれで読み取って,射影変換したQRコードをlibdecodeqrに食わせてみた.結果からいえば,失敗.が.理由は単純で,QRコードの周りに適切な余白をつけることで,デコードできました.

090924_qrcode02.png

おおむね良好.

ということで,今後プログラムに起こす(連続かつ自動で流れるように)べきこと.

  1. QRコードの四隅の座標を取得する
  2. ネガポジ反転する(てか二値化を反転させておけばいい?)
  3. 射影変換する
  4. 周りに余白をつける
  5. libdecodeqrにデコードさせる

うん.だいたいの道筋はできたし,できそうな気配を感じ取った.射影変換に苦労しなくて良かったのは,画像処理屋でない視点からして嬉しい.

夏の自由研究の話なんですが,結構やばいです.図で説明します.

090918_qr01.jpg

こはカメラから取り込んで,二値化処理をしたQRコードと思われる部分です.うまくとれます.これはok.

090918_qr02.jpg

これは二値化して切り取ったQRコード(傾いている)を射影変換したもの.コードはOpenCVです.うまくいってます.これもok.後は,これをQRコードとしてデコードすればよろしい.

090918_qr03.jpg

これがいただけない.射影変換したQRコードをネガポジ反転して,QRコードデコーダであるlibdecodeqrに放り込んだ様子.ステータスコード2009(16進数だよ!)はエラーコードによりますと,以下の通りです.

  • QR_IMAGEREADER_DECODED 0x2000
  • QR_CODEDATA_NOT_SUPPORT_ECI 0x0001
  • QR_CODEDATA_UNRECOVERABLE 0x0008

重傷じゃん!どうすっかなー?こんなにきれいに復元できても,サポート外とか・・・.んなバカなって話ですよ.特定のQRコードしか読めないのかしら??それとも,このQRコードが亜種なのか.QRコードデコーダを自力で書かなくてはならないのだろうか・・・.ボスケテ!

200909200947追記:
nitechの先生からコメント頂きました.P906iでデコードできないそうです.iPhone 3GSの場合,QRコードが悪いのかリーダが悪いのか特定できないくらいに性能が悪いので,旧ケータイのW53CAを使ってみた.結果としては「24」とデコードできました.うーん.これはこれで困る結果だ.どうしよう・・・.

090812_overview01.png

やろうとしていることは,上図のような感じです.QRコードをデコードした後はどうするのかという話は,また別.初音ミクでも表示させておけば良いんじゃないかと思っている.おそらくは,そこから先はOpenGLの出番かと.うーん.勉強するべき技術が多いぜ.

何故こんな流れになっているかと申しますと.最初はlibdecodeqr付属のwebcamサンプルを拡張していたんですが,いかんせん歪みに弱く,QRコードをかなり大きめに撮影する必要がありました.これは複数のQRコードを同時に読ませようとする目的からして,かなり厳しいです.なので,OpenCVで画像処理してやればいいんじゃね?という発想からきています.射影変換等で多少変になっても,RS符号によって誤り訂正しまくってくれることを期待しています.そうすると,今度はOpenCVに処理させるべきQRコードと思われる部分をどのようにして切り出すかという話になるので,それはARToolKitに押しつけた形です.要するには,自力でコードを書く量は最小限にして,既存技術を最大限に活かそうという考えです.目的の本質じゃないところで苦労したくないんです.

というわけで,こんな感じの流れで実装していますが,「はっ?ばかじゃねーの?そんなの××で一発じゃん?」とか「○○を使ってARToolKitで直接QRの領域切り出せよ」とか「△△なら傾いたQRコードでもデコードするし,みたいな?」なんていうご意見や情報等がありましたら,どしどしとお寄せいただきたいと思います.特に,AR業界や画像処理業界の方々からのご意見をお待ちしております.異分野コラボレーションだ!(いや,マジでなにかご意見下さいorz)

090812_ar01.jpg

今日の成果.あとは,選択された領域を切り取って,射影変換して,libdecodeqrに投げてみる.上手くいけば,上手くいくはず.ただ,残念なことに,QRコード同士が近すぎて誤認識が多いです.領域が正方形に近いかどうかというチェックも必要かしら?実際はこんなに詰まった状態では使わないから,無視でも良いかな?

capture_11082009_012108.jpg

赤枠はイメージです.マーカパターンはhiroを使っているので,パターンをシンボルで作り直せば,もうちょっとちゃんと認識するかと.

libdecodeqrでがんばって,複数(といっても2個)のQRコードを同時に認識させることはできた.理論上は何個でも認識するはずなのだが・・・.Webカメラで読み込んでいたり,QRコードは模様が細かかったり,歪み等の補正を何もしていなかったりと,いろいろな状況が重なり合って,2個が限界の上に,全く安定しない.これは困った.

というわけで,libdecodeqrでがんばるのもどうかと思ったので,ARToolKitとOpenCVとlibdecodeqrを組み合わせる方向でがんばってみようかと思う.

で.結局のところ,基本アイディアはQRコード上の初音ミクに戻るのだが,これはlibdecodeqrを使っていないようだし,座標変換してるみたい.座標変換で平面に持ち込めば,libdecodeqrで認識できると信じている.てか,libdecodeqrは読めないQRコードパターンが多いような気がする.特に,バージョンが高くなるとダメぽ.これはカメラの性能だろうか?

なんだか,気合いの入り具合が間違った方向に向いてきた・・・.まずいまずいまずい.もっとさらっと仕上げる予定だったのに!QRコード上の初音ミクのソースが公開されていないから,こんなに苦労するんだ!(責任転嫁)

ARToolKit拡張現実感プログラミング入門

ARToolKit拡張現実感プログラミング入門
著者: 橋本 直
価格: ¥3129(税込)
出版社: アスキー・メディアワークス (2008/9/17)
ISBN-10: 4048673610
ISBN-13: 978-4048673617

工学ナビで有名な橋本氏が執筆したARToolKitの入門書.今更ですが,買ってみました.6日に注文して,8日に発送されて,10日に到着しました.いやいやまさに,入門書です.授業用の教科書にも使えるかと思います.サンプルもたくさん収録されているので,ARToolKitとはなんぞや?というレベルの方に最適です.中身はそれほどに難しくありませんが,行列がでてくるので,その辺の計算や表記法が分かっていないと,その部分を理解するのは難しいかもしれません.が,分からなくても,動かせますw.試しに動かしてみて,それから納得するのが工学ですよね?

まとめ:
入門には最適.オレには不適.もう1冊の方も買ってみようかな・・・.

調べたけど分からない.決定的なものが見当たらない.MSXMLを使うのが簡単そう.だけど,自宅では環境が足りない模様.明日,開発環境でテストしてみるコード.ちなみに,「実証コードには手間を掛けない」が持論なので,簡単にXMLをパースしちゃう言語をご紹介.「これはひどい」で有名なPHPで.

<?php
$string = <<<XML
<a>
<b>
<c>text</c>
<c>stuff</c>
</b>
<d>
<c>code</c>
</d>
</a>
XML;

$xml = new SimpleXMLElement($string);

/* <a><b><c> を探します */
$result = $xml->xpath('/a/b/c');

while(list( , $node) = each($result)) {
echo '/a/b/c: ',$node,"\n";
}

/* 相対パスでも動作します... */
$result = $xml->xpath('b/c');

while(list( , $node) = each($result)) {
echo 'b/c: ',$node,"\n";
}
?>

PHP: SimpleXMLElement::xpath - Manual

実行結果は以下の通り.

/a/b/c: text
/a/b/c: stuff
b/c: text
b/c: stuff

PHP: SimpleXMLElement::xpath - Manual

xpathもできて,かんたーん.

諸事情で,QRコードを複数認識したい衝動に駆られた.で.libdecoreqrってのが便利らしいので,試してみた.現時点までで分かったこと.

  • OpenCVが予想以上に便利だった
  • libdecodeqrで複数QRコードを認識させるには,外側からのアプローチじゃダメそうなので,中身を弄らないとダメそうなことは理解した
  • QRコードの方がイメージしやすいと思ったんだけど,
  • あきらめてARToolKitで複数マーカ認識にした方が良いだろうか
  • 実はARToolKitはあまり得意じゃないです><;
  • ニコニコ技術部のソースファイル(もしくは考え方)がみたい・・・
  • 具体的にはQRコード上のミク

おなかすいた.

学生会員の皆様には会誌6月号にマイクロソフト社の学生支援プログラムのパンフレットを同封いたします。
(これから学生会員に入会される方には入会承認通知に同封予定)
最新の製品を無償で提供するサービスですので、ぜひご活用ください。

パンフレットに自分専用の認証コードがついておりますので、お見逃しのないようご注意ください。

学生支援プログラム(Microsoft DreamSpark)

おや?情報処理学会の学生会員だと,国際学生証がなくても良いのかな?専用の問い合わせ先があるくらいだから,きっとそうなのだろうなぁ・・・.

200906181548追記:
研究室の学生に会誌が届いたので,中身を見せてもらった.

090618_dreamspark01.jpg

このような手順のようだ.この裏面(いや,表面)には認証コード(Microsoftでよく見かける5文字が5セットのやつ)が書かれていて,すぐに使えるようになっているみたいです.国際学生証が必要ないので,手軽に利用できます.

DreamSparkを提供して,1研究会登録費無料なんて,IPSJは学生に対して優しいですっ!入会はこちらから

理系トップクラスの大学院生でこの体たらくとは.CS系の学生には常識中の常識だと思うが,浮動小数点は信用ならないから,正確な演算結果が欲しいなら固定小数点でやる.以下,実証コードをC言語で.コンパイラはBCC32 5.5.1です.

#include <stdio.h>
union test {
double a;
int b[2];
} test;
void main() {
union test a;

a.a = 0.1;
printf("%lf=%x %x\n", a.a, a.b[1], a.b[0]);

a.a = 1.0;
a.a -= 0.9;
printf("%lf=%x %x\n", a.a, a.b[1], a.b[0]);

a.a = 0.09;
a.a += 0.01;
printf("%lf=%x %x\n", a.a, a.b[1], a.b[0]);
}

実行結果はこんな感じ.

C:\Temp>test
0.100000=3fb99999 9999999a
0.100000=3fb99999 99999998
0.100000=3fb99999 99999999

JK.0.1っていう数字を正確に表現できる君は,コンピュータよりも圧倒的に優れているよ.間違いなく.

関連:
Windows の更新の電卓のアクセサリ
グーグルの電卓機能が計算ミス:ニュース - CNET Japan

せっかくだからまとめ.こっちの環境は,Windows XP Pro SP3にVisual Studio 2008 Proです.

ARToolKit on Visual Studio 2008
なんというか,工学ナビ様の通りにやればいいと思うよ.このガイド通りで,トラブルフリーです.最高♪

PTAM on Visual Studio 2008 w/ Web-Camera
こっちはちょっと手こずる.手こずるっていっても,時間がかかるっていうだけで,以下の手順に従えば,できます.今回は現時点での最新ソース(v1.0-r111, Mon, 11 May 2009 16:38:02 +0100)を利用しています.基本的なガイドは以下の通り.

マーカレスAR(PTAM)のソースコードを動かしてみた(WindowsXP VisualC++) | happymeme

今回は最新ソースのREADME.txtに従って,TooN,libcvd,gvars3をCVSからとってくる.ガイド通りだと,build\vc2005となっているが,最新ソースのREADME.txtで示されているリビジョンをダウンロードすると,build\vc2008がありますので,それを使います・・・と見せかけて,slnが変になってるのか,読み込めないので,結局build\vc2005を使うのでした.どんまい!てか,gvars3だけ上手くコンパイルできない.config.hがない件については,config.h.inをリネームします.もう1つのエラーは,以下の通り.

以前のバージョンのソースを参考に、次の行を、

template static T& get(const std::string& name, const T& default_val=DefaultValue::val(), int flags=0);

次のように書き換える。

template static T& get(const std::string& name, const T& default_val=T(), int flags=0);

とりあえず、良しとする。

自己満足なBLOG

えーと.上手くいきません.上手くいかないので,gvars3.hの261行目を以下のように書き換える.

template<class T> static T& get(const std::string& name,
const T& default_val=T(), int flags=0);

実際には改行しないで下さい.準備が整ったら,PTAMをWebカメラで使えるようにいじります.もちろん,工学ナビ様の思し召しのままに.手順としては簡単に述べると以下の通り.VideoSource.hとVideoSource_Win32_EWCLIB.ccをPTAMのルートに.PTAM\Build\Win32にあるVideoSource_Win32_CMU1394.cc以外の3ファイルをPTAM直下にコピー.CameraCalibrator.vcorojの208行目とPTAM.vcprojの368行目を以下の通り書き換える.

書き換え前:RelativePath=".\VideoSource_Win32_CMU1394.cc"
書き換え後:RelativePath=".\VideoSource_Win32_EWCLIB.cc"

後は神に祈るのみ.あ.dxtrans.hの件を忘れていた.

そうですね。
ここにjiapeiさんが書かれている方法を元に編集したら若干警告はあるもののビルドできました。
SampleGrabber も使えました。
私の環境における編集内容は下記です。
//#include "dxtrans.h" ・・・ 495行目
IDxtCompositor //: public IDXEffect ・・・ 979行目
IDxtAlphaSetter //: public IDXEffect  ・・・1484行目
IDxtJpeg //: public IDXEffect ・・・1725行目
IDxtKey //: public IDXEffect ・・・2400行目

オラ検: DirectShowと戦うスレ Part 2 (990) via DirectX SDK November 2007にdxtrans.hが入っていない件について - DenpaFreak

これでコンパイルはできたが,Webカメラがないので,続きは月曜日以降に・・・.

関連:
SourceForge.net: ARToolKit
Parallel Tracking and Mapping for Small AR Workspaces (PTAM)
工学ナビの中の人の研究と周辺 ゼロからはじめるARToolKit on VisualC++ 2008 Express Edition
マーカレスAR(PTAM)のソースコードを動かしてみた(WindowsXP VisualC++) | happymeme
自己満足なBLOG
工学ナビ - BACKYARD
DirectX SDK November 2007にdxtrans.hが入っていない件について - DenpaFreak
オラ検: DirectShowと戦うスレ Part 2 (990)
マーカーレスAR技術「PTAM」をDVカメラで動作させてみる - program - 釣堀.net
PTAMをがんばってみる - 4403 is written

Linuxでやれば簡単なのに!(挨拶)

  1. おもむろに,VMware Playerをダウンロードして,インストールする.
  2. 適当なUbuntuのVMware用仮想マシンを入手する.
  3. 仮想マシンのUbuntuを起動させる.
  4. 適当に,apt-get updateやら,apt-get upgradeやらをやる.
  5. GMPを入れるために,以下のコマンドを打つ.
    $ sudo apt-get install libgmp3-dev
  6. PBC Libraryをダウンロードする.
    $ wget http://crypto.stanford.edu/pbc/files/pbc-0.4.18.tar.gz
  7. 余裕で解凍する.
    $ tar zxvf pbc-0.4.18.tar.gz
  8. ディレクトリに潜って,例のコマンドを放つ
    $ ./cofigure
    $ make
    $ sudo make install
  9. prefixを付けないと/usr/localに入れられるので,コンパイルは以下のように.
    $ gcc -o foo foo.c -I /usr/local/include/pbc -L /usr/local/lib
    -Wl,-rpath /usr/local/lib -l pbc

ね.簡単でしょ?

関連:
Visual Studio 2008でGMPを使う方法 - 4403 is written

20090428-143741-45501500.gif

Linuxでやれば簡単なのに!(挨拶)

Visual Studio 2008でGMPを使う方法を書いておく.備忘録.環境はWindows XP Pro SP3に,Visual Studio 2008 Proです.基本方針はこれを参考にしてます.手順内に出てくるリンク切れの参考サイトはこっち

  1. なにはなくとも,GMP本体をダウンロードする.2009年4月28日時点では4.3.0が最新のようだが,ビルドに必要なファイルが4.2.4を前提にしているらしいので,4.2.4をダウンロード(直リン注意!)する.なお,4.3.0に4.2.4用のビルドファイルを適用してみたが,ダメだった.どこをどう直せばいいのか,皆目見当もつかないくらいにエラーが出たので,今後の課題に.
  2. ダウンロードしたgmp-4.2.4.tar.gzを展開する.ここでは,c:\gmpとする.
  3. このサイトで提供しているgmp-4.2.4.vc9.zipをダウンロードして,解凍する.解凍したファイルをc:\gmpに上書きする.
  4. C:\gmp\build.vc9\yasm.rulesをC:\Program Files\Microsoft Visual Studio 9\VC\VCProjectDefaultsにコピーする.
  5. YASMから,適切なバイナリ(例えば,yasm-0.8.0-win32.exe)をダウンロードし,yasm.exeにリネームして,C:\Program Files\Microsoft Visual Studio 9\VC\binにコピーする.
  6. C:\gmp\build.vc9\gmp.slnを開くと,エラーが4回くらい出るので,無視します.これは,異なるプラットフォームだからだそうですが,Core2でコンパイルしたいなぁ・・・.何故かエラーになる.どうやるんだろう?OSが64ビットじゃないから?
  7. gen-bases, gen-fac_ui, gen-fib, gen-psqrの4つをビルドしまくる.
  8. dll_gmp_p4とlib_gmp_p4をビルドる.
  9. lib_gmpxxをビルドる.
  10. c:\gmp\build.vc9\dll\Win32\(Debug|Release)\にdllファイルが,c:\gmp\build.vc9\lib\Win32\(Debug|Release)\にlibファイルができます.
  11. c:\gmpにあるヘッダファイルをC:\Program Files\Microsoft Visual Studio 9\VC\includeに,ビルドされたlibファイルをC:\Program Files\Microsoft Visual Studio 9\VC\libにコピー.

これでok.続いて,GMPを用いたコードをテストします.以下のコードをコンパイルすることを考えましょう.

#include<iostream>
#include<gmpxx.h>
using namespace std;

mpz_class factorial(int val){
    mpz_class result = 1;
    for(int i=1; i<=val; i++) result *= i;
    return result;
}

int main(void){
    mpz_class result = factorial(300);
    cout << result.get_str() << endl;
    return 0;
}

Windows 環境下での GMP の利用法

結果は,こんな感じ.

090428_gmp01.png

あーさむ.ただし,何故かコンパイル時にエラーが出ることがある.その場合は,静的リンクを設定してみて下さい.

関連:
Windows 環境下での GMP の利用法
A Native GMP Port Using Microsoft Visual Studio

思うところがあって,スクレイパを書いてみた.言語は何でも良かったんだけど,何となくperlで.rubyの方が資料が豊富そうだったけど,書いたことがないので,時間がない今回は却下.RoRは便利そうだから,使ってみた方がいいような気がするけど・・・.

ちゅーわけで,WWW::MechanizeとWeb::ScraperにXPathでやりました.コメントとか無駄がいっぱいなのに,たった68行でやりたいことを実装できました.幸せー.

参考にしたサイトを以下に列挙.

タグ

あわせて読みたい