RGB ビット深度のうんちく (前編) 〜 前提知識

前篇、中編、後編の三部作に分けます。この記事は前編です、
ビット深度自体は知ってて具体的な処理を知りたい方は、この記事を読み飛ばして中編から読んでください。

- RGB ビット深度のうんちく (前編) 〜 前提知識
  - https://qiita.com/yoya/items/41b00127b0b1fea8c4f1
- RGB ビット深度のうんちく (中編) 〜 実数型と整数型の変換
  - https://qiita.com/yoya/items/6ee02736f1db8bdd520e
- RGB ビット深度のうんちく (後編) 〜 整数型同士の変換
  - https://qiita.com/yoya/items/3509bbb54c0732865882

サンプルデモを作りました。任意の画像のビット深度を変更できます。お試し下さい。

|  http://app.awm.jp/image.js/bitdepth.html |
|---|
|![スクリーンショット 2018-10-24 14.39.17.png](https://qiita-image-store.s3.amazonaws.com/0/1798/6b09cdde-5cd1-4f3e-4347-451b8752e668.png)|

# はじめに

Webで閲覧できる殆どのデジタル画像のRGBは各々8ビット、1ピクセル辺り計24ビットの輝度値を持ちます。この前者のビット数を**ビット深度(Bit Depth)**又は色深度(Color Depth)と呼びます。つまりビット深度は8である事が多いです。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/1798/c48b82e8-cfe2-7686-2ad0-0bad92a31170.png)
ビット深度に応じて使える色数が決まります。例えば、1ビットだと0,1の2種類の値を表せるので2色表現できます。8ビットだと0〜255で256色ですね。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/1798/2fdc8ae0-8201-35c1-1bec-635b8e384d3b.png)
高画質を求めてビット深度を増やす事もあれば、データ量の節約で減らす事もあり様々な深度が使われます。色んな画像を相手にしていると、4, 8, 12, 14, 16 といったビット深度を見かけるでしょう。

|ビット深度|4ビット| 8ビット|16ビット |
|---|---|---|---|
|グレースケール|![image.png](https://qiita-image-store.s3.amazonaws.com/0/1798/66e21e73-98a1-597c-cdce-0b51dff4547f.png) 2^4=16色 | ![image.png](https://qiita-image-store.s3.amazonaws.com/0/1798/0ae516db-5db4-640e-904c-59504b2c4da6.png)  2^8=256色 | ![image.png](https://qiita-image-store.s3.amazonaws.com/0/1798/5fd454fe-4ae9-3908-d16b-cf74fb5a9b8e.png) 2^16=65,536色 |
|カラフル|![image.png](https://qiita-image-store.s3.amazonaws.com/0/1798/e5929a75-aa9d-fc61-d206-c8c14c0e8cfc.png) 16^3=4,096色 | ![image.png](https://qiita-image-store.s3.amazonaws.com/0/1798/3f193d48-23f5-5ea7-f65e-2e9bef6cf610.png) 256^3=16,777,216色(約1678万色) |![image.png](https://qiita-image-store.s3.amazonaws.com/0/1798/6d978dfd-be40-86b0-f188-673438c2585f.png) 65,536^3=28,147,497,6710,656色(約281兆色) |

更には計算の都合で実数型（float/double等の浮動小数点）の 0.0〜1.0 として扱う事もあります。
少し細かい話ですが、**実数型もデジタル値なので不連続量です。このエントリはそこに目をつむってアナログ値とごっちゃに話をするので、ご容赦ください。**

|浮動小数点 IEEE 754 形式|
|---|
|float(32ビット) ![image.png](https://qiita-image-store.s3.amazonaws.com/0/1798/4c766ed4-5f76-4998-44f9-094d9e844aab.png)|
|double(64ビット) ![image.png](https://qiita-image-store.s3.amazonaws.com/0/1798/853df9c8-9772-1058-68b3-bd07622ff91f.png)|

このシリーズでは、実数型(浮動小数点数)と特定のビット深度を持つ整数型との相互変換の考え方と、中編ではその具体的な処理について、後編にて整数型同士のビット深度変換のうんちくを語ります。

# ビット深度について

参考に、8ビット、3ビット、1ビット の画像を並べます。(みんな大好きレナさん画像です！)
なお、ビット深度8のカラー画像は 24ビット画像と呼ぶ事が多いのですが、このエントリではカラフルもグレースケールもまとめてビット深度8と表現します。

|ビット深度| 8ビット|3ビット|1ビット|
|----|----|----|---|
|グレースケール | ![lena_std-gray.png](https://qiita-image-store.s3.amazonaws.com/0/1798/ed104129-fa1c-312e-3789-cf0b506cfc9a.png) 2^8=256色| ![lena_std_gray-depth3.png](https://qiita-image-store.s3.amazonaws.com/0/1798/3032ec76-163c-7fd8-d112-9958913688cd.png) 2^3=8色|![lena_std-gray-depth1-0.png](https://qiita-image-store.s3.amazonaws.com/0/1798/88b97aca-0b4f-78e3-2eef-78901ae4a228.png) 2^1=2色 |  
| カラフル |![lena_std.png](https://qiita-image-store.s3.amazonaws.com/0/1798/7e1d4ed3-4575-60d3-2cf6-b1ce8b304842.png) 256^3=16,777,216色 |![lena_std-depth3.png](https://qiita-image-store.s3.amazonaws.com/0/1798/9c8991de-ad03-6af5-bbe0-aaa339229865.png) 8^3=512色 | ![lena_std-depth1.png](https://qiita-image-store.s3.amazonaws.com/0/1798/7b1a587e-44e1-71da-781d-1ca2bac73ce2.png) 2^3=8色|

ImageMagick で PNG ファイル生成した結果のサイズを du 表示します。

```
% du -h *.png
 28K	lena_std-depth1.png
 84K	lena_std-depth3.png
464K	lena_std.png
 12K	lena_std_gray-depth1.png
 32K	lena_std_gray-depth3.png
448K	lena_std_gray.png
```

このように、輝度階調/色数と画像ファイルのサイズはトレードオフの関係にあります。目的に応じた丁度良いビット深度の画像に変換する要求が生じてきます。(ほんとはビット深度3でもディザをかければ綺麗にできますが、説明のしやすさを優先)

# ビット深度変換の考え方

## アナログからデジタルへ (A/D 変換)

カメラで取り込む元映像、モニタで表示する先の映像。真の映像は実質無限の解像度と無限階調の連続量を持ちます。いわゆるアナログです。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/1798/a4019609-c2e8-099d-f854-4b6a0be9b7b0.png)

デジタルは無限の分解能は持てないので、適切な縦と横の解像度を決めて各ピクセルで値を持ちます。これを映像/画像の標本化(Sampling)と呼びます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/1798/8d14f12e-7d2e-1d4c-ffa6-131e5f682914.png)

またデジタルは輝度に対して無限の階調を表現できないので、適切なビット深度を決めて、階段状の不連続な輝度に落とし込みます。その事を輝度/色の量子化(Quantization)と呼びます。画像の輝度は大体こんな感じで Quantize します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/1798/e7ac757f-72bc-fe34-1651-eaef0feef31d.png)
よく見ると端っこがいびつな事に気付くでしょう。bitdepth:1 は左右で半々ですが、bitdepth:2 だと 0 と 3 の範囲が狭くて、一見して不公平です。

連続的な量のどの範囲を、どの不連続な値で代表させるかは色んなパターンが考えられます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/1798/42c7faeb-4d92-5250-6f50-ba71d01a70ad.png)

長くなってきたので、具体的な量子化のパターンは次エントリで扱います。

# 最後に

中編に続きます。

- RGB ビット深度のうんちく (中編) 〜 実数型と整数型の変換
  - https://qiita.com/yoya/items/6ee02736f1db8bdd520e