Python入門トップページ


目次

  1. scikit-image のインストール
  2. Matplotlib による画像の表示
  3. 表示関数の定義
  4. RGBA から RGB への変換
  5. グレースケールをイメージする
  6. RGB からグレースケールへの変換
    1. RGB 平均
    2. ITU-R Rec BT.602
    3. Contemporary CRT phosphors (Rec 709)
    4. 3種類の比較
    5. scikit-image の rgb2gray 関数
  7. 平均化フィルタ
    1. 平均化フィルタの自作
    2. 平均化フィルタの一般化
    3. scikit-image の平均化フィルタ関数
  8. ガウシアンフィルタ
  9. バイラテラルフィルタ
  10. ランダムノイズとフィルタ
  11. ソーベルフィルタ
    1. ソーベルフィルタの自作
    2. scikit-image の sobel 関数
    3. 平均化/ガウシアンフィルタとソーベルフィルタの併用

画像フィルタの作成と利用

RGBA から RGB への変換

PNG 画像は RGB と RGBA のデータ形式を扱うことができます.この A (アルファチャンネル)は不透明度を意味し,1.0 (または 255) の場合は完全不透明,0 は完全な透明になります.その中間の不透明度は256段階で指定できます.

ここでは,RGBA から RGB に変換するコードを自作したあと,scikit-image.color の rgba2rgb 関数による変換を行います.

まずは ink.png の画像ファイルが RBGA 形式になっていることを確認します.次の結果は高さが250ピクセル,幅が250ピクセル,1画素あたり RGBA の4チャンネルのデータ形式であることを意味しています.

ink_img = plt.imread('ink.png')
show(ink_img)
ink_img.shape
filters_00_ink_rgba
(250, 250, 4)

左上の画素について RGBA のデータを確認します.アルファチャンネルが 1.0 であることから完全な不透明であることがわかります.

ink_img[0,0]
array([0.68235296, 0.59607846, 0.5058824 , 1.        ], dtype=float32)

アルファチャンネルを削除すると RGB データに変換できます.

img = ink_img[:, :, 0:3]
img.shape
(250, 250, 3)

左上の画素について RGB データを確認します.アルファチャンネルが削除されていることを確認できます.

img[0,0]
array([0.68235296, 0.59607846, 0.5058824 ], dtype=float32)

RGB 形式の画像を表示します.元の RGBA 形式のデータについてもすべての画素のアルファチャンネルが完全不透明であったことから,結果的には同じ画像が表示されることになります.

show(img)
filters_01_ink-rgb

次に,scikit-image.color で提供される rgba2rgb 関数を利用して RGB に変換してみます.透明なピクセルが含まれる場合の背景色を指定する方法など,詳細はドキュメントを参照してください.

ink_img = plt.imread('ink.png')
img = color.rgba2rgb(ink_img)
img.shape
(250, 250, 3)

前のページで定義した show_zoom_with_color 関数を使って,画像の一部を拡大表示します.

show_zoom_with_color(
    img,
    xlim=(40,90),
    ylim=(100, 50), # ylimは(上限,下限)の順で指定することに注意
    show_color=False)
filters_02_zoom1

更に拡大します.

show_zoom_with_color(
    img, xlim=(40,70), ylim=(100, 70),
    show_color=False)
filters_02_zoom2

更に拡大すると,画素ごとの色の変化がはっきりと見えるようになりました.

show_zoom_with_color(
    img, xlim=(50.5,59.5), ylim=(89.5, 80.5),
    show_color=False)
filters_02_zoom3

元の画像の左上の画素と,拡大図の四隅の画素について RGB データを 0 〜 255 の範囲に変換して表示します.左下や右下の画素は RGB の値が左上と比較すると小さく,その結果として暗い色になっていることが確認できます.

print(img[0,0]*255)
print(img[81,51]*255)  # x = 51, y = 81
print(img[81,60]*255)
print(img[90,51]*255)
print(img[90,60]*255)
[174. 152. 129.]
[209. 172. 129.]
[167. 141. 116.]
[75. 66. 89.]
[ 86.  82. 102.]

Numpy 配列として RGB データを作成すると画像として表示できることを理解するために,4×4画素のデータを作成して表示してみます.例えば,元の画像の x=59, y=81 の位置にある画素の情報を利用してみます.

# 特定のピクセルの色を取り出して拡大表示する
r, g, b = img[81,59] # y , x の順で指定すること
img1 = np.array(
    [
        [[r, g, b], [r, g, b], [r, g, b], [r, g, b]],
        [[r, g, b], [r, g, b], [r, g, b], [r, g, b]],
        [[r, g, b], [r, g, b], [r, g, b], [r, g, b]],
        [[r, g, b], [r, g, b], [r, g, b], [r, g, b]],
    ]
)
show(img1, save_png=False)
print(img1[0,0]*255)
filters_02_zoom4
[198. 165. 125.]

目次に戻る