先月だったか。取り込んだ画像内に配置したポイント群の座標を数値列として取り出し、この数値列にカーブフィッティングできる電卓(CASIO の PRIZM)が話題になっていた。画像からの座標取得やカーブフィッティング計算を電卓でできちゃう時代になったんだなぁと、おじいさんのようなことを思ってしまったのはさておき、こういう計算をするなら、少なくとも 2010 年現在なら、パソコン内でやった方が、得られた結果の再利用の点からも便利だよなぁ、なんてことを考えた。

もちろん、超々高級電卓であらせられる Mathematica 様にも、このくらいの作業をする機能は当たり前に備わっているので、今日はこれを紹介したい。

Mathematica 7 のノートブックに画像を取り込む(表示する)方法はいろいろあるが、いちばん手軽なのはコピー&ペーストで貼り付けることだ。貼り付けた画像を右クリックして「座標の取得」を選ぶと、マウスカーソルの右下にカーソルの座標がリアルタイムで表示され、この状態で画像内をクリックすると、画像内にポイントが配置される。このポイントはいくつも置くことができるので、必要なだけ置いたら「編集」メニューの「コピー」を実行してから、ノートブックの余白をクリックしてペースト。すると、クリックで配置したポイントの座標列がリストとして貼り付けられる。

Mathematica で貼り付け画像から座標リストを得る。

この「クリック配置したポイントの座標列をリストにする機能」は、貼り付け画像だけでなく、 Plot 関数などで描いた二次元グラフでも使える。 グラフ内のクリックで得られる座標は、グラフの座標系に基づいたものになるのがポイント。

グラフからの「座標の取得」

上で紹介した貼り付け画像では、画像のピクセル座標を取得したわけだが、画像を Mathematica のグラフ内に配置すれば、この Plot の要領で、グラフ座標にスケールした画像内の座標を得ることができる。たとえば、最初の画像を、x: -1~3, y: -0.5~1 の範囲にスケールするには、次のようにする。

まず、貼り付けた画像の左側に pic = と書いて式を評価(Shift + Enter)して、画像を変数に収める。それから、次のような式を評価する。

g = Graphics[Raster[Reverse@ImageData[pic], {{-1, -0.5}, {3, 1}}],
  Axes -> True]

画像をグラフ座標軸の中にスケールして表示

Raster の第2引数に、画像の左下と右上の座標値を指定している。ImageData で得られる数値列は画像の最上段から順に並んでいるため、Reverse してから Raster に渡さないと、画像の上下がさかさまになってしまうことので注意が必要だ。

ここでさっきと同じ要領で「座標の取得」をすれば、Mathematica グラフの座標系(表示している軸の座標系)での座標列を得ることができる。

スケールした画像から「座標の取得」

いったん座標のリストが得られれば、カーブフィッティング自体は普通の Mathematica 操作で OK。ここでは、a Exp[-((x - c)/b)^2] + d というモデル式を使ってやってみよう。まずペーストした座標リストの前に、data = と置いて評価して、座標リストを変数に収めるところから。

data = {{-0.7651, 0.2741}, {-0.4051, 0.2741}, {-0.05676, 0.2973},
  {0.2684, 0.3437}, {0.5819, 0.425}, {0.8606, 0.5063}, {1.105,
   0.6108}, {1.383, 0.6108}, {1.627, 0.5063}, {1.813, 0.4134}, {2.022,
   0.3321}, {2.301, 0.2973}, {2.603, 0.2508}, {2.881, 0.2276}};
model = a Exp[-((x - c)/b)^2] + d;
myFit = FindFit[data, model, {a, b, c, d}, x]

めでたくフィッティング計算が完了したら、座標取り込みに使った画像と重ねて結果を表示してみる。

Show[g, Plot[model /. myFit, {x, -1, 3}], ListPlot[data]]

フィッティング結果と元のデータを重ねて描画

ManipulateLocator を使えば、マウスでポイントを配置・移動するのに合わせてフィッティングを行うようなことも可能だ。

Manipulate[myFit = FindFit[pts, model, {a, b, c, d}, x];
  Show[g, Plot[model /. myFit, {x, -1, 3},
    PlotStyle -> {Red, Thickness[0.008]}],
  ListPlot[pts, PlotStyle -> PointSize[0.015]],
    PlotLabel -> model /. myFit],
  {{pts, data}, Locator, LocatorAutoCreate -> True}]

Manipulate を使ってインタラクティブなフィッティング

こういうことしたい人、意外にいるんじゃないかと思うのだが、どうだろう?

※この記事の内容は執筆者の個人的見解で、ヒューリンクスによる公式情報ではありません。[免責事項]

トラックバック

この記事へのトラックバックURL
http://blog.hulinks.co.jp/cgi/mt/mt-tb.cgi/445
内容に対しての関連性がみられないものは削除する場合があります

コメントの投稿

Emailアドレスは表示されません。は必須項目です。
ヒューリンクス取り扱い製品の内容や購入に関するお問い合わせはヒューリンクスサイト連絡先へお願いいたします。投稿前にその他の注意事項もご覧ください。

HULINKS サイトの新着情報