https://hinastory.github.io/cats-cats-cats/, you can read useful information later efficiently. 今回は深層学習、ディープラーニングで細胞の種類を判別してみたいと思っています。判別するのは私が普段実験で使っている上皮細胞のeph4という細胞と、遺伝子発現用のhek293という細胞です。 4.1 Image Jを用いて画像を二値化する方法; 4.2 ImageJを使って細胞の数を数える方法; 4.3 ImageJを使ってくっついている細胞同士を分離する方法; 4.4 Image Jを用いて蛍光標識された多数の物体の面積を求める方法; 4.5 Image Jを用いて輝度を調べる方法 本記事ではその状況に一石を投じたく、一般のプログラマにも伝わるようになるべく図解で「パターンマッチ」を解説してみたいと思います。, 本記事はプログラミング言語における「パターンマッチ」1という機能に着目して解説したものです。「パターンマッチ」は、switch文の強化版2であり、仮にパターンマッチを持たないプログラミング言語のユーザだとしても全プログラマが知っていて損はないアイデアだと思います。, パターンマッチは以下の図のように、入力データを「パターン」と呼ばれる特定の構造と照合して、データとパターンが適合(マッチング)した場合に分解して要素を取り出します。, パターンマッチの凄いところは、入力データの値だけではなく、構造にも着目してデータを抽出できることです。上記の図は入力データとして同じ整数の配列([1,6,5,2])を用いて、4種類のパターンを用いてパターンマッチを実行している様子です。1番目のパターンは特に説明は不要だと思うので、二番目のパターンから説明するとパターン([1,x,5,y])のように、構造から値を抽出しておきたい場所を変数にしておけば、データ構造を分解することができます。抽出した変数は後の変換処理で利用できます。3番目のパターンはパターンマッチが失敗していますが、理由は簡単でパターンと入力データの長さが異なるからです。4番目のパターンは再帰処理でよく使うパターンで配列の先頭とそれ以外にデータを分割できます。, このようにパターンマッチを用いると、データ構造をパターンを用いて分解して処理ができるので、様々なアルゴリズムが書きやすくなるというメリットがあります。, パターンマッチの構文はプログラミング言語ごとに異なりますが、概ね「入力」と「パターン」と「変換処理」を記述できます。以下はscalaを用いた一番シンプルなパターンマッチ構文の例です。, 変換処理では分解によって取り出した変数を利用した処理を書くことができます。そして、変換処理の結果自体がパターンマッチ全体の結果となります。パターンマッチに失敗した場合は一般的には例外が発生します。, 最初の図の4つのパターンマッチをScalaで記述した例が以下になります。Scalaを知らなくても上記の図が理解できていれば、どんな処理をしているのか想像がつくと思います。, パターンはいくつかの基本形に分類されますが、以下は自分が特に重要だと思う9つの基本形です3。パターンマッチで一番誤解を受けいているのがこの部分で、この基本形を十分に理解せずにはパターンマッチを使いこなしているとは言えないと思います。そしてこの基本形を使いこなせるようになればパターンマッチ、ひいてはプログラミングの世界が大きく広がると思います4。, 基本形は組み合わせてより複雑なパターンを記述することができます。重要な役割を果たすのが入れ子構造にすることが可能なシーケンスパターンとタプルパターンです。, 上記の複雑なパターンは「定数パターン」、「変数パターン」、「ワイルドカードパターン」、「シーケーンスパターン」、「タプルパターン」、「asパターン」、「パターンガード」の7つの基本形を組み合わせたパターンになります。このようにパターンは入れ子にすることで飛躍的に表現力が増し、応用範囲が広がります。さらにはパターンマッチで分解した結果を「変換処理」の中でさらにパターンマッチすることもできます。つまりパターンだけでなくパターンマッチ自体も入れ子にすることができます。以下の例はScalaを用いたパターンマッチを入れ子にした例です5。, ここまで読んでいただいた方はパターンマッチにおける基本形の重要さが理解できたと思います。そして一番最初に図解したパターンがどの基本形にあたるかも簡単に分かると思います。プログラミングの重要な目的の一つはデータを処理することだと思います。そしてパターンマッチはデータ構造をパターンで分析し処理するのにうってつけの機能です。従ってパターンマッチは間違いなくプログラミングの本質に迫る機能だと考えられます。, プログラミング言語のパターンマッチは、以下の図のとおり入力と出力がある一種の関数と考えることができます。パターンマッチの内部は「パターン」と「変換処理」と呼ばれるユーザが定義するデータと「照合(check)」、「分解(destructure)」、「変換(transform)」と呼ばれる3つの工程から構成されています6。, 上記の図は「シーケンスパターン」を用いて、整数の配列[1,2,3]の入力に対するパターンマッチを実行している様子を示しています。この入力のパターンマッチは成功して実行結果として5を返しますが、もし、仮に入力が[1,2]だった場合にはパターンの照合に失敗して赤矢印で示した「NG」へ行き、パターンマッチが失敗します。, パターンマッチを関数とみたときにこのように失敗する可能性がある場合は、失敗しない関数(数学的な意味での関数、全関数とも言う)と区別して「部分関数」と呼ぶことがあります。部分関数を全関数にするにはパターンを網羅的にする必要があります。, 「照合」の役割は、以下の図のようパターンに適合(マッチ)する入力データを選別することです。そして適合したデータは次の「分解」のフェーズに送られます。, 「分解」の役割は、以下の図のようにパターンに従ってデータを分解して、変数に対応する値を入力データから見つけて変数に入れることです。分解の結果は次の「変換」のフェーズに送られます。, この分解はパターンマッチ構文以外でも見ることができます。例えば以下は擬似コードですが代入がシーケンスパターンのパターンマッチになっています。, このように代入に見えてパターンマッチになっているケースもあるので、実は知らないうちにパターンマッチのお世話になっているかもしれません。, 「変換」の役割は、以下の図のように変換処理の変数に分解結果の変数を引き当てて、評価することです。評価した結果は出力としてパターンマッチ全体の結果になります。, パターンマッチの合成には直列合成と並列合成があります。直列合成のイメージは以下の図のように通常の関数の合成のイメージと同じで前の関数の出力と後ろの関数の入力の型が合えば合成することができます7。, ソースコードの方が理解しやすい方がいるかも知れないので以下にScalaで2つのパターンマッチを直列合成をした例を記載します。, 以下はパターンマッチの並列合成です。並列合成は大抵の言語のパターンマッチ構文に組み込まれているので、あまり「合成」と意識することは少ないかもしれません。しかし直列合成と比較するとプログラミングの論理演算であるandとorと類似していることが分かると思います。つまり、直列合成の場合はパターンマッチが全て成功しないと合成されたパターンマッチが成功しないのに対して、並列合成ではパターンマッチが一つでも成功すれば、合成されたパターンマッチが成功します。, 以下は直列合成の例を並列合成に書き換えたものです。結果が変わっているのがわかると思います。, 並列合成のパターンマッチの場合には、パターンの重なりを意識することが重要です。以下の図は整数の集合における基本的なパターンの重なりを分類したものですが8、このようにパターンを図で思い描けるようになるとパターンの設計に非常に役に立ちます。, 並列合成では上のパターンマッチから順番に照合されるため、パターンに重なりがあると上のパターンマッチが優先されることになります。特に包含関係にあるパターンは上に大きいパターンを持ってくると下のパターンが隠れてしまって全く照合されない事態になるので、注意が必要です。, またパターンを網羅的にすることでパターンマッチの失敗がなくなり、無意識にバグを作り込むことを防ぐことができます。従ってパターンマッチは特に理由がない場合は網羅的にすることが望ましいです。網羅的にするのに適した基本パターンは「変数パターン」と「ワイルドカードパターン」になるので、並列合成の一番最後にこれらのパターンを入れることを検討してください。, 従来パターンマッチはHaskellに代表されるような関数型言語の十八番でしたが、現在では関数型プログラミングに源流を持たないプログラミング言語でもパターンマッチを実装するようになってきました。C#では7.0以降でパターンマッチが利用可能であり、Rubyでもすでにtrunkではパターンマッチが利用できます9。また比較的新しく出た言語は最初からパターンマッチが使える場合が多く、パターンマッチの世界は広がり続けています。仮にお気に入りの言語にパターンマッチがなかったとしても諦めるのはまだ早いかもしれません。使い勝手は言語に統合された機能よりは劣るかもしれませんが、パターンマッチのためのライブラリも数多く公開されています。, 言語としての変わり種は Egisonです。「直感をそのまま表現するパターンマッチング 」という謳い文句で、パターンマッチとして非常に面白いので気になった方はぜひ触って見てください。, このように少しずつですが着実にパターンマッチが使える言語が増え続けているのは、パターンマッチがプログラミング全般で非常に用途が広く、使いこなすことで直接的にプログラマの能力を拡張するからだと思っています。以下の図は思いついたパターンマッチの用途です。, パターンマッチは関数型プログラミングでは特に再帰関数と相性が良く欠かせない存在ですが、一般のプログラマへの浸透具合はいまいちと感じたので、関数型プログラミングの文脈からなるべく切り離して解説をしてみました。, ここで言うぱ「パターンマッチ」はパターンマッチを実装しているプログラミング言語の総和でイメージしており、特定のプログラミン言語のパターンマッチを意味していません。従って、本記事で解説しているパターンマッチの機能や用語は個別の言語でそれぞれ異なる場合があります。 ↩, ここで言う「switch文」とはC言語のswitch文をイメージしています。また、ここではswitch文とパターンマッチとの歴史的な繋がりではなく、機能的な包含関係について「強化版」という表現をしています。 ↩, パターンの記述は疑似言語で記載しています。また、パターンマッチの対応を謳っているプログラミング言語でも、いくつかの基本形が使えない場合があります。しかし上の6つのパターンはだいたい使えるのではという感触です。 ↩, 9つの基本形は非常に重要なのでA4サイズで収まりがいいように図を工夫しました。チートシートとしてご利用ください。机や冷蔵庫に貼って忘れないようにするのもいいかもしれません(笑)。 ↩, 工程の呼び方はいろいろあります。例えばdestructureとextractと呼んだりtransformをmapと呼ぶ場合もあるようですが、ここでは自分が一番分かりやすいと思った表現を採用しています。また、「照合」と「分解」だけを指して「パターンマッチ」と呼ぶ流儀も存在しますが、多くのプログラミン言語のパターンマッチの構文には変換処理も含まれるので、この記事では「変換」も含めて「パターンマッチ」と呼びます。 ↩, 実際には型だけでなく関数の定義域や値域を考慮する必要がありますが、数学的な話になってくるので詳細は割愛します。 ↩, 整数にしたのはイメージが簡単にできると思われるためであり、ここで説明するパターンの重なりは整数以外の集合にも同じことが言えます。 ↩. You write expressions that examine the object, and make control flow decisions based on those conditions.   You'll often find that pattern matching expressions can be a very useful tool when you're working with data and want to separate the data storage concerns from the behavior concerns. パターン マッチングでは、現在既に使用しているアルゴリズムに対してより簡潔な構文を提供します。 Pattern matching provides more concise syntax for algorithms you already use today. エッジ検出を行い,閾値処理により2値画像を用意する. 2. ab空間をセルに分割する.セルの値をゼロにしておく. 3. Your email address will not be published. (adsbygoogle = window.adsbygoogle || []).push({}); ImageJは無料の画像処理ソフトです。マックでもウインドウズでもリナックスのOSでも使えて、研究で必要な画像処理が比較的簡単にできるので、バイオ研究者の間で非常によく使われています。自分も長年にわたり使ってきましたが、画像データを見直したり簡単な解析(特定の領域の平均輝度を取得するなど)を行うときには、Image Jを使うのが一番手軽で便利な方法だと思います。, 実際には、Image Jよりもさらに高機能なFijiを自分は使っています。Fijiは単にImageJそのもので(Fiji is just ImageJ)、プラグインが最初からたくさんくっついてくるだけです。Image Jは様々なデータ処理・データ解析のためにプラグインを入れることができますが、Fijiには最初からこれらのプラグインがてんこ盛りで入っていますので、いちいち後からインストールする手間がなくて良いです。顕微鏡メーカーやカメラメーカー独特の画像フォーマットでも、大抵の画像ファイルがFijiで開けてしまいます(Bio-Formatsを利用するなどして)。, ImageJは、https://imagej.nih.gov/ij/download.html からダウンロードできます。Fijiは、https://imagej.net/Fiji/Downloads からダウンロードできます。, アイデア次第でいろいろな画像処理がImageJでできますが、自分がよくやる画像処理をいくつか紹介します。, メニューからImage, Adjust, Threshold…を選びます。2つのスライダーを調節して、望む画像になるような閾値を探して決めましょう。今の場合、76-255としました。Applyボタンをクリックして適用します。, この画像を使って、ImageJでカラー画像を白黒にし、2値化して、粒子解析の機能を利用して、細胞の数を数えてみます。, メニューからFile, Open…として、ダウンロードしておいた目的の画像ファイルを開きます。, メニューからImage, Type, 8-bitと順に選びます。これで白黒画像に変更されました。, メニューからImage, Adjust, Threshold…を選びます。2つのスライダーを調節して、全ての細胞が分離できそうな閾値を探して決めましょう。今の場合、183-255としました。Applyボタンをクリックして適用します。, さてそれでは粒子解析 (Particle Analysis) の機能を使って、数を数えましょう。, 抽出された粒子(今の場合、赤血球)のパラメータとして何を知りたいかは、メニューからAnalyze, Set Measurements… とすることにより選択できます。パネルの中のAreaにチェックが入った状態にします。他は今はとりあえず不要です。ここで、写真の中の赤血球のだいたいの面積を知っておきましょう。メニュー上にあるROIの形(四角形や丸や不定形など)から丸(Oval)を選び、赤血球の一つがちょうど同じ大きさになるように合わせます。そして、Analyze, Measureと選ぶと、Resultsという名のウインドウ上に(みあたらなければ、メニューからWindow,Resultsと選ぶと、最前面に表示されます)Areaが表示されます。今の場合420という数値になりました。カーソルを細胞の上にあてると画素の値が出ますが、今やってみると、黒く表示されている赤血球の画素の値が0で、白いbackグランウンドの値が255でした。粒子を数えるときは値が255でないと困るので、ここでメニューからEdit, Invertを選び白黒を反転させます。, それではいよいよ粒子解析を行うため、Analyze, Analyze Particles…を選びます。粒子としてカウントするサイズをここで選ぶことができます。ここで粒子の面積のサイズが取りそうな範囲を適切に設定してやれば、画面上のノイズや目的外のものを除外できる可能性があります。さきほど赤血球の面積がおよそ400画素程度だったので、ここでは広めにとって、Size (pixel^2): 200-800 としておきましょうか。Circularityは全範囲にしておきます。明らかに丸っこいものしかないというのであれば、ここで強い条件(1に近い範囲)を設定してやれば、不定形のごみを区別して除くこともできます。あとは、Display results, Clear results, Summarize, Include holesにチェックを入れておきます。 Include holesというのは、赤血球の丸い形の真ん中が2値画像にしたときに抜けていても、その穴は埋めた状態として(つまり穴に見える部分の画素も細胞に属する画素として)考えてくれるということです。あと、Show:Masksを選んでおきます。粒子解析を実行した結果、マスク画像として以下が得られました。ここには、粒子としてカウントされたものが表示されています。たしかに「穴」も埋められていることがわかります。, さて、Summaryというウインドウに結果が表示されており、それを見るとCountが573、Average Size(粒子の面積の平均)が419.211となりました。つまり、赤血球の数がおよそ573個あって、それらの面積の平均は419画素だったというわけです。ちなみに、もとのカラー写真をみると白血球みたいなものも一つありましたが、この画像処理ではそれは無視されて赤血球と区別がつかなくなっているため、カウントされています。, こんなふうに細胞同士がくっついて見える写真で数を数えるにはどうすればいいのでしょうか?, メニューの欄からImage, Type, 8-bitと選び、まず白黒画像にします。, Image, Adjust, Threshold…で2値化します。スライダーをうごかして、できるだけ細胞がはっきり見えるように調整しました。細胞の画素が0で背景が255になっていたので、Edit, Invertで白黒を反転させます。, Process,Binary, Fill Holesで細胞の真ん中部分の「穴」を埋めます。まあ完全ではありませんが。これくらいなら、手作業で不完全に残った「穴」の開いた細胞を埋めてもいいかもしれません。, さて、この画像は結構細胞同士がくっついていますが、Process, Binary, Watershed により、無理やり分離させてみます。, 完全とはいいがたいですが、大半に関してくっついていた細胞が分離できています。これの画像に対して視野を覆うように円形のROIを適用してParticle Analysisを適用すれば、細胞数が数えられるでしょう。, Watershedの機能も用いて細胞を分離して、細胞数をカウントする方法を示したYOUTUBE動画があったので紹介しておきます。

D 01j Adb Driver 34, デレステ 総選挙 歴代 6, カインズ 掃除機 収納 4, Xperia ポケモンgo 重い 4, 恐竜 名前 英語 12, 月灯りの下で 歌詞 意味 7,