見出し画像

デジタルってなんだっけ

DICOMの歴史までの解説では、DICOMについて、抽象的に、簡単に触れてきました。

DICOMでは、実世界のデータを標準化された属性に分割し、情報オブジェクト定義と呼ばれる「属性の集合」として、任意の実世界のオブジェクトを記述します。

ここでは、このプロセスをより詳細に見ていくために、デジタルデータについておさらいしていきます。

バイナリー

DICOMはデジタルであるからこそ、コンピュータの基礎知識を身につけなければなりません。私たちの日常生活では、数を10進数で数え、0から9までの数字で表しています。

一方で、コンピュータの中のデータは、一般に、2進法で処理されます。

2進法とは、どのようなものも「0」か「1」の2つの数字で表現する方法です。

ビット(bit)は2進法における1桁の数字を表します。

その結果、どのビットも、2つ値のうちの1つしか取ることができません。そう、0か1です。

ビットのほかに、バイト(byte)という単位もありました。1バイトは単純に8ビット(8桁の2進数)のことを意味します。

ではここで、8つの0と1のすべての組み合わせを考えてみます。その数は、2^8=256個(の2進数)になります。

00000000, 00000001, 00000010, 00000011, 00000100, ..., 11111110, 11111111

これは、言い換えると、1バイトは、0から255までの値を表現することができるということです。

一般に、コンピュータは、バイナリデータをバイト単位で読み取ったり、書き込んだりを行います。例えば、13ビットのデータを保存するためには、コンピュータは2バイト(16ビット)分のメモリを確保しなければならないということです。

もう少し具体的な例では、従来のパソコンのモニターは、色の原色(赤、緑、青)の256階調を1バイトで表現しています。

医療で使用されるグレースケール階調を表現できるのは1バイトのみです。つまり、従来のモ二ターでは、256階調のグレーが表示され、それ以上を1バイトに詰め込むことはできません。

特殊な画像診断モニターは、グレースケールに多くのバイト(16、32ビットなど)を割り当てることができるようになっており、この制限を克服しています。

また、1バイトはすべてのラテン文字を表現します。1バイトは1文字単位とみなされます。「a」という1文字は、1バイトのデータというわけです。例えば、12文字を表現する場合、コンピュータは12バイトのメモリーを使用します。

画像のような大容量のデータは、保存に数百万バイトを必要とすることがあります。

そのため、2進法ではバイトを大きな数字で数えます。2^10=1024バイトは1キロバイト、1024キロバイトは1メガバイトに相当します。

量の単位のおさらい(^記号は、累乗のつもり)

普段は、バイトの単位は、2つの異なる方法でカウントされます。 情報技術では2^10=1024の倍数を使いますが(これは2進法の観点からは完全に理にかなっています)、よくパソコンメーカーは、キロ、メガなどを1000の倍数で表記しています。不思議なのですが、1GBのSSDドライブは、10^9バイトで、2^30(バイナリー的な意味でのGB)より7.37%少ないのです。まあ、そんなことはどうでもいいのですが(いいんかい!)。

さて、バイトを表すときは、KB、MB、GBのように書きますが、ときどき、Kb、Mb、Gbのように小文字のbを使う場合を見かけますよね。これは、バイトではなくビットを表していることが多いです。

わざわざこのように書く理由は、ネットワークを考えるときに役立つからです。ネットワークの帯域幅は、コンピュータのストレージとは異なり、通常1秒間に何ビット通信させるかで考えます。例えば、キロビット、メガビット、ギガビットで測定されますよね。

Hexadecimal

次に、16進数です。

16進数は、連続した2バイトの短縮表現で、65536(256^2)個の値が表現可能です。16進数は16ビット(2バイト)なので、0~9の数字と10~15を表すA~Fの文字からなる文字を使って、16進法で扱うことができます。Aは10、Bは11を表し、Fは15を表すということです。16進数で表すには16個の記号が必要なので、A-Fを加えて新しい数字としているというわけです。

また、テキスト(文字データ)や10進数と区別するために、データとして16進数を扱うときには、16進数の前に0xを付けます。

0x007Fの16進数はどのように解釈できるかやってみましょう。
10 進法の 10 の累乗と同じように、各桁に合わせて 16 の累乗を掛けます。(接頭辞の "0x "を無視して)16進数で0x007Fを表すと、次のようになります。

0 * 16^3 + 0 * 16^2 + 7 * 16^1 + F * 16^0 = 127

10進法の場合、当然ですが、2桁の数字は、00、01、02、...から99まで表すことができます。同様に16進数では、0〜9、A〜Fの16種の値を用いて、0x00から0xFFまでの2桁の16進数を表現でき、これは、16^2=256通りの値をカバーしていることになります。この256通りは、すでにご存知のように、1バイトに相当するわけです。

ただし、例えば、16進数の0x7Fは1バイト、0x007Fは00と7Fの2バイトを使っています。

16進数では、0xを取り除いた部分で、常に先頭にゼロが書き込まれます。先頭のゼロは、数値(0x7F=0x007F=127)を変更しませんが、その数値を格納するために必要なコンピュータのストレージのバイト数を指定する意味を持っています(16進数2桁につき1バイト)。

DICOMは、0x 接頭辞と互換的に、16進数にH接尾辞を付けることができます。 例えば、DICOMの「12」は10進数に対応し、「12H」または「0x12」は16進数の12、または、1 * 16^1 + 2 * 16^0 = 16 + 2 = 18を意味します。

Hや0xがある場合、または10進数では不自然な、先頭のゼロとA-Fから成る数字は、16進数形式であると考えましょう。

DICOMの数値のほとんどは、16進数(かつバイナリ)形式で保存されていることを、原則として覚えておいてください。

テキスト

データはその形式によって、テキストまたはバイナリ表現で表すことができます。バイナリ形式は、単一の数値や数値列(画像ピクセルなど)のエンコードに使用されます。

先に説明したように、2進数はコンパクトで、コンピュータに適した方法で数値を格納できる利点があり、デジタルデータを扱うために利用されるのは自然な流れです。

一方、2進数のデータエンコーディングは、コンピュータに依存します。コンピュータによっては、バイトオーダーが異なる場合があるのです。

あるシステムでは、最下位バイトから始まる数字を記録することもあれば(リトルエンディアンオーダー)、他のシステムでは、同じ数字を最上位バイトから記録する(ビッグエンディアンオーダー)こともあります。

例えば、リトルエンディアンのコンピュータ(Windows PCなど)がバイナリ形式で0x007Fと記録しているものを、ビッグエンディアンのコンピュータでは、バイトを逆から並び替えて、0x7F00として記録します。データが、エンディアンタイプの異なるシステム間を行き来する場合、エンディアンタイプを適切に変換する必要があります。そうしないと、数値が逆に読み込まれ、全く違った値になってしまいます。0x007F=127が、0x7F00=32512のようになってしまうということです。

ビッグエンディアンオーダーのコンピュータは、2023時点ではほとんど見かけませんが、技術としてあるということは知っておいて損はないでしょう。

このようなエンディアンタイプに起因するデータ転送のエラーを避けるために、DICOMアプリケーションは常にエンディアンタイプを一致させます。例えば、通信している2つのDICOMユニットがある場合、データ転送を開始する前に、最初のネットワークのハンドシェイクの中でエンディアンタイプの選択を行うわけです。

これを可能にするために、DICOMはリトルエンディアンをデフォルトのバイトオーダータイプとしています。つまり、すべてのDICOMアプリケーションは、それがどのようなシステムまたはハードウェア上で実行されているかにかかわらず、リトルエンディアンバイトオーダーで処理できることが求められるということです。

ビッグエンディアンとリトルエンディアンの議論は、技術的なメリットよりも、ハードウェアの歴史に大きく関わっています。私がDICOM製品の開発に携わるときは、これらのエンディアンタイプを適切に扱うことは、製品のクロスプラットフォーム性を保証するための責任の1つとして求められるのでしょう。

さて、テキストの話に戻ります。
数値と比較して、テキストデータでは各文字(バイト)が独立して保存されるため、ハードウェアに関係なく常に同じ順序で保存されます。

DICOM は、データ型に応じて、テキストとバイナリの両方の形式を使用します。

DICOMファイルをワードパッドで開くと、全く読めない記号のなかに、多少意味のあるテキスト文字列が混在しているのがわかります。

DICOMファイルをワードパッドで開いた画面

見ての通り、DICOMデータに保存されている内容を読み解くためには、常に専用のDICOMソフトウェアが必要になります。これは、DICOMと、任意のテキストエディタを使用して読み取りや変更が可能なフォーマット(HTMLやXMLなど)を区別するためです。

次回の解説からは、DICOMのテキストとバイナリデータがどのようにフォーマットされるかを、DICOM文法から読み解いていきたいと思います。


Stay Visionary


この記事が気に入ったらサポートをしてみませんか?