1月第2週の振り返り

1月第2週(1/6-1/12)

法医学

法医学において画像診断は死因判定と生体診察の両方に用いられるが、特に宗教的理由から解剖が忌避される地域において死後画像診断が積極的に導入されている。PMI: postmortem (cross-sectional) imagingと呼称される。

非破壊検査であるため、解剖では骨の破損状況や内容物が失われてしまうもの(骨折・腐敗遺体の脳内出血・空気塞栓・緊張性気胸など)や小型の異物を発見することに向く。一方で軟骨の損傷については発見が難しい。また外傷と病気の両方が考えられるものについて鑑別が不可能である(クモ膜下出血・動脈解離など)。

メディアプログラミング

今回は画像処理について。

昔映画館で流行ったような気がする赤青メガネであるが、赤-シアンのペアになっている。光のRGBのうちRを透過する赤フィルムと、G+Bを透過するシアンフィルムを用意することで、Rチャンネルの輝度配列とG+Bチャンネルの輝度配列を合成した画像を左右の目で分けて受けることができる。RとG+Bをずらして合成することで、左右の目で受け取る輝度情報に視差を生じさせ、そのずらす量に応じて距離が異なっているように知覚させる。そのため「目の前に飛び出して見える」ものは左右の視差が大きい=RとG+Bの像の位置が大きく異なる部分で、遠くに見えるものはその逆である。

撮像素子は光電効果を利用して光の強さを測定する。デジタルカメラでは、Bayer配列と呼ばれる並びのR/G/Bカラーフィルタを通すことで、各画素はRGBいずれかの単一波長の光の強さを測定し、他色の輝度情報を周辺の画素による測定結果から補間することで、各画素に当たっていたであろう光の成分を再現する。

RGBは光の波長ごとの強度を表現しているが、人間の色覚と合致するわけではない。写真の中で日陰に次のような色で画素に表現された物体があるとき、日向にある物体と似た色をしているのはどちらかという問いに対し、ピクセルから直接取得できるRGBでは#0000ff◆◆#00009bユークリッド距離が#0000ff◆◆#6400ffのそれと等しいため、判断できない。しかし環境光による色変化を補正しようとする作用が働き(色の恒常性)、ヒトは通常前者を日向にある物体と似た色だと認識する。そこで人間の色覚に適合するよう、照らされ具合(照度)とは独立に色合いを表現する方法への需要が生じる。

HSV色空間は、物体が反射する光の主波長(色相:Hue)・主波長成分への偏り(飽和度/彩度:Saturation)・主波長成分の分光反射率(明度:Value)によって色を表現するものであり、人間の色覚と親和的であるとされる。

ASP.NET Core MVC

https://docs.microsoft.com/en-us/aspnet/core/data/ef-mvc/ に沿ってWebアプリケーションの設計を学んでいる。チュートリアルASP.NET Core 2に準拠しており最新のLTS版である3.1ではないので記述を変える必要があるところもあったが、概ね順調に進み今週は/ef-mvc/introまで終えた。

モデルの定義の中で関連するデータへのアクセスを容易にするためのナビゲーションプロパティにList<T>ではなく抽象型であるICollection<T>を使うことで、DBから条件を満たすデータを取り出そうという時にList<T>.FindAll()のような不適切な操作(条件を満たしていれば順番は不問であるのに、不要なList<T>化を行ってしまう)による取得を防止することができる。他方DBに格納する時は、仮に新規データをList<他モデル>ではなくDictionary<string, 他モデル>という形で扱っていたとしてもICollectionにキャストすれば受け入れられる。Values.ToList()の必要はない。

この「データ取得操作の規律性」・「データ登録操作の利便性」が、具象クラスではなくインタフェースによる定義を行う根拠なのだろうと思う。

ナビゲーションプロパティについて、 Microsoft.EntityFrameworkCore.ProxiesをNuGetで導入してoptions.UseLazyLoadingProxies()することでLazy Loadingがデフォルトになる(同時にすべてのナビゲーションプロパティにvirtual修飾子が必要となる)。

このLazy LoadingとEager Loadingのコンセプトについて混乱していたが、どうもEF Core 3では以下のようであると認識するに至った(正確性の保証はできない)。

  1. 既定でナビゲーションプロパティは読み込まれず、アクセスするとnullになる
  2. entity.Collection/Reference(e => e.NavProp).Load()をするとそのエンティティについてのみナビゲーションプロパティが読み込まれる(Explicit Loading)
  3. Model.Include(e => e.NavProp)をするとOUTER JOINが行われ、全件について当該ナビゲーションプロパティにアクセス可能になる(Eager Loading)
  4. options.UseLazyLoadingProxies()をするとナビゲーションプロパティへの参照が入った時点で自動的に.Load()する(Lazy Loading)

しかしLazy Loadingは当該ナビゲーションプロパティへの参照が行われるたびその一件についてのみ取得するので、1+Nクエリ問題を引き起こすことがある。

生成されたSQL文はEF Core 3では何もせずともログとして流れているが、warning扱いでVisual Studioの出力には出てこない。確認できるようにするためにはappsettings.Development.jsonで"Microsoft.EntityFrameworkCore.Database.Command": "Information"をLogLevelの中に追加すればよい(以下を参考にした)。

devadjust.exblog.jp