====== 【数値情報処理b】第1回 デジタル画像について ====== ===== 数値情報処理b について ===== コンピュータで扱う画像はデジタルデータである。 画像を見やすくしたり、画像から情報を抽出することは画像処理ソフトウェアを使えば簡単にできるが、その画像処理の原理を知らなければソフトウェアを使いこなすことができない。 本講義では R と imager を使って様々な画像処理の方法の原理について学ぶ((Ruby や他の言語でも同じ方法は使える。))。 * 輪郭抽出 * 画像の平滑化 * 変形 * 物体検出 * 色空間 ---- 授業では RStudio を使用する。 RStudio は Web ブラウザで動作する R のIDE(統合開発環境)である。 * [[r:top]] 学内に RStudio サーバを用意してある。ただし、学内ネットワークからのみアクセスできる。 * [[RS>|学内 RStudio サーバ1(学内限定)]] * [[RS2>|学内 RStudio サーバ2(学内限定)]] 学外から利用したい場合は[[https://www.koeki-prj.org/roy/openvpn/|VPN 接続]]でアクセスする。 ---- ==== プロジェクトの作成 ==== プロジェクト機能とは、特定の作業ディレクトリでスクリプトファイルなどを管理する機能である。 「数値情報処理b」用のプロジェクトを作成するには以下の手順で行う。 - 右上のプロジェクトボタンをクリックして ''**[New Project]**'' を選ぶ、もしくはメニューの ''**[File]**''%%→%%''**[New Project]**'' を選ぶと「Create Project」のウィンドウが開く。 - ''**[New Directory]**'' を選ぶ。 - ''**[New Project]**'' を選ぶ。 - 「Directory name:」にプロジェクト名「数値情報処理b」を入力する。 - 「Create project as subdirectory of:」 が「~」になっていなければ ''**[Browse]**'' をクリックして ''**[Home]**'' ボタンをクリックした後 ''**[Choose]**'' ボタンをクリックする。 - ''**[Create Project]**'' をクリックする。 これでプロジェクトが作成できる。 他の講義でこの学内 RStudio サーバを使う場合は、ファイルが混ざってごちゃごちゃにならないように講義ごとにプロジェクトを作成し、プロジェクトを切り替えて使うと良い。 別のプロジェクトへの切り替えは右上のプロジェクトボタンから行う。 ===== R と RStudio の使い方 ===== * [[r:rstudio]] * [[r:basic1]] * [[r:basic2]] ===== 画像編集用ソフトウェア ===== 画像編集用ソフトウェアは、画像を表示するだけでなく、変形や合成を行えるなど様々な機能を持っている。 代表的な画像編集用ソフトウェアは以下のものがある。 * [[https://www.adobe.com/jp/products/photoshop.html|Adobe Photoshop]](商用) * [[https://www.gimp.org|GIMP]](無料、オープンソース) * [[https://ibispaint.com/about.jsp|ibisPaint]](無料) 本講義では画像編集ソフトウェアが実際にどのような処理を行っているのかを R のプログラムを通して理解する。 ===== imager(R のパッケージ) ===== 本講義では R で画像を扱うために imager という画像処理のパッケージを利用する。 * https://dahtah.github.io/imager/ * [[https://cran.r-project.org/web/packages/imager/imager.pdf|リファレンス(英語)]] imager を利用するには以下のコマンドをコンソールで実行する。 スクリプトを実行する際はスクリプトの最初に書いておく。 library(imager) ---- ==== 画像の読み込み ==== 画像の読み込みは ''load.image()'' で行う。 > 変数 <- load.image("ファイル名") ファイル名には RStudio サーバにアップした画像ファイルや URL を指定する。 このコマンドでは、読み込まれた画像のデータが変数に代入され、その型は cimg になる。 以下、cimg 型の変数を「cimg 変数」とする。 ---- ==== 画像の表示 ==== 画像の表示は ''plot()'' で行う。 > plot(cimg変数) RStudio では、右下のペインの Plots タブにグラフのように画像が表示される。 さらに引数をオプションで追加することができる。 よく使う引数は以下の通り。 ^ 引数 ^ デフォルト ^ 機能 ^ | ''rescale'' | ''TRUE'' | ''TRUE'' だと画素値が [0,1] の範囲になるように調整される(リスケール)。 | | ''interpolate'' | ''TRUE'' | ''TRUE'' だと画像の画素を滑らかに表示する(アンチエリアス)。 | | ''axes'' | ''TRUE'' | ''TRUE'' だと軸を表示する。 | 例えば以下のコマンドでは、''im'' という cimg 変数に ''https://www.koeki-u.ac.jp/uploaded/image/1004.jpg'' という URL の画像を読み込み表示する。 > im <- load.image("https://www.koeki-u.ac.jp/uploaded/image/1004.jpg") > plot(im) 軸を表示したくなければ引数にオプションを追加して指定する。 > plot(im, axes = FALSE) ---- ==== サンプル画像 ==== imager ではサンプル画像が用意されている。 特に ''boats'' はあらかじめ cimg 変数として用意されているのですぐに使えて便利である。 > plot(boats) その他のサンプル画像は ''load.example()'' で読み込む必要がある。 ^ 画像名 ^ 説明 ^ | ''parrots'' | オウムの写真 | | ''coins'' | コインの写真 | | ''birds'' | 鳥の絵 | | ''hubble'' | ハッブル宇宙望遠鏡で撮影された深宇宙の画像 | | ''tennis'' | 卓球の動画 | > im <- load.example("parrots") > plot(im) ---- ==== 画像の書き出し ==== cimg 型の変数のデータを画像ファイルに書き出すには ''save.image()'' を使う。 > save.image(cimg変数, "ファイル名") 画像ファイルフォーマットはファイル名の拡張子で判断される。 JPEG 形式の場合は、引数に ''quality'' を与えることで品質を設定できる。 品質の値は 0 から 1 の間の範囲で、1 に近いほど高品質になり画像の劣化は少ないが、ファイルサイズは大きくなる(デフォルトは 0.7)。 画素値が [0,1] の範囲以外の場合は自動的にリスケールされる。 **書き出した画像ファイルは RStudio サーバに保存される。** RStudio サーバに保存された画像ファイルは右下のペインの Files タブでクリックすればブラウザ上に表示されるので、それを自分の PC や端末に保存できる。 ---- ==== 新規画像の作成 ==== 新規画像を作成するには ''imfill()'' を使う。 > 変数 <- imfill(横幅, 縦幅, val = 塗りつぶしの色) 塗りつぶしの色には ''%%"black"%%'', ''%%"white"%%'', ''%%"red"%%'' のように英語文字列で色名を与えるか、''c(1,0,0)'' のように RGB の値で与えることができる。 ---- ==== 文字列の描画 ==== 画像に文字列を描画するには ''draw_text()'' を使う。 cimg 変数の画像を背景とした文字列を描画した新しい画像を生成する場合は以下のようになる(元の cimg 変数は変わらない)。 > draw_text(cimg変数, x座標, y座標, 文字列, col = フォント色) フォント色には ''%%"black"%%'', ''%%"white"%%'', ''%%"red"%%'' のように英語文字列で色名を与えるか、''c(1,0,0)'' のように RGB の値で与えることができる。 オプション ''fsize'' でフォントサイズを変更できる(デフォルトは 20 ピクセル)。 例えば以下のコマンドでは、 - 黒で塗りつぶした 60x40 の画像を ''im1'' に代入。 - ''im1'' を背景として文字列 ''%%"KOEKI"%%'' を(フォントサイズ20で)描画した画像を ''im2'' に代入。 - ''im2'' を背景として文字列 ''%%"UNIV"%%''をフォントサイズ16で描画した画像を ''im3'' に代入。 を実行している。 > im1 <- imfill(60, 40, val = "black") > im2 <- draw_text(im1, 1, 1, "KOEKI", col = "white") > im3 <- draw_text(im2, 1, 20, "UNIV", col = "white", fsize = 16) ===== デジタル画像 ===== コンピュータの中では画像は__**画素(ピクセル)**__の集合として描かれる。 1 つの画素は 1 色で塗りつぶされたタイルである。 それぞれの画素における色の濃淡の値を__**画素値**__という。 {{ pixel.png?nolink |画素のイメージ}} 上図のように画像中の画素は縦と横に格子状に並んでいる。 **右方向を $x$ 軸の正方向**、**下方向を $y$ 軸の正方向**((数学の場合は上方向を $y$ 軸の正方向にとる。))にとり、画素の(中心)座標は $(x,y)$ で表す。 * imager では、一番左上の画素の座標は $(1,1)$ である。 * GIMP などの他のソフトウェアでは、一番左上の画素の座標は $(0,0)$ の場合が多い。GIMP では、画像を読み込んで 5 を押して表示倍率 16 倍にすると分かりやすい(1で 1 倍になる)。 それぞれの画素の画素値はコンピュータの中では配列として格納されている。 一般的な画素値は 8bit(1byte)の整数で表される。 つまり $2^{8}=256$ 階調で 0 から 255 の範囲の整数値であり、小さいほど暗く大きいほど明るい。 コンピュータでは、色は光の 3 原色である **赤(Red)**、**緑(Green)**、**青(Blue)** の重ね合わせで表現される。 これらは略して R, G, B とそれぞれ呼ばれる。 {{ primarycolors1.png?nolink |光の三原色}} カラー画像の場合、1 つの画素には R, G, B の 3 つの情報があり、__**カラーチャンネル**__という。 それぞれのカラーチャンネルは 256 階調の画素値を持ち、 R, G, B の 3 つのカラーチャンネルを合わせると $256^{3}=16777216$ で約1677万色の表現が可能である。 {{ sample_rgb.png?nolink |カラー画像のカラーチャンネル}} グレースケール画像(モノクロ画像)の場合、1 つのカラーチャンネルの情報で表現できる。 256 階調の画素値を持ち、0 だと真っ黒、255 だと真っ白を表す。 {{ sample_grayscale.png?nolink |グレースケール画像}} カラーチャンネルの他に__**アルファチャンネル**__を持つ場合があり、補助的な情報(透明度など)に利用される。 ---- ==== cimg型 ==== imager で読み込んだ画像は cimg 型のデータである。 cimg 型は4次元の配列であり、各次元は順に x, y, z, cc となっている。 ^ 各次元 ^ 意味 ^ | x | 横方向の座標 | | y | 縦方向の座標 | | z | z は動画のフレーム番号(画像では使わないので z=1 に固定) | | cc | カラーチャンネル | 各次元の配列のサイズは ''dim(cimg変数)'' で分かる。 > dim(boats) [1] 256 384 1 3 ''boats'' の画像は * x のサイズ(横幅)が 256 * y のサイズ(縦幅)が 384 * z のサイズ(フレーム数)が 1 * カラーチャンネルが 3チャンネル であることが分かる。 画像のサイズを知るための関数としては以下がある。 ^ 関数 ^ 機能 ^ | ''width(cimg変数)'' | x のサイズ(横幅)を返す。 | | ''height(cimg変数)'' | y のサイズ(縦幅)を返す。 | | ''depth(cimg変数)'' | z のサイズ(動画のフレーム数)を返す。画像の場合は 1 である。 | | ''spectrum(cimg変数)'' | カラーチャンネル数を返す。 | | ''dim(cimg変数)'' | 横幅、縦幅、フレーム数、カラーチャンネル数を返す。 | | ''nPix(cimg変数)'' | 全ピクセル数(横幅×縦幅×フレーム数×チャンネル数)を返す。\\ ''prod(dim(cimg変数))'' と同じ。 | カラー画像の場合、各カラーチャンネルの画素値の配列は以下のように取り出せる(#以下はコメント)。 > imc <- boats > imc[, , 1, 1] # Rチャンネル > imc[, , 1, 2] # Gチャンネル > imc[, , 1, 3] # Bチャンネル これで取り出した値は matrix 型になるので ''plot()'' で表示させようとしても画像表示にはならない。 画像表示させたければ、''as.cimg()'' で cimg 型にするとよい。 > plot(as.cimg(imc[, , 1, 1])) 座標 $(x,y)$ の画素値を取り出すには以下のようにする。 > imc[x, y, 1, 1] # Rチャンネルの座標(x,y)の画素値 ''color.at()'' を使うと座標 $(x,y)$ の全てのカラーチャンネルの画素値が取り出せる。 > color.at(imc, x, y) 一般的な画素値は 0 から 255 の範囲の整数値と上で述べたが、cimg の画素値は一般的な画素値を 255 で割って **0 から 1 の範囲 [0,1] の実数値**にしたものになる。 [0, 1] の範囲以外の値も一応使えるが、''plot()'' などでは自動的にリスケールして解釈されることがある。 ===== 小テスト① ===== [[KMS>|Moodle Server(非公式)]]で第1回の小テスト①を受験しなさい。 ===== グレースケール化 ===== カラー画像は ''grayscale()'' でグレースケール化することができる。 > grayscale(cimg変数) グレースケール画像の場合、基本的にカラーチャンネルは1つだけである((ただし、RGB の3チャンネルでもグレースケールを表現することは可能。))。 > img <- grayscale(boats) # グレースケール化 > dim(img) [1] 256 384 1 1 ''grayscale()'' は元の画像にアルファチャンネルが含まれているとうまくいかない。 そのときはアルファチャンネルを ''rm.alpha()'' で削除する必要がある。 > im <- load.image("https://www.kitp.org/class/lib/exe/fetch.php?media=numericalipb:sample_rgb.png") > dim(im) [1] 964 343 1 4 # カラーチャンネルが4チャンネル > img <- grayscale(im) # アルファチャンネルのためにエラー > img <- grayscale(rm.alpha(im)) > plot(img) ===== 画像ファイルフォーマット ===== サイズの大きい画像ほど当然ながらデータ量は多くなる。 画素値が8bit(1byte)とすると、横 $w$ ピクセル、縦 $h$ ピクセルの画像のデータ量は、グレースケール画像では1 チャンネルのみなので $w\times h$ bytes、カラー画像では 3 チャンネルになるので $w\times h\times 3$ bytes になる。 例えば、横 2000ピクセル、縦 1000ピクセルのカラー画像では、 \[ 2000\times 1000\times 3=6\times 10^{6}\mathrm{bytes}=6\mathrm{Mbytes} \] となり、一枚でかなりのデータ量になる。 このように大きな画像データをそのまま保存するのは容量の無駄なので、何らかのアルゴリズムを使って小さいデータ量に__**圧縮**__してファイルに保存するのが普通である。 例えば、__**ランレングス圧縮(RLE)**__という圧縮アルゴリズムを見てみよう。 16進数で「3a, 3a, 3a, 3a, 3a, 3a, b1, b1, b1, b1」という 10bytes のデータがあるとする。 これは 0x3a が6個と 0xb1 が4個続くので「3a, 06, b1, 04」というデータで表すことにすれば 4bytes で済む。 データ量の圧縮率は $4/10=0.4=40\%$ である。 {{ rle.png?nolink |ランレングス圧縮の例}} これはかなり原始的な圧縮アルゴリズムで、同じデータが連続する場合は有効であるが、写真のように連続でないデータが多い場合は逆にデータ量が増えてしまう。 現在はより効率的な圧縮アルゴリズムが色々と開発されて使われている。 圧縮した画像は__**展開**__して元の画像に戻して見ることができる。 圧縮方法には完全に元の画像に戻せる__**可逆圧縮**__と完全には戻せない__**不可逆圧縮**__がある。 一般的に可逆圧縮より不可逆圧縮の方が圧縮率は高い。 特に写真画像は様々な色や形が混じっているので、不可逆圧縮で少々情報が失われてもパッと見では違いが分からない。 以下は一般的な画像ファイルフォーマットである。 ^ フォーマット ^ 拡張子 ^ 色数 ^ 透明度 ^ 圧縮 ^ アニメ ^ 説明 ^ | JPEG | .jpg, .jpeg | 約1677万色 | × | 主に不可逆 | × | 写真画像に適しており、広く使われている。\\ 品質を設定できる。 | | PNG | .png | 約1677万色 | ○ | 可逆 | ○ | CGなどに適している。 | | GIF(ジフ) | .gif | 256色 | ○ | 可逆 | ○ | アニメ機能がよく使われる(GIFアニメーション)。\\ 同時に使える色数が少ない。 | | Windows bitmap | .bmp | 約1677万色 | ○ | 可逆 | × | Windows で標準的に使われる。 | | HEIF(ヒーフ)\\ HEIC(ヘイク) | .heif\\ .heic | 約1677万色以上 | ○ | 不可逆 | ○ | Apple の最近の機器で標準的に使われる。\\ Apple 以外の機器や OS では標準で扱えないことが多い。 | | WebP(ウェッピー) | .webp | 約1677万色 | ○ | 可逆・不可逆 | ○ | Google が開発したフォーマットで、最近増えてきている。 | 参考:[[https://ja.wikipedia.org/wiki/%E7%94%BB%E5%83%8F%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%83%95%E3%82%A9%E3%83%BC%E3%83%9E%E3%83%83%E3%83%88%E3%81%AE%E6%AF%94%E8%BC%83|画像ファイルフォーマットの比較]] ===== 小テスト② ===== [[KMS>|Moodle Server(非公式)]]で第1回の小テスト②を受験しなさい。 ===== 課題 ===== [[KMS>|Moodle Server(非公式)]]で第1回の課題を行いなさい。 [[moodle:upload]] 締め切り:2026年6月17日(水)20時