kashiwa.r#1 画像解析とパターン認識における r の利用
TRANSCRIPT
画像解析とパターン認識における R の利用
くつな なつまろ
朽名 夏麿
(東京大学 大学院新領域創成科学研究科 先端生命科学専攻)
2011-11-11 Kashiwa.R#1
生物画像解析の特性 多次元 (時間,立体,波長…)
データサイズ・枚数 (n)
自動化・計算機支援に向く
・ 多様な画像と目的をカバーできる適応性・汎用性
・ 数値化による客観性,自動化による高速性
多様性(生物種,部位,観察法…)
多目的性 (何に着目するか)
研究者(人間)の柔軟性が不可欠
数・形・長さ 100 ms/枚
1024*1024 pixel/枚
12 bits/pixel
→ 4 GiBytes / 5 分
運動 濃度・電位
t, z, l
位置・局在
AI?? パターン認識?? 機械学習?? データマイニング??
「画像→画像」の例
共焦点画像 高周波数成分の抽出
(繊維等の強調処理)
二値化像
(白黒画像)
細線化像
「画像→数値」の例
短径 / 長径
短径
長径
気孔開閉の指標
気孔に対する
アクチン繊維の角度
アクチン繊維の配向の指標
気孔
q
気孔
q
気孔 この場合,
短径 / 長径=0.47 この場合,
アクチン繊維の角度=54.3° 灰色: 気孔領域
黒色: アクチン繊維
シロイヌナズナ気孔
アクチン繊維
デジタル画像は数値が並んだもの
y
(x,y) = (0, 0)
輝度 35
(3, 0)
輝度30
(3, 2)
輝度 21
x
表示を縮小
159列
159
153
153行
画像処理・画像解析のソフトウェアツールと要件
NIH Image/Scion Image/ImageJ
Photoshop
GIMP
MetaMorph
OpenCV
VTK (Mayavi, ParaView)
Amira
MATLAB, Octave
ImageMagick
CImg
Python Imaging Library (PIL)
:
R
採用されている画像や処理のモデル
拡張性
可搬性
インタラクティビティ(REPL,GUI)
フリーソフトウェア,オープンソース
ユーザの多さ,情報の多さ
開発状況
速度や記憶量.スケールするか.
ImageJ
Java .オープンソース.NIH の人が開発.生物学分野で多用される.
拡張性:
* 独自仕様のマクロ
* Java等JVM用言語でのプラグイン
* JavaプラットフォームでのAPI
可搬性・速度・スケール性:
* Java に準ずる.
画像のモデルがバイオ向き
* 画素について u8, u16, float ...
* Z軸,時間軸でのスタック化
(3次元以上の高次元画像)
以降の顕微鏡画像は全て http://ome.grc.nia.nih.gov/iicbu2008/ (IICBUデータベース) より取得.
ImageJ plugins http://rsbweb.nih.gov/ij/plugins/ (ImageJ 公式サイト内)
このサイトだけでも500個以上のプラグインが紹介されている.
Java ソースかクラスファイルか JAR 形式.
Java による ImageJ plugin
生物画像解析のニーズは多彩すぎており,
探すよりも書く方が早く済むことも多い.
Python による ImageJ plugin
ImageJ では画像から欲しい情報を
定量化するところまでは容易だが…
高次元・多量の非画像データの
扱いは不得手.
Excel にコピペしてプロットや検定…
ある程度はパッケージがあるようだ.
(試してません…)
R で画像処理の本が出る
共立出版のサイトより引用 http://www.kyoritsu-pub.co.jp/series/arudemanabu.html#11
生物画像解析における R の使いどころ
画像データの生成
(シミュレーション等)
画像の読込
画像処理
画像からの測定
データ解析
画像処理 画像処理
画像からの測定
データ解析
ImageJ から R を使うには
?
Rserve: TCP/IP を介した R の利用
R console と ImageJ を別プロセスで動かしつつ,
データのやりとりをすることができれば
便利そうなので,そのうちトライしたい.
ImageJ
(Java) R
connect
http://www.rforge.net/Rserve/
rJava: R から Java を呼出す
JRI: Java から R を呼出す
R
call ImageJ
(Java)
これを使って ImageJ と R をむすんだ
プロダクトを簡単に 2 つ紹介します.
call http://www.rforge.net/rJava/
RImageJ: R から ImageJ を呼出す
http://romainfrancois.blog.free.fr/index.php?post/2009/06/22/using-ImageJ-from-R%3A-the-RImageJ-package
R で実質6行のパッケージ.
これだけでも ImageJ マクロのサブセット
が R コンソールから使える.
インタラクティブな操作は不明.
Bio7: ImageJ と R,その他を統合
ImageJ や R の良さが一部
失なわれているように思う.
あと挙動が怪しい気が…?
導入 (ubuntuの場合) export R_HOME=/usr/lib/R export CLASSPATH=${CLASSPATH}:${R_HOME}/site-library/rJava/jri/JRI.jar export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:${R_HOME}/site-library/rJava/jri % sudo apt-get install r-cran-rjava
試用 % scala scala> val engine=new org.rosuda.JRI.Rengine(Array("--no-save"),false,null) engine: org.rosuda.JRI.Rengine = Thread[Thread-4,5,main] scala> engine.eval("sum(iris$Sepal.Length)").asDouble res0: Double = 876.5 scala> engine.eval("iris$Sepal.Length").asDoubleArray.sum res1: Double = 876.5000000000002
JRI (Java → R) を試す
これを使って ImageJ から R を使ってみることにした.
Rは別のJavaスレッドで動く
今回の plugin
JRI (Java/R)
JNI (Java/C)
R
ImageJ randomForest package
ImageJ から R を使って画像の学習と分類をする
1. 画像
2. 特徴等 6. 分類結果
7. 表示 5. 分類結果 3. 特徴等
4. 教師データから分類森を作り,
課題データを分類
ゴルジ体 リソソーム ?
教師画像群 課題画像
object Ijp extends KbiPlugIn { private val imgClassA = arg("imgClassA", KbiGenericDialogObj.Choice.empty) private val imgClassB = arg("imgClassB", KbiGenericDialogObj.Choice.empty) def config(argStr: String): Option[() => Any] = runWith(imp => { val winList = KbiWinListObj.all() imgClassA.resetChoice(winList) imgClassB.resetChoice(winList) input(imgClassA, imgClassB) def idx2imp(idx: Int): Imp = winList.getImpFromIdx(idx) match { case null => KbiExc("image not found") case imp => imp } new TrainAndClassifier(idx2imp(imgClassA().idx), idx2imp(imgClassB().idx)) }) } private object Rengine { private lazy val engine = new org.rosuda.JRI.Rengine(Array("--no-save"), false, null) def eval(s: String): org.rosuda.JRI.REXP = engine.eval(s) }
ユーザに教師画像を
2セット(A, B)指定してもらう.
R engine の管理.
R は初回使用時のみ初期化する.
今回のプラグインのソースリスト (一部)
private class TrainAndClassifier(impA: Imp, impB: Imp) extends ProcNotShow { private val featureExtractor = str2featureSet("glcmPlain") private val vectorsA = ips2features(UtilImg.ist2ips(impA.getStack)) private val vectorsB = ips2features(UtilImg.ist2ips(impB.getStack)) private val nDim = vectorsA(0).size private def ips2features(ips: Array[Ip]) = for (ip <- ips) yield featureExtractor.extract(ip).values.drop(2).toArray def proc(istQ: Ist, impQ: Imp, kpl: KbiPlugIn) { val ipsQ = UtilImg.ist2ips(istQ) val vectorsQ = ips2features(ipsQ) val cmdsForR = Util.withArrBuf[String](acc => { def addVectorStr(i: Int) { acc += "tf%d <- c(%s,%s)".format(i, vectorsA.map(_(i)).mkString(","), vectorsB.map(_(i)).mkString(",")) acc += "qf%d <- c(%s)".format(i, vectorsQ.map(_(i)).mkString(",")) } acc += "library(randomForest)" for (i <- 0 until nDim) addVectorStr(i) acc += "imgClass <- c(%s,%s)".format( Array.fill(vectorsA.size)("'A'").mkString(","), Array.fill(vectorsB.size)("'B'").mkString(",")) acc += "dTeach <- data.frame(%s,imgClass)".format((0 until nDim).map(n => "f%d=tf%d".format(n, n)).mkString(",")) acc += "dQuery <- data.frame(%s)".format((0 until nDim).map(n => "f%d=qf%d".format(n, n)).mkString(",")) acc += "rf <- randomForest(formula=imgClass ~., data=dTeach)" acc += "predicted <- as.integer(predict(rf, dQuery))" })
課題画像からの特徴抽出
教師画像からの特徴抽出
R に渡すコマンドを生成
(学習と分類)
cmdsForR.forall(cmd => Rengine.eval(cmd) != null) match { case false => KbiExc("error occurred in R") case true => { val predicted = Rengine.eval("predicted").asIntArray KbiExc.assert(predicted != null, "error occurred in R: predicted") val (ipsEstA, ipsEstB) = Util.withArrBuf[Ip, Ip]((accA, accB) => for ((lbl, idx) <- predicted.zipWithIndex) lbl match { case 1 => accA += ipsQ(idx) case 2 => accB += ipsQ(idx) }) if (ipsEstA.size > 0) UtilImg.show(ipsEstA) if (ipsEstB.size > 0) UtilImg.show(ipsEstB) } } } }
R の呼出
分類結果に応じて
課題画像を
2つに分けて表示.
今回は R script を生成するために double[] a = { 1.2, 2.4, 3.6 }; を String s = String.format("f1 <- c(%g, %g, %g)", a[0]… Rengine.eval(s); のようにデータを文字列中に埋め込んでから評価しているが, Rengine.assign("f1", array); の方が速度や誤差の面では望ましい.
実行のようす: 教師画像群A, Bと課題画像の指定
ゴルジ体 リソソーム
?
(エンドソーム)
実行のようす: 分類結果の表示等
R engine に渡した R script
→ 後で R コンソールで検討可能.
分類
8 vs 83
ゴルジ体 リソソーム
エンドソームの分類状況(一部)
ゴルジ体ぽい
リソソームぽい
エンドソームは今回の特徴量と分類法と
画像セットでは,ゴルジ体よりリソソームに
似た局在をしている.
8 vs 83
Next...
クラスタリングについて
当研究室の湖城さんから